Android HttpURLConnection 在 post 请求中发送数据不起作用,但 javascript XMLHttpRequest 可以
Android HttpURLConnection sending data in post request doesnt work, but javascript XMLHttpRequest does
我有一个使用 mongodb、mongoose 和 node.js 的服务器。
我已经实现了一些 GET 和 POST 方法。
在 HTML 网站中,我可以 post 在 XMLHttpRequest 中向服务器发送数据,如下所示 javascript:
function postPlantType(base64){
var httpPost = new XMLHttpRequest(),
path = "http://...", // real URL taken out here
header = ('Content-Type','application/json'),
data = JSON.stringify({image:base64});
httpPost.onreadystatechange = function(err) {
if (httpPost.readyState == 4 && httpPost.status == 201){
console.log(httpPost.responseText);
} else {
console.log(err);
}
};
path = "http://..." // real URL taken out here
httpPost.open("POST", path, true);
httpPost.send(data);
}
这很好用。现在我想创建一个 Android 应用程序,利用这样一个 POST 请求,但我的代码无法成功运行。这是我的代码:
private class PostNewPlantTask extends AsyncTask<String, Integer, String> {
String responseString = "";
int response;
InputStream is = null;
protected String doInBackground(String... urls){
DataOutputStream wr=null;
try {
URL url = new URL(urls[0]); // urls[0] is the url of the http request "http://www..."
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
String json = "{\"image\":\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYE...\"}";
Log.d("json", json.toString());
conn.setRequestProperty("Content-length", json.getBytes().length + "");
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
OutputStream os = conn.getOutputStream();
os.write( json.getBytes("UTF-8"));
os.close();
// Starts the query
conn.connect();
response = conn.getResponseCode();
if (response >= 200 && response <=399){
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
// Convert the InputStream into a string
String contentAsString = readIt(is, 200);
responseString = contentAsString;
conn.disconnect();
} catch (Exception e) {
responseString = "error occured: "+e;
} finally {
if (is != null){
try { is.close();} catch (Exception e) {Log.d("HTTP POST planttypes","Exception occured at closing InputStream: "+e);}
}
}
Log.d("HTTP POST plants", "The response is: " + response + responseString);
return responseString;
}
protected void onPostExecute(String result){
// TODO: nothing(?)
// give user feedback(?)
}
}
注意:如果我将 json 字符串更改为无效的 json 内容,例如删除最后一个“}”,服务器的响应是
400 "code":"InvalidContent","message":"Invalid JSON: Unexpected end of input"
所以我假设整个 json 字符串必须是正确的,如果它没有变化的话。
由于测试问题,我在这里对 base64 编码的图像字符串进行硬编码,而不是对真实图像进行编码。你可以在这个 jsfiddle 看到图片。
如果我没看错,它与我的 javascript 发出的请求完全相同,但我收到 500 内部服务器错误。
但是,为了获得更多信息,这里是为该请求调用的服务器函数 url:
function postNewPlantType(req, res, next){
var json = JSON.parse(req.body);
newPlantTypeData = {
image:json.image
};
var imageBuffer = decodeBase64Image(json.image);
newPlantType = new Planttype(newPlantTypeData);
newPlantType.save(function(err){
if (err) return next(new restify.InvalidArgumentError(JSON.stringify(err.errors)));
var fileName = cfg.imageFolder + "" + newPlantType._id + '.jpeg';
fs.writeFile(fileName, imageBuffer.data, function(error){
if (error) log.debug(error);
log.debug("PlantType-ImageFile successfully created on server.");
});
res.send(201, newPlantType);
log.debug("PlantType successfully saved in database.");
});
}
我想知道的是,javascript 请求有效,但 android 请求无效。所以我假设我的 android 代码一定有错误。你能帮我解释一下,错误是什么,我必须改变什么吗?
您可能需要对其进行正确编码:
conn.connect();
DataOutputStream printout = new DataOutputStream(conn.getOutputStream ());
printout.write(URLEncoder.encode(json.toString(),"UTF-8"));
printout.flush ();
printout.close ();
response = conn.getResponseCode();
...
经过很多天的调查,我终于通过更改线路得到了 201 响应
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
至
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
嗯..我发送的是编码的 JSON 而不是 json 本身...
我有一个使用 mongodb、mongoose 和 node.js 的服务器。 我已经实现了一些 GET 和 POST 方法。
在 HTML 网站中,我可以 post 在 XMLHttpRequest 中向服务器发送数据,如下所示 javascript:
function postPlantType(base64){
var httpPost = new XMLHttpRequest(),
path = "http://...", // real URL taken out here
header = ('Content-Type','application/json'),
data = JSON.stringify({image:base64});
httpPost.onreadystatechange = function(err) {
if (httpPost.readyState == 4 && httpPost.status == 201){
console.log(httpPost.responseText);
} else {
console.log(err);
}
};
path = "http://..." // real URL taken out here
httpPost.open("POST", path, true);
httpPost.send(data);
}
这很好用。现在我想创建一个 Android 应用程序,利用这样一个 POST 请求,但我的代码无法成功运行。这是我的代码:
private class PostNewPlantTask extends AsyncTask<String, Integer, String> {
String responseString = "";
int response;
InputStream is = null;
protected String doInBackground(String... urls){
DataOutputStream wr=null;
try {
URL url = new URL(urls[0]); // urls[0] is the url of the http request "http://www..."
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
String json = "{\"image\":\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYE...\"}";
Log.d("json", json.toString());
conn.setRequestProperty("Content-length", json.getBytes().length + "");
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
OutputStream os = conn.getOutputStream();
os.write( json.getBytes("UTF-8"));
os.close();
// Starts the query
conn.connect();
response = conn.getResponseCode();
if (response >= 200 && response <=399){
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
// Convert the InputStream into a string
String contentAsString = readIt(is, 200);
responseString = contentAsString;
conn.disconnect();
} catch (Exception e) {
responseString = "error occured: "+e;
} finally {
if (is != null){
try { is.close();} catch (Exception e) {Log.d("HTTP POST planttypes","Exception occured at closing InputStream: "+e);}
}
}
Log.d("HTTP POST plants", "The response is: " + response + responseString);
return responseString;
}
protected void onPostExecute(String result){
// TODO: nothing(?)
// give user feedback(?)
}
}
注意:如果我将 json 字符串更改为无效的 json 内容,例如删除最后一个“}”,服务器的响应是
400 "code":"InvalidContent","message":"Invalid JSON: Unexpected end of input"
所以我假设整个 json 字符串必须是正确的,如果它没有变化的话。
由于测试问题,我在这里对 base64 编码的图像字符串进行硬编码,而不是对真实图像进行编码。你可以在这个 jsfiddle 看到图片。 如果我没看错,它与我的 javascript 发出的请求完全相同,但我收到 500 内部服务器错误。 但是,为了获得更多信息,这里是为该请求调用的服务器函数 url:
function postNewPlantType(req, res, next){
var json = JSON.parse(req.body);
newPlantTypeData = {
image:json.image
};
var imageBuffer = decodeBase64Image(json.image);
newPlantType = new Planttype(newPlantTypeData);
newPlantType.save(function(err){
if (err) return next(new restify.InvalidArgumentError(JSON.stringify(err.errors)));
var fileName = cfg.imageFolder + "" + newPlantType._id + '.jpeg';
fs.writeFile(fileName, imageBuffer.data, function(error){
if (error) log.debug(error);
log.debug("PlantType-ImageFile successfully created on server.");
});
res.send(201, newPlantType);
log.debug("PlantType successfully saved in database.");
});
}
我想知道的是,javascript 请求有效,但 android 请求无效。所以我假设我的 android 代码一定有错误。你能帮我解释一下,错误是什么,我必须改变什么吗?
您可能需要对其进行正确编码:
conn.connect();
DataOutputStream printout = new DataOutputStream(conn.getOutputStream ());
printout.write(URLEncoder.encode(json.toString(),"UTF-8"));
printout.flush ();
printout.close ();
response = conn.getResponseCode();
...
经过很多天的调查,我终于通过更改线路得到了 201 响应
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
至
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
嗯..我发送的是编码的 JSON 而不是 json 本身...