title: Why am I getting a 400: bad request?
body: <p>I'm trying to post XML to my <a href="http://en.wikipedia.org/wiki/Apache_Tomcat" rel="nofollow">Tomcat</a> server from an Android device, but I get zero bytes in the stream. I get a 400 bad request response, but I am not sure what's wrong with it. I can access my web application in a browser from Android and on my server's machine. When I log the XML, it looks fine. Why am I getting a 400: bad request?</p>
  
  <p>[<strong>Update 4]:</strong> I just intercepted the request with <a href="http://en.wikipedia.org/wiki/Wireshark" rel="nofollow">Wireshark</a> and get (Len=0) Length of zero. I still don't know why though.</p>
  
  <p>[<strong>Update 3]:</strong> Posting to 10.0.2.2 crashes with <code>connection to http://10.0.2.2:8080/Archery refused</code>. Posting to my server's actual <a href="http://en.wikipedia.org/wiki/IP_address" rel="nofollow">IP address</a> gets the bad request.</p>
  
  <p>[<strong>Update 2]:</strong> logcat</p>
  
  <pre><code>...
      08-06 15:32:39.189 W/myApp   (2064): xstream created
      08-06 15:32:39.269 W/myApp   (2064): xml created
      08-06 15:32:39.269 E/test    (2064): &lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;Why don't you work?&lt;/body&gt;&lt;/html&gt;
      08-06 15:32:39.269 E/test    (2064): XML set to String Entity
      08-06 15:32:39.269 E/test    (2064): post headers set
      08-06 15:32:39.269 E/test    (2064): Sending post
      08-06 15:32:39.319 W/InputManagerService(239): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@2bc4a7c0
      08-06 15:32:39.339 E/test    (2064): Post sent, response is: HTTP/1.1 400 Bad Request[Lorg.apache.http.Header;@2c0695d0org.apache.http.impl.client.ClientParamsStack@2c1a4cd0
      08-06 15:32:41.309 D/OpenGLRenderer(337): Flushing caches (mode 0)
      08-06 15:32:41.409 W/InputManagerService(239): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@2bc79268
      08-06 15:32:41.589 I/ActivityManager(239): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.cyanogenmod.trebuchet/.Launcher} from pid 239
  ...
  </code></pre>
  
  <p>[<strong>Update 1]:</strong> When my request is like this:</p>
  
  <pre><code>StringEntity se = new StringEntity(xmlString, "UTF-8");
  Log.e("test", "XML set to String Entity");
  se.setContentType("text/xml");
  post.setEntity(se);
  post.setHeader("Content-Type", "text/xml; charset=utf-8");
  post.setHeader("Host", "http://xxx.xxx.x.x:8080/Archery");
  Log.e("test", "post headers set");
  </code></pre>
  
  <p>I get this logged when using RequestDumpFilter:</p>
  
  <pre><code>INFO: Request Received at 2013-08-06 13:27:01.342
   characterEncoding=null
       contentLength=-1
         contentType=null
              locale=en_US
             locales=en_US, en
            protocol=HTTP/1.1
          remoteAddr=0:0:0:0:0:0:0:1
          remoteHost=0:0:0:0:0:0:0:1
              scheme=http
          serverName=localhost
          serverPort=8080
            isSecure=false
  ---------------------------------------------
         contextPath=
              header=host=localhost:8080
              header=user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0
              header=accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
              header=accept-language=en-US,en;q=0.5
              header=accept-encoding=gzip, deflate
              header=connection=keep-alive
              header=cache-control=max-age=0
              method=GET
            pathInfo=null
         queryString=null
          remoteUser=null
  requestedSessionId=null
          requestURI=/Archery
         servletPath=/Archery
  =============================================
  </code></pre>
  
  <p>And adding content length header, <code>post.setHeader("Content-Length", Long.toString(se.getContentLength()));</code>, crashes the program with a ClientProtocolException</p>
  
  <p>Server processRequest method:</p>
  
  <pre><code>protected void processRequest(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
      //String xmlSent = req.toString();
  
      resp.setContentType("text/html;charset=UTF-8");
      PrintWriter pw = resp.getWriter();
  
      InputStream xmlStream = req.getInputStream();
      if (xmlStream != null){
          pw.println("XML stream: " + xmlStream.available());
      }
      else{
          pw.println("No XML stream found");
      }
      String xmlSent = convertStreamToString(xmlStream);
      ShootRecord recordSent = XMLTransformer.xmlToObject(xmlSent);
  
      if(recordSent!=null){
          String date =  recordSent.listOfScoreSheets.get(0).getmDate();
          String target = recordSent.listOfScoreSheets.get(0).getmTargetNumber();
          String dateTargetKey = date + target;
          shootRecordMap.put(dateTargetKey, recordSent);
      }
  
      //out.write(xmlSent.getBytes());
      if (recordSent != null){
          pw.println("Date of record sent: "+recordSent.shootRecordDate);
      }
      else{
          pw.println("No record received yet");
      }
      pw.flush();
      pw.close();
  }
  
  // &lt;editor-fold defaultstate="collapsed" desc="HttpServlet methods. doGet and doPost call processRequest"&gt;
  // &lt;/editor-fold&gt;
  </code></pre>
  
  <h3>postToServletOverWifi method</h3>
  
  <pre><code>public boolean postToServletOverWifi(ShootRecord recToSend, Context context)
  {
      try
      {
          Log.w("myApp", "starting method postToServletOverWifi");
  
          /* Prepare object as XML */
          XStream xstream = new XStream();
          xstream.processAnnotations(ScoreSheet.class);
          xstream.processAnnotations(ShootRecord.class);
          Log.w("myApp", "xstream created");
  
          ArrayList&lt;ScoreSheet&gt; mListOfScoreSheets = recToSend.getListOfScoreSheets();
          ShootRecord testShootRecord = new ShootRecord();
          testShootRecord.setmShootRecordDate(recToSend.getRecordDate());
          testShootRecord.setmNumArchersOnTarget(recToSend.getNumArchersOnTarget());
          testShootRecord.setmScoreSheetTypeIndex(recToSend.getScoreSheetType());
          testShootRecord.setmShootRecordName(recToSend.getmShootRecordName());
          testShootRecord.setmListOfScoreSheets(mListOfScoreSheets);
  
          String xml = xstream.toXML(testShootRecord);
          Log.w("myApp", "XML created");
  
          new taskForPostingToServer(xml).execute();
  
          // p.flush();
          // ostream.close();
  
          return true;
      }
      catch (Exception e) {
          System.out.println( e.getMessage() );
          e.printStackTrace();
          return false;
      }
  }
  </code></pre>
  
  <h3>Android Task</h3>
  
  <pre><code>public taskForPostingToServer(String xml)
  {
      xmlString = xml;
      client = new DefaultHttpClient();
      url = "http://xxx.xxx.x.x:8080/Archery";
      post = new HttpPost(url);
      //post.setHeader("Content-type", "text/xml; charset=utf-8");
      post.setHeader("host", "http://xxx.xxx.x.x:8080/Archery");
      response = null;
  }
  
  protected void onPreExecute()
  {
      //StringEntity se = null;
      try {
          //se = new StringEntity(xmlString, "UTF-8");
          //post.setEntity(se);
          Log.e("test", xmlString);
          InputStream inputStream=new ByteArrayInputStream(xmlString.getBytes()); //Init your own inputstream
          InputStreamEntity inputStreamEntity=new InputStreamEntity(inputStream, xmlString.getBytes().length);
          post.setEntity(inputStreamEntity);
          post.setHeader("Content-Type", "text/xml;charset=UTF-8");
      }
      catch (Exception ex) {
          Logger.getLogger(ScoreSheetsView.class.getName()).log(Level.SEVERE, null, ex);
      }
  }
  
  
  protected Boolean doInBackground(Integer... params)
  {
      boolean success = true;
      try {
          Log.e("test", "Sending post");
          response = client.execute(post);
          Log.e("test", "Post sent, "+ "response is: "+response.getStatusLine());
  
      }
      catch (IOException ex) {
          Logger.getLogger(ScoreSheetsView.class.getName()).log(Level.SEVERE, null, ex);
      }
      if (response == null){
          success =false;
      }
      return success;
  }
  ...
  </code></pre>