Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
818 views
in Technique[技术] by (71.8m points)

android - How can I delete the nameValuePairs key from the JSONObject?

I'm working on an Android project which needs a JSONObject for the body of my POST request. After putting the keys and values of the JSON I got the following line:

{
    "xxxx":"zzzzzzz",
    "yyyy":"uuuuuuu"
}

But the server got the following:

{
    "name_value_pairs": {
                        "xxxx":"zzzzzzz",
                        "yyyy":"uuuuuuu"
    }
}

I've already tried a JSONStringer but it wasn't really helpful because the Content-Type of the request is application/json.

UPDATE

I'm not trying to construct a JSONObject because it's already done by using the following line of code (the same given by @osayilgan):

JSONObject jsonRequest = new JSONObject();
jsonRequest.put("xxxx", "zzzzzzz");
jsonRequest.put("yyyy", "uuuuuuu");

Here is not the problem. The interface described below is used to communicate with the server.

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void testFunction(@Body JSONObject jsonObject, Callback<Response> callback);
}

The server got the request with the second JSON as Body which is disappointing. I note that the key name_value_pairs is automatically added to the object.

Does anybody know how can I fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Issue:

Retrofit by default uses GSON to convert HTTP bodies to and from JSON. The object which is specified with @Body annotation will be passed to GSON for serialization, which basically converts the JAVA object to JSON representation. This JSON representation will be the HTTP request body.

JSONObject stores all the key-value mapping in a member variable by name nameValuePairs. Here is an excerpt of JSONObject implementation:

public class JSONObject {
    ...
    private final Map<String, Object> nameValuePairs;
    ...
}

When you pass JSONObject to @Body annotation, this JSONObject is seraliazed, hence the HTTP request body contains : {"nameValuePairs": "actual JSON Object"}.

Solution:

Pass the actual JAVA object to @Body annotation, not it's corresponding JSONObject. GSON will take care of converting it to JSON representation.

For e.g.

class HTTPRequestBody {
   String key1 = "value1";
   String key2 = "value2";
   ...
}

// GSON will serialize it as {"key1": "value1", "key2": "value2"}, 
// which will be become HTTP request body.

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void postJson(@Body HTTPRequestBody body, Callback<Response> callback);
}

// Usage
MyService myService = restAdapter.create(MyService.class);
myService.postJson(new HTTPRequestBody(), callback);

Alternative solution:

If you still want to send raw JSON as HTTP request body, then follow the solution mentioned by Retrofit author here.

One of the suggested solution is to use TypedInput:

public interface MyService {
  @POST("/test")
  void postRawJson(@Body TypedInput body, Callback<Response> callback);
}

String json = jsonRequest.toString();
TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8"));
myService.postRawJson(in, callback);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...