问题
I have the following cURL command and I would like to execute the same thing from Android,
curl -X POST -H "Content-Type: application/json" -d
'{"username":"user","password":"pass"}'
http://www.somesite.com/login
This is what I made for Andorid,
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.somesite.com/login");
try {
httppost.addHeader("Content-Type", "application/json");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", "user"));
nameValuePairs.add(new BasicNameValuePair("password", "pass"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
HttpResponse response = httpclient.execute(httppost);
Log.d("RESPOND", EntityUtils.toString(response.getEntity()));
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
When I ran the application I get the whole page as a response instead of the desired JSON array. I'm new in cURL and I have no idea what's going wrong with the code.
回答1:
Use JSONObject instead of just a List of name/value pairs.
Use a StringEntity instead of a UrlEncodedFormEntity.
Build a JsonObject wrapping your KV strings and then use a 'writer' to dump the Object to a string in the form of a StringEntity on the POST request in httpclient.
some relevant code using "Jackson" for the JsonObj implementation and httpclientandroid.
ObjectNode rootOb = new ObjectMapper().createObjectNode();
rootOb.put("username",user );
...
StringWriter writer = new StringWriter();
try {
new ObjectMapper().writeValue(writer, rootOb);
} catch (JsonGenerationException e) {
}
String poststr=writer.toString();
new HttpConnection(handler4).post(url, poststr);
...
httpPost.setEntity(new StringEntity(poststr));
testing with curl -VERBOSE first then just reimplement exactly the curl in android is a very good technique as long as you are able to turn on LOGGER in the android httpclient that gives you HEADER / WIRE level logging when you need to verify that your android does EXACT or almost exact what your Curl client was doing.
example below of a curl expression followed by Android logs (WIRE/HEADERS) showing android analogs of the same stuff you sent using Curl.
curl -v -X POST \
-H "X-Parse-Application-Id: LAbR" \
-H "X-Parse-REST-API-Key: ke" \
-H "Content-Type: application/json" \
-d '{"score":1337,"playerName":"Sean Plott","cheatMode":false}' \
https://api.parse.com/1/classes/GameScore
D/ch.boye.httpclientandroidlib.wire(18636): >> "POST /1/files/audio HTTP/1.1[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "X-Parse-Application-Id: LAbR[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "X-Parse-REST-API-Key: kuI9[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "Content-Type: audio/*[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "Content-Length: 12074[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "Host: api.parse.com[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "Connection: Keep-Alive[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "--"
D/ch.boye.httpclientandroidlib.wire(18636): >> "cVxX6b-jxQnxFCczaKHLNZ_Hq8HI9AEW219GW3w"
D/ch.boye.httpclientandroidlib.wire(18636): >> "[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "Content-Disposition"
D/ch.boye.httpclientandroidlib.wire(18636): >> ": "
D/ch.boye.httpclientandroidlib.wire(18636): >> "form-data; name="bin"; filename="myfile.3gp""
D/ch.boye.httpclientandroidlib.wire(18636): >> "[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "Content-Type"
D/ch.boye.httpclientandroidlib.wire(18636): >> ": "
D/ch.boye.httpclientandroidlib.wire(18636): >> "application/octet-stream"
D/ch.boye.httpclientandroidlib.wire(18636): >> "[\r][\n]"
D/ch.boye.httpclientandroidlib.wire(18636): >> "[\r][\n]"
D/ch.boye.httpclientandroidlib.headers(18636): >> POST /1/files/audio HTTP/1.1
D/ch.boye.httpclientandroidlib.headers(18636): >> X-Parse-Application-Id: LAbR
D/ch.boye.httpclientandroidlib.headers(18636): >> X-Parse-REST-API-Key: kuI9
D/ch.boye.httpclientandroidlib.headers(18636): >> Content-Type: audio/*
D/ch.boye.httpclientandroidlib.headers(18636): >> Content-Length: 12074
D/ch.boye.httpclientandroidlib.headers(18636): >> Host: api.parse.com
D/ch.boye.httpclientandroidlib.headers(18636): >> Connection: Keep-Alive
When you get used to turning on/off your android logs, anything you do in Curl for connection tests, you can then just implement in android httpclient and it will work as long as you put basically same headers, mimetype, post body (JsonAsString) in your android.
来源:https://stackoverflow.com/questions/24590929/using-curl-commands-in-android