Issue
I get a JSON like below from a call to an api:
{"birthDate":"2002-06-09T22:57:10.0756471Z","created":"2022-06-09T22:57:10.0756471Z","idNumber":"1234567","lastName":"Tester"}
I have confirmed that the JSON is correct, I validated it online and it validates.
My application gets this response and handles it properly without any issues. So does Postman.
However, MockMvc test in Springboot fails when converting this Json response string to my class with error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 15 path $.birthDate
I do conversion like:
MockHttpServletResponse response = mvc.perform(
post("/examples")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(String.valueOf(postData)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse();
String responseString = response.getContentAsString(); // returns string like "{"birthDate":"2002-06-09....}"
Gson gson = new Gson();
ExampleResponse exampleResponse = gson.fromJson(responseString, ExampleResponse.class); // this line fails
My ExampleResponse class is:
public class ExampleResponse {
private String idNumber;
private String lastName;
private OffsetDateTime birthDate;
private OffsetDateTime created;
/// getters and setters
}
I dont understand why is the fromJson call failing.
Solution
Figured it out. Need to register OffsetDateTime with GsonBuilder like:
Add a class like:
public class OffsetDateTimeDeserializer implements JsonDeserializer<OffsetDateTime> {
@Override
public OffsetDateTime deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
return OffsetDateTime.parse(jsonElement.getAsString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
}
, then modify code above that uses Gson to convert Json string to model class to following:
MockHttpServletResponse response = mvc.perform(
post("/examples")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(String.valueOf(postData)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse();
String responseString = response.getContentAsString();
String responseString = response.getContentAsString();
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeDeserializer());
Gson gson = gsonBuilder.setPrettyPrinting().create();
ExampleResponse exampleResponse = gson.fromJson(responseString, ExampleResponse.class); // NOW IT WORKS!!!
Answered By - pixel
Answer Checked By - Cary Denson (JavaFixing Admin)