我正在尝试从Android设备向我的Tomcat服务器发布XML,但我在流中得到零字节。我得到400个错误的请求响应,但我不确定它有什么问题。我可以通过Android和我服务器的机器在浏览器中访问我的Web应用程序。当我记录XML时,它看起来很好。为什么我得到400:不好的请求?
[更新4]:我刚用Wireshark拦截了请求,得到(Len = 0)长度为零。我仍然不知道为什么。
[更新3]:使用connection to http://10.0.2.2:8080/Archery refused
发布到10.0.2.2崩溃。发布到我服务器的实际IP address会收到错误的请求。
[更新2]: logcat
...
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): <html><head></head><body>Why don't you work?</body></html>
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
...
[更新1]:当我的请求是这样的时候:
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");
我在使用RequestDumpFilter时记录了这个:
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
=============================================
添加内容长度标头post.setHeader("Content-Length", Long.toString(se.getContentLength()));
,使用ClientProtocolException崩溃程序
服务器processRequest方法:
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();
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. doGet and doPost call processRequest">
// </editor-fold>
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<ScoreSheet> 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;
}
}
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;
}
...