Retrofit adding extra slash to the serialized JSON multipart string - android

I believe it's Retrofit that's adding the extra slash to the key value pairs when calling the service with serialized JSON data.
I have a hash map object to be passed as a multipart string, and I'm converting it to JSON string using Gson.
public static String getJsonString(Object object) {
gson = new Gson();
jsonString = gson.toJson(object);
return jsonString;
}
I have the retrofit builder like
Retrofit.Builder()
.baseUrl(path)
.addConverterFactory(GsonConverterFactory.create())
.client(trustCert(context))
.build();
Passing the JSON data as
Call<ResponseBody> responseBodyCall = ApiClient.getInstance(context).getApiService().uploadData(getJsonString(params));
Api interface:
#Multipart
#POST("upload")
Call<ResponseBody> uploadData(#Part("data") String data);
When we debugged on the server side, the received json data has extra slashes in it. For example, it's supposed to be like \"{\"key1\", \"value\"}\" but it is being serialized as \\"{\\"key1\\", \\"value\\"}\\". I have put a breakpoint just before the api call, and the data is all good, but on the server side it's weird.

Related

replace / encode special characters in json response from server?

I want to replace or encode special characters from json response body.
my response is
{"form":"\u003Cdiv class=\u0022column\u0022\u003E \n
\u003Cdiv class=\u0022ajxpos col-md-12\u0022 id=\u0022edit-pannel\u0022 style=\u0022margin
i already used GsonConverterFactory in my Retrofitclient.But it doesn't work in these case.
Retrofit retrofit = new Retrofit.Builder().baseUrl(Api.BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
I need to get result like this:
String form = "<div class=\"column\">.....
any solution ?
Finally i found a solution :
public static String toPrettyFormat(String jsonString)
{
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(jsonString).getAsJsonObject();
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
String prettyJson = gson.toJson(json);
return prettyJson;
}

How to send post request along with data in raw form in Retrofit?

I want to send a data in the above format in raw form of Body. The data type should be "JSON(application/json)" and the header should include "application/json" as Content-Type.
I tried using this way but is not working for me.
public interface AddData {
#POST("/Api/")
Call<String> postData(#Header("Content-Type") String content_type,#Body JSONObject body);
}
Use #Header as the annotations
#Headers("Content-Type: application/json")
#POST("/Api/")
Call<String> getUser(#Body JSONObject body);
Refer to https://github.com/square/retrofit/issues/1587

How to parse dynamic JSON with Retrofit?

I have dynamic JSON, here is example: http://pastebin.com/QMWRZTrD
How I can parse it with Retrofit?
I failed to generate POJO classes, since I have dynamic fields like "5411" and "5412".
EDIT:
I solved it by using Map, since first value is always integer, and second is list of objects.
#FormUrlEncoded
#POST("history.php")
Observable<Map<Integer, List<Vehicle>>> getHistory(#Field("uredjaji") String vehicleId, #Field("startDate") String startDATE, #Field("endDate")
you can use Map to serialize and deserialize it in case of Random keys.
Observable<Map<Integer, List<YourObject>>>
You can get retrofit api call to return String in your RestApi Interface like
Call<String> method(#Path(..)...);
And for that to work you would need to add the scalars converter factory to where you create your Retrofit object.
First you would need to import it:
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
And then add it:
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://your.base.url/")
.build();
And then in onResponse
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
Type mapType = new TypeToken<Map<String,List<SomeClass>>() {}.getType(); // define generic type
Map<String,List<SomeClass>> result= gson.fromJson(response.body(), mapType);
} else {
}
}
Also,check out this site it has great tutorials on Retrofit.

Directly POST JSONObject via retrofit

Can I send JSON directly via retrofit like this:
#POST("rest/workouts")
Call<CreateWorkoutSuccessAnswer> createWorkout(#NonNull #Body JSONObject jsonObject);
You can use TypedInput
#POST("rest/workouts")
Call<CreateWorkoutSuccessAnswer> createWorkout(#NonNull #Body TypedInput body);
And to form param:
TypedInput in = new TypedByteArray("application/json", jsonObject.toString().getBytes("UTF-8"));
And use in as a parameter for request.
You can directly post JSON objects using GSONs JsonObject class.
The reason Googles JSONObject does not work is that retrofit uses GSON by default and tries to serialize the JSONObject parameter as a POJO. So you get something like:
{
"JSONObject":
{
<your JSON object here>
}
}
If what you are doing requires you to use JSONObject then you can simply convert between the two using the String format of the object.

What is the right way to handle Strings when doing HTTP requests?

I have an Android application acting as a client to my back end server.
I am doing a POST http request with a help of Retrofit lib with a String in the body.
Problem is, Retrofit is most likely escaping double quotes when using GSON builder.
That results in a field in my DB containing double quotes, example: "example_gcm_token".
I need to know whether I should handle that on server side or on client side and how to do that.
I assume it shouldn't be on the server side as it would mean I have to remove escaped quotes for every single endpoint.
#POST ("/Maguss/users/{userId}/gcmtoken")
Call<Void> setGcmToken(#Path("userId") Long userId, #Body StringEntity gcmToken);
I would try to replace the StringEntity with a POJO:
public class SetGcmTokenRequest {
#SerializedName("gcmtoken")
private String gcmToken;
public String getGcmToken() {
return gcmToken;
}
public void setGcmToken(String gcmToken) {
this.gcmToken = gcmToken;
}
}
And change the interface like this:
#POST ("/Maguss/users/{userId}/gcmtoken")
Call<Void> setGcmToken(#Path("userId") Long userId, #Body SetGcmTokenRequest setGcmTokenRequest);

Categories

Resources