How can I delete the nameValuePairs key from the JSONObject?
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);
Use com.google.gson.JsonObject instead of org.json.JSONObject.
JSONObject jsonRequest = new JSONObject();
jsonRequest.put("xxxx", "zzzzzzz");
jsonRequest.put("yyyy", "uuuuuuu");
Change to
JsonObject jsonRequest = new JsonObject();
jsonRequest.addProperty("xxxx", "zzzzzzz");
jsonRequest.addProperty("yyyy", "uuuuuuu");
Then in interface
public interface MyService {
@Headers({"Content-type: application/json",
"Accept: */*"})
@POST("/test")
void testFunction(@Body JsonObject jsonObject, Callback<Response> callback);
}
JSONObject class keeping the values in LinkedHashMap
with the variable name of nameValuePairs
, When Gson trying to convert the JSONObject's instance into JSON,
GSON keeps the structure(which has the variable nameValuePairs
). That causing this problem.