I am trying to get a response message to a POJO class that has already been defined. However, I am getting null values for all the fields in the POJO class. I printed the json file and they are not null and I am wondering what is actually going. This is the response that I get.
I should get this VirtualAccountResponseDto(account_number=null, bank_code=null, unique_id=null, account_name=null, account_reference=null, bank_name=null, created_at=null, currency=null, id=null, account_status=null, customer=null)
This is the gson class that I printed to the console
+++++++++>>>>>>>>>{"data":{"account_number":"1110006278","bank_code":"000","unique_id":"KPY-VA-NEBOrKvKCmTSOJe","account_name":"James Bond","account_reference":"xyz163ath285","bank_name":"test","created_at":"2022-11-27T23:38:36.449Z","currency":"NGN","id":6268,"account_status":"active","customer":{"name":"James Bond","email":"hey#yxc.com"}},"message":"Virtual bank account created successfully","status":true}
This is what the POJO class looks like
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class VirtualAccountResponseDto {
#SerializedName("account_number")
private String account_number;
#SerializedName("bank_code")
private String bank_code;
private String unique_id;
private String account_name;
private String account_reference;
private String bank_name;
private String created_at;
private String currency;
private String id;
private String account_status;
private Customer customer;
This is the customer class
#Data
public class Customer {
private String email;
private String name;
}
Here is my code to convert from Json to POJO
Gson gson = new Gson();
String requestJson = gson.toJson(bankDto);
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("Authorization", "Bearer "+KORAPAY_TOKEN);
headers.put("accept", "application/json");
HttpResponse<JsonNode> apiResponse = Unirest.post(KORAPAY_BASE_URL +
"virtual-bank-account")
.headers(headers)
.body(requestJson)
.asJson();
System.out.println(apiResponse.getBody());
JSONObject responseJson = apiResponse.getBody().getObject();
System.out.println("This is the response body" + apiResponse.getBody());
JsonParser jsonParser = new JsonParser();
JsonObject gsonObject = (JsonObject)jsonParser.parse(responseJson.toString());
System.out.println("+++++++++>>>>>>>>>" + gsonObject);
VirtualAccountResponseDto responseDTO = gson.fromJson(gsonObject,
VirtualAccountResponseDto.class);
System.out.println("I should get this " + responseDTO);
return responseDTO;
I have tried annotating the variable names with #Serializedname. I have also checked for case_senstivity issues. Also, I have rearranged the POJO fields in the order in which the JSON is returned and I still get the same null values
As #Marcono1234 pointed out, your DTO structure and JSON structures do not match.
I tried by modifying the structure of the DTO class to add a 'data' element and it works fine after that.
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class VirtualAccountResponseDto {
DataClass data; // <-- Added this class to match the JSON structure
}
#Data
class DataClass {
private String account_number;
private String bank_code;
private String unique_id;
private String account_name;
private String account_reference;
private String bank_name;
private String created_at;
private String currency;
private String id;
private String account_status;
private Customer customer;
}
#Data
class Customer {
private String email;
private String name;
}
Output after the change:
VirtualAccountResponseDto(data=DataClass(account_number=1110006278, bank_code=000, unique_id=KPY-VA-NEBOrKvKCmTSOJe, account_name=James Bond, account_reference=xyz163ath285, bank_name=test, created_at=2022-11-27T23:38:36.449Z, currency=NGN, id=6268, account_status=active, customer=Customer(email=hey#yxc.com, name=James Bond)))
Related
This question already has an answer here:
How to deserialize a JSON array with no name, using RestAssured?
(1 answer)
Closed 5 months ago.
I have created couple of POJO classes for serializing/deserializing. When I create a request to receive all categories I am expecting to receive an array of category objects. But I am getting the following error:-
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type POJO.Categories from Array value (token JsonToken.START_ARRAY)
1. This is my test class and I try to map the response to my POJO class(model) but it gives me an error.
#Test(alwaysRun = true, priority = 1)
public void getUserDetail() {
String url = "http://localhost:8081/users";
RequestSpecification httpRequest = RestAssured.given()
.header("Content-Type", "application/json")
.contentType(ContentType.JSON);
Response response = httpRequest.get(url);
ResponseBody responseBody = response.getBody();
UsersResponseDetails b = responseBody.as(UsersResponseDetails.class);
softAssert.assertEquals(b.getId(), 1,"invalid");
softAssert.assertAll();
}
2. Error
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `model.UsersResponseDetails` from Array value (token `JsonToken.START_ARRAY`)
at [Source: (String)"[{"id":1,"name":"litteleHelpByKR-1","dob":"2020-05-23T","addressDetails":{"houseNumber":"H-55","aadharNumber":32345,"addressLine1":"Mg Road-1","addressLine2":"12th Cross-1","landmark":"Near Airport Road","pin":1,"officeAddress":{"buildingNumber":3,"addressLine1":"XYZ-1","addressLine2":"Airport Road","landMark":"Near U turn signal","cardId":"EMP-001","pin":75943764}}}]"; line: 1, column: 1]
3. Used Jackson dependent but its not work
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4</version>
</dependency>
4. API GET response
[
{
"id":1,
"name":"litteleHelpByKR-1",
"dob":"2020-05-23T",
"addressDetails":{
"houseNumber":"H-55",
"aadharNumber":32345,
"addressLine1":"Mg Road-1",
"addressLine2":"12th Cross-1",
"landmark":"Near Airport Road",
"pin":1,
"officeAddress":{
"buildingNumber":3,
"addressLine1":"XYZ-1",
"addressLine2":"Airport Road",
"landMark":"Near U turn signal",
"cardId":"EMP-001",
"pin":75943764
}
}
}
]
5. This model I created to map the response
#Getter
#Setter
public class UsersResponseDetails {
private int id;
private String name;
private String dob;
private AddressDetails addressDetails;
#Getter
#Setter
public static class AddressDetails {
private String houseNumber;
private int aadharNumber;
private String addressLine1;
private String addressLine2;
private String landmark;
private int pin;
private OfficeAddress officeAddress;
#Getter
#Setter
public static class OfficeAddress {
private int buildingNumber;
private String addressLine1;
private String addressLine2;
private String landMark;
private String cardId;
private int pin;
}
}
}
My suggesstion are:
If you want to work with array, then
UsersResponseDetails[] b = responseBody.as(UsersResponseDetails[].class);
softAssert.assertEquals(b[0].getId(), 1,"invalid");
If you prefer List, then
List<UsersResponseDetails> b= responseBody.as(new TypeRef<List<UsersResponseDetails>>() {});
softAssert.assertEquals(b.get(0).getId(), 1,"invalid");
I'm new to Spring and I'm having trouble consuming an API and serialising the Response to Java POJOs using Jackson. This the API endpoint I'm trying to consume.
This what my request looks like:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", "Bearer " + applicationProperties.getApiKey());
ArrayList<String> externalIds = new ArrayList<>();
externalIds.add(userId);
Map<String, Object> parameters = new HashMap<>();
parameters.put("external_ids", externalIds);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(parameters, headers);
ResponseEntity<ProfileExportDTO> response = this.restTemplate.postForEntity(url, request , ProfileExportDTO.class);
This is my POJO class (setters and getters removed for simplicity):
#JsonIgnoreProperties(ignoreUnknown = true)
public class ProfileExportDTO implements Serializable {
#JsonProperty("first_name")
private String firstname;
#JsonProperty("last_name")
private String lastname;
private String language;
private String email;
private String dob;
#JsonProperty("home_city")
private String city;
private String country;
private String phone;
#JsonProperty("time_zone")
private String timezone;
#JsonProperty("last_coordinates")
private float[] lastCoordinates;
private String gender;
#JsonProperty("total_revenue")
private float revenue;
private String attributed_campaign;
private String attributed_source;
private String attributed_adgroup;
private String push_subscribe;
private String email_subscribe;
My problem is that when this runs the produced object is null. Does anyone know why?
I have model:
public class StudyModel {
#Id
private String ID;
private boolean isStable;
private String LastUpdate;
private MainTest test;
public static class MainTest {
private String test1;
private String test2;
}
}
I want to parse it to my model.
It works correctly but when it goes to MainTest where on json file I have couple values it fails and I have null on the rest of fields.
How I can deal with it?
public StudyModel getStudyDetails(String studyId){
RestTemplate restTemplate = new RestTemplate();
String url = URL + "studies/" + studyId;
ResponseEntity<String> serverResponse = restTemplate.getForEntity(url, String.class);
Gson g = new Gson();
String json = serverResponse.getBody();
StudyModel study = g.fromJson(json, StudyModel.class);
return study;
}
RestTemplate can handle deserialization for you
ResponseEntity<StudyModel> serverResponse = restTemplate.getForEntity(url, StudyModel.class);
StudyModel studyModel = serverResponse.getBody();
I am trying to map a String (with json values) to my POJO but getting a null when I do that.
Can I get some advivec on what I am doing wrong pls. They are matching up correctly from what I see.
I have the following String:
"{\"identifier_type\":\"TEST\",\"simple_construct_response\":[{\"identifier\":\"123451234512435\",\"customer_id\":\"\",\"trim_code\":\"DDD\",\"trim_reason_code\":\"\",\"simple_products\":[{\"product_name\":\"ABC_CPS_ABCD\",\"product_presentment_timestamp\":\"2019-02-28 06:07:20:383\"}]}]}"
It would conform to the following structure.
{
"identifier_type": "TEST",
"simple_construct_response": [
{
"identifier": "123451234512435",
"customer_id": "",
"trim_code": "DDD",
"trim_reason_code": "",
"simple_products": [
{
"product_name": "ABC_CPS_ABCD",
"product_presentment_timestamp": "2019-02-28 06:07:20:383"
}
]
}
]
}
This is my code where the output is null when I map.
String response = "{\"identifier_type\":\"TEST\",\"simple_construct_response\":[{\"identifier\":\"123451234512435\",\"customer_id\":\"\",\"trim_code\":\"DDD\",\"trim_reason_code\":\"\",\"simple_products\":[{\"product_name\":\"ABC_CPS_ABCD\",\"product_presentment_timestamp\":\"2019-02-28 06:07:20:383\"}]}]}";
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MainResponse output = mapper.readValue(response, MainResponse.class); // this results in null
These are my POJOs to match above string.
#Getter
#Setter
public class MainResponse {
private String identifierType;
private List<SimpleConstructResponse> simpleConstructResponse;
}
#Getter
#Setter
public class simpleConstructResponse {
private String identifier;
private String customerId;
private String trimCode;
private String trimReasonCode;
private List<SimpleProduct> simpleProducts;
}
#Getter
#Setter
public class SimpleProduct {
private String productName;
private String productPresentmentTimestamp;
}
Instead of
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
write following code
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
For the most part,
the fields in your JSON do not match the fields in your class.
Because of this,
you must identify the field mapping for Jackson.
Jackson provides a way to identify the field name in the JSON and to
associate it with a field in the Java class;
the #JsonProperty annotation.
Here is some example code:
#Getter
#Setter
public class MainResponse
{
#JsonProperty("identifier_type")
private String identifierType;
#JsonProperty("simple_construct_response")
private List<SimpleConstructResponse> simpleConstructResponseList;
}
#Getter
#Setter
public class SimpleConstructResponse
{
private String identifier;
#JsonProperty("customer_id")
private String customerId;
#JsonProperty("trim_code")
private String trimCode;
#JsonProperty("trim_reason_code")
private String trimReasonCode;
#JsonProperty("simple_products")
private List<SimpleProduct> simpleProducts;
}
#Getter
#Setter
public class SimpleProduct
{
#JsonProperty("product_name")
private String productName;
#JsonProperty("product_presentment_timestamp")
private String productPresentmentTimestamp;
}
JSON FORMAT:
[
{
"0":
{
"cast":"",
"showname":"woh pagle",
"type":"Episodes"
},
"video":[
{
"src":"video.mp4"
},
{
"DRM":"False"
}
]
}
]
Here problem is I am getting below exception:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize
instance of java.util.ArrayList out of START_OBJECT token at [Source:
java.io.StringReader#1c9ca1; line: 1, column: 55617] (through
reference chain:
com.apalya.myplex.valueobject.ThirdPartyContentDetailsArray["video"])
My pojo classes are :
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonProperty("0")
private ThirdPartySubContentDetails subContent;
#JsonProperty("video")
private List<ThirdPartySubContentVideoInfo> video;
My Sub class pojo is :
private String src;
#JsonIgnore
#JsonProperty("DRM")
private String drm;
Please help me to write a pojo for that video list.
Your json starts as an array and not as an Object. The important part to change is how the Objectmapper should generate your json. For returning a List you need to do it this way:
List<FirstJson> jsonList = mapper.readValue(json, new TypeReference<List<FirstJson>>(){});
Here is my short working test I implement locally:
public static void main(String[] args) {
String json = "[{\"0\":{\"cast\":\"\",\"showname\":\"wohpagle\",\"type\":\"Episodes\"},\"video\":[{\"src\":\"video.mp4\"},{\"DRM\":\"False\"}]}]";
ObjectMapper mapper = new ObjectMapper();
List<FirstJson> jsonList = mapper.readValue(json, new TypeReference<List<FirstJson>>(){});
System.out.println(jsonList.toString());
}
The first part of your JsonArray in Pojo.(Named it FirstJson)
public class FirstJson{
#JsonProperty("0")
private FirstJson subContent;
private String cast;
private String showname;
private String type;
#JsonProperty("video")
private List<Video> videos;
//getter/setter
And the Video Pojo:
public class Video {
private String src;
#JsonProperty("DRM")
private String drm;
//getter/setter
Just a sidenote: If you declare your pojos in the same class file, the classes should be static. public static class FirstJson
According to the JSON structure described in the question, the following should be the POJOs:
public class MainPojo
{
#JsonProperty("0")
private ThirdPartySubContentDetails subContent;
#JsonProperty("video")
private List<ThirdPartySubContentVideoInfo> video;
// Getters and Setters for subContent and video
}
class ThirdPartySubContentDetails
{
private String cast;
private String showName;
private String type;
// Getters and Setters for cast, showName and type
}
#JsonIgnoreProperties(ignoreUnknown = true)
class ThirdPartySubContentVideoInfo
{
#JsonProperty("src")
private String src;
#JsonProperty("DRM")
private String drm;
// Getters and Setters for src and drm
}
You should call the deserializer method as follows:
List<MainPojo> list = new ObjectMapper().readValue(json, new TypeReference<List<MainPojo>>(){});