How to use #JsonUnwrapped in list of objects - java

I'm trying to deserialize a JSON object using Jackson annotation, but I can't deserialize it:
Is an array of a type "Deposito"
{
"depositos": [
{
"deposito": {
"id": "13168775373",
"nome": "Geral",
"saldo": "100000.0000000000",
"desconsiderar": "N",
"saldoVirtual": "100000.0000000000"
}
}
]
}
my java class:
#JsonUnwrapped
#JsonProperty(value ="depositos")
private List<Deposito> depositos;
my deposito class:
#JsonRootName(value = "deposito")
public class Deposito {
private String id;
private String nome;
private Double saldo;
private String desconsiderar;
private Double saldoVirtual;
}

You would need to add an additional class to your model:
public class DepositoMetadata {
private Deposito deposito;
}
Now you need to adjust your main java class (as you called it):
private List<DepositoMetadata> depositos;
Finally, you can remove #JsonRootName(value = "deposito") from your Deposito class.

Related

How to map attribute value into two fields during Jackson deserialisation

I would like to know is there a way (probably using deserialiser) in Jackson to copy one attribute value to another object attribute the container has.
For example, documentId from the TestData class also needs to be persisted in the Details.documentId attribute.
json/TestData.json
{
"id": "1",
"documentId" : "234234",
"details" : {
"name": "test",
"lastName": "asdf"
}
}
#RequiredArgsConstructor(onConstructor_ = #Autowired)
#SpringBootTest(classes = ExampleMicroserviceApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
#ActiveProfiles("test")
public class TestDocumentId {
final ObjectMapper objectMapper;
#Value("classpath:json/TestData.json")
Resource testData;
#SneakyThrows
#Test
void testDocumentIdPresentInDetails() {
var data = objectMapper.readValue(testData.getFile(), TestData.class);
assertThat(data.documentId).isNotNull();
assertThat(data.getDetails().name).isNotNull();
assertThat(data.getDetails().documentId).isNotNull();
}
#Data
public static class TestData {
private String id;
private String documentId;
private Details details;
#Data
public static class Details {
private String documentId;
private String name;
private String lastName;
}
}
}

Jackson-databind mapping JSON skip layer

I got a JSON response like this:
{
"status": "success",
"response": {
"entries": [
{
"id": 1,
"value": "test"
},
{
"id": 2,
"value": "test2"
}
]
}
}
And i want to map it with jackson-databind on an object like this:
public class Response {
#JsonProperty("status")
private String status;
#JsonProperty("response.entries")
private Collection<ResponseEntry> entries;
}
So i'm searching for an way to give #JsonProperty a path so it can skip the layer "response".
Welcome to Stack Overflow. You can define a wrapper class for your Collection<ResponseEntry> collection like below :
public class ResponseWrapper {
#JsonProperty("entries")
private Collection<ResponseEntry> entries;
}
The ResponseEntry class could be defined like below :
public class ResponseEntry {
#JsonProperty("id")
private int id;
#JsonProperty("value")
private String value;
}
Once defined these classes you can rewrite your old Response class like below :
public class Response {
#JsonProperty("status")
private String status;
#JsonProperty("response")
private ResponseWrapper responseWrapper;
}
You can flatten using the #JsonUnwrapped annotation.
You can have your classes like this
public class Response {
private String status;
private Collection<ResponseEntry> entries;
}
public class ResponseEntry {
#JsonUnwrapped
private Entry entry;
}
pubic class Entry{
private Integer id;
private String value;
}

Why am I unable to map my object to this String

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;
}

How to set JsonProperty value dynamically

I want to create a json request like below:
"additionalData": {
"riskdata.basket.item1.sku": "045155",
"riskdata.basket.item1.quantity": "1"
"riskdata.basket.item2.sku": "0451166",
"riskdata.basket.item2.quantity": "1"
...
"riskdata.basket.item4.sku": "0451111",
"riskdata.basket.item4.quantity": "2"
Please suggest how to set the JsonProperty value dynamically in the object mapping.
Example: deliveryMethod is a constant field hence I am able to map like below using JsonProperty annotation. However, how I can use the JsonProperty for sku and quantity so that it will accept as many number as possible. Any suggestion would be helpful.
public class AdditionalData implements java.io.Serializable
{
#JsonProperty(value = "riskdata.deliveryMethod")
private String deliveryMethod;
#JsonProperty(value = "riskdata.basket.item??.sku")
private String sku;
#JsonProperty(value = "riskdata.basket.item??.quantity")
private String quantity;
}
You can create a basket[] array property in your AdditionalDataclass.
public class AdditionalData implements java.io.Serializable
{
#JsonProperty(value = "riskdata.deliveryMethod")
private String deliveryMethod;
#JsonProperty(value = "riskdata.basket")
private Basket[] basket;
}
public class Basket implements java.io.Serializable
{
#JsonProperty(value = "sku")
private String sku;
#JsonProperty(value = "quantity")
private String quantity;
}
And the change your json structure like this:
"additionalData": {
"riskdata.basket": [
{
"sku": "045155",
"quantity": 1"
},
{
"sku": "045156",
"quantity": 1"
}]
}

Map JSON to pojo using Jackson for List that have different parameters

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>>(){});

Categories

Resources