I'm trying to POST a JSONObject using the Retrofit library, but when I see the request at the receiving end, the content-length is 0
.
In the RestService interface:
@Headers({
"Content-type: application/json"
})
@POST("/api/v1/user/controller")
void registerController(
@Body JSONObject registrationBundle,
@Header("x-company-device-token") String companyDeviceToken,
@Header("x-company-device-guid") String companyDeviceGuid,
Callback<JSONObject> cb);
And it gets called with,
mRestService.registerController(
registrationBundle,
mApplication.mSession.getCredentials().getDeviceToken(),
mApplication.mSession.getCredentials().getDeviceGuid(),
new Callback<JSONObject>() {
// ...
}
)
And I'm certain that the registrationBundle
, which is a JSONObject
isn't null or empty (the other fields are certainly fine). At the moment the request is made, it logs out as: {"zip":19312,"useAccountZip":false,"controllerName":"mine","registrationCode":"GLD94Q"}
.
On the receiving end of the request, I see that the request has Content-type: application/json
but has Content-length: 0
.
Is there any reason why sending JSON in the body like this isn't working? Am I missing something simple in using Retrofit?
The Best Answer is The @Body annotation defines a single request body. Since Retrofit uses Gson by default, the FooRequest instances will be serialized as JSON as the sole body of the request. The Gson docs have much more on how object serialization works. And then use an instance of that class similar to #1.
This means your @GET or @DELETE should not have @Body parameter. You can use query type url or path type url or Query Map to fulfill your need. Else you can use other method annotation.
By default, you don't need to set any headers if you want a JSON request body. Whenever you test Retrofit code, I recommend setting .setLogLevel(RestAdapter.LogLevel.FULL)
on your instance of RestAdapter. This will show you the full request headers and body as well as the full response headers and body.
What's occurring is that you are setting the Content-type twice. Then you're passing a JSONObject, which is being passed through the GsonConverter and mangled to look like {"nameValuePairs":YOURJSONSTRING}
where YOURJSONSTRING
contains your complete, intended JSON output. For obvious reasons, this won't work well with most REST APIs.
You should skip messing with the Content-type header which is already being set to JSON with UTF-8 by default. Also, don't pass a JSONObject to GSON. Pass a Java object for GSON to convert.
Try this if you're using callbacks:
@POST("/api/v1/user/controller")
void registerController(
@Body MyBundleObject registrationBundle,
@Header("x-company-device-token") String companyDeviceToken,
@Header("x-company-device-guid") String companyDeviceGuid,
Callback<ResponseObject> cb);
I haven't tested this exact syntax.
Synchronous example:
@POST("/api/v1/user/controller")
ResponseObject registerController(
@Body MyBundleObject registrationBundle,
@Header("x-company-device-token") String companyDeviceToken,
@Header("x-company-device-guid") String companyDeviceGuid);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With