I am calling a RestFul API written in Java that consumes plain text or JSON and returns a response in JSON. I am using gson library to generate and parse my fields. I am calling the api from an Android simulation where I user retrofit2 library and GsonConverterFactory. The generated String seems fine. I am not using a POJO, just a generic HashMap which I then convert to a String.
Generated gson from Android is {"password":"K16073","userid":"K16073"}
Code given below. At the API service, the string received is wrapped with additional double quotes.
Printed String including the quotes in the beginning and end "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
Because of this I am getting java.lang.IllegalStateException: Not a JSON Object: "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
I tried to remove the quotes and then I get com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 2 path $.
/* Android code */
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(myRFReceivingApis.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Map<String, String> userData = new HashMap<>();
userData.put("userid",edtTxtUserId.getText().toString());
userData.put("password",editTxtPassword.getText().toString());
Gson gson = new Gson();
System.out.println(" generated gson " gson.toJson(userData));
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
call.enqueue(new Callback<Object>() {
@Override
public void onResponse(Call<Object> call, Response<Object> response) {
textViewResp.setText(response.body().toString());
:
/* End of Android code */
API Service code in Java
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Path("login")
public String RFLoginNew(String jsonString) {
String result = jsonString.substring(1, jsonString.length() - 1);
System.out.println(" Json String " result);
// tried using JsonParser -- line 1 below
JsonObject o = JsonParser.parseString(result).getAsJsonObject();
// tried using Gson gson.fromJson
Gson gson = new Gson();
JsonElement element = gson.fromJson (result, JsonElement.class); //Converts the json string to JsonElement without POJO
JsonObject jsonObj = element.getAsJsonObject(); //Converting JsonElement to JsonObject
// --line 2 below
System.out.println(" RFLoginNew struser " jsonObj.get("userid").getAsString());
I am not getting the correct json format. I am not sure what is wrong with the way jsonString is generated.
CodePudding user response:
Cause
You are making double serialization.
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
Here your map gets serialized to json string, and then this json gets serialized a second time when request is sent.
Fix
- Serialize only once on frontend - whatever library you are using(i don't do android stuff) should have method where you supply the payload as an
Оbject
- the method argument should be the map,userData
in your case.
call = ApiClient.getInstance().getMyApi().callLogin(userData);
Something like that.
- Or double deserialization on backend - deserialize to
String
, then deserialize the resulting string again to whatever you need.
String jsonString = gson.fromJson(doubleJson, String.class);
Map<String, String> result = gson.fromJson(jsonString, Map.class);
System.out.println(result);