Create a json array - java

I'm writing a code where in there has to be a main array generated in json. my code is as below.
My pojos
JsonCreator.java
package com.createjson;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "EntityLabels", "ExampleText", "SelectedIntentName" })
public class Jsoncreator {
#JsonProperty("EntityLabels")
private List<EntityLabel> entityLabels = null;
#JsonProperty("ExampleText")
private String exampleText;
#JsonProperty("SelectedIntentName")
private String selectedIntentName;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("EntityLabels")
public List<EntityLabel> getEntityLabels() {
return entityLabels;
}
#JsonProperty("EntityLabels")
public void setEntityLabels(List<EntityLabel> entityLabels) {
this.entityLabels = entityLabels;
}
#JsonProperty("ExampleText")
public String getExampleText() {
return exampleText;
}
#JsonProperty("ExampleText")
public void setExampleText(String exampleText) {
this.exampleText = exampleText;
}
#JsonProperty("SelectedIntentName")
public String getSelectedIntentName() {
return selectedIntentName;
}
#JsonProperty("SelectedIntentName")
public void setSelectedIntentName(String selectedIntentName) {
this.selectedIntentName = selectedIntentName;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
EntityLabel.java
package com.createjson;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "StartToken", "EntityType", "EndToken" })
public class EntityLabel {
#JsonProperty("StartToken")
private int startToken;
#JsonProperty("EntityType")
private String entityType;
#JsonProperty("EndToken")
private int endToken;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("StartToken")
public int getStartToken() {
return startToken;
}
#JsonProperty("StartToken")
public void setStartToken(int startToken) {
this.startToken = startToken;
}
#JsonProperty("EntityType")
public String getEntityType() {
return entityType;
}
#JsonProperty("EntityType")
public void setEntityType(String entityType) {
this.entityType = entityType;
}
#JsonProperty("EndToken")
public int getEndToken() {
return endToken;
}
#JsonProperty("EndToken")
public void setEndToken(int endToken) {
this.endToken = endToken;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Main Class
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.config.ConfigDetails;
import com.createjson.EntityLabel;
import com.createjson.Jsoncreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class dummy {
public static void main(String[] args) throws JsonProcessingException {
Jsoncreator jsoncreator = null;
EntityLabel label;
List<EntityLabel> entityLabelList;
ObjectMapper objectMapper;
List<String> matchList;
String[] lines = { "What is (Jim)'s gift (limit)? <=> Personname <=> Amount::Spent",
"What is (John)'s gift (limit)? <=> Personname <=> Amount::Spent" };
// check if the text has entities
for (String line : lines) {
entityLabelList = new ArrayList<EntityLabel>();
if (line.contains("<=>")) {
String[] example_split = line.split("<=>", 2);
// System.out.println("String is " + example_split[1]);
if (example_split[0].length() > 1) {
String[] example_entity = example_split[1].split("<=>");
int entities_count = 0;
int startPosition;
int endPosition = 0;
matchList = new ArrayList<>();
Pattern regex = Pattern.compile("\\((.*?)\\)");
Matcher regexMatcher = regex.matcher(line);
jsoncreator = new Jsoncreator();
while (regexMatcher.find()) {
startPosition = regexMatcher.start() + 1;
endPosition = regexMatcher.end() - 1;
matchList.add(regexMatcher.group(1));
label = new EntityLabel();
label.setStartToken(startPosition);
label.setEntityType(example_entity[entities_count].toString());
label.setEndToken(endPosition);
entityLabelList.add(label);
objectMapper = new ObjectMapper();
TestCasesString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(label);
jsoncreator.setEntityLabels(entityLabelList);
entities_count++;
}
}
}
objectMapper = new ObjectMapper();
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsoncreator));
}
}
}
when I run this program, there are two objects created, but I want a songle object created.
My Current O/P
{
"EntityLabels" : [ {
"StartToken" : 9,
"EntityType" : " Personname ",
"EndToken" : 12
}, {
"StartToken" : 22,
"EntityType" : " Amount::Spent",
"EndToken" : 27
} ]
}
{
"EntityLabels" : [ {
"StartToken" : 9,
"EntityType" : " Personname ",
"EndToken" : 13
}, {
"StartToken" : 23,
"EntityType" : " Amount::Spent",
"EndToken" : 28
} ]
}
My Expected O/P
[{
"EntityLabels" : [ {
"StartToken" : 9,
"EntityType" : " Personname ",
"EndToken" : 12
}, {
"StartToken" : 22,
"EntityType" : " Amount::Spent",
"EndToken" : 27
} ]
},
{
"EntityLabels" : [ {
"StartToken" : 9,
"EntityType" : " Personname ",
"EndToken" : 13
}, {
"StartToken" : 23,
"EntityType" : " Amount::Spent",
"EndToken" : 28
} ]
}]
please let me know how can I do this.
Thanks

If you want an array you need to serialise a list, the same way you are already doing with entityLabels. Every jsoncreator object is going to create a json representation for that instance, just need to save them in a list and serialise it.
Something like:
public class dummy {
public static void main(String[] args) throws JsonProcessingException {
List<Jsoncreator> objectsToSerialise = new ArrayList<>();
... your code
// check if the text has entities
for (String line : lines) {
... your code
objectsToSerialise.add(jsonCreator);
}
objectMapper = new ObjectMapper();
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectsToSerialise));
}
}
Hope you get the idea.
Jackson – Unmarshall to Collection/Array

Related

Convert denormalized or flat data to hierarchical Java Object

This is what tried I did to convert a denormalized or flat data to hierarchical Java Object?
Here is the input, output and code, (question is at the bottom)
INPUT:
[ {
"countryName" : "USA",
"stateName" : "FL",
"cityName" : "Miami"
}, {
"countryName" : "USA",
"stateName" : "FL",
"cityName" : "Doral"
}, {
"countryName" : "India",
"stateName" : "Tamilnadu",
"cityName" : "Chennai"
}, {
"countryName" : "India",
"stateName" : "Karnataka",
"cityName" : "Bangalore"
} ]
OUTPUT:
[ {
"countryName" : "USA",
"states" : [ {
"stateName" : "FL",
"cities" : [ {
"cityName" : "Miami"
}, {
"cityName" : "Doral"
} ]
} ]
}, {
"countryName" : "India",
"states" : [ {
"stateName" : "Karnataka",
"cities" : [ {
"cityName" : "Bangalore"
} ]
}, {
"stateName" : "Tamilnadu",
"cities" : [ {
"cityName" : "Chennai"
} ]
} ]
} ]
CODE:
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toSet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.Data;
public class Normalizer {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
final var objectWriter = objectMapper.writerWithDefaultPrettyPrinter();
Tuple t1 = Tuple.of("USA", "FL", "Miami");
Tuple t2 = Tuple.of("USA", "FL", "Doral");
Tuple t3 = Tuple.of("India", "Tamilnadu", "Chennai");
Tuple t4 = Tuple.of("India", "Karnataka", "Bangalore");
List<Tuple> tuples = List.of(t1, t2, t3, t4);
System.out.println("INPUT:\n" + objectWriter.writeValueAsString(tuples));
System.out.println("---------------------------------------------");
final var countries = normalize(tuples);
System.out.println("OUTPUT:\n" + objectWriter.writeValueAsString(countries));
}
public static Set<Country> normalize(List<Tuple> tuples) {
System.out.println("Step 1: Grouping");
final var map = tuples.stream()
.collect(groupingBy(Country::of, groupingBy(State::of, mapping(City::of, toSet()))));
System.out.println("Step 2: Creating Object Hierarchy");
Set<Country> countries = new HashSet<>();
map.forEach((country, value) -> {
countries.add(country);
Set<State> states = new HashSet<>();
value.forEach((state, value1) -> {
state.setCities(value1);
states.add(state);
});
country.setStates(states);
});
return countries;
}
#Data(staticConstructor = "of")
public static class Tuple {
private String countryName;
private String stateName;
private String cityName;
public static Tuple of(String countryName, String stateName, String cityName) {
Tuple t1 = new Tuple();
t1.setCountryName(countryName);
t1.setStateName(stateName);
t1.setCityName(cityName);
return t1;
}
}
#Data(staticConstructor = "of")
public static class Country {
private String countryName;
private Set<State> states = new HashSet<>();
public static Country of(Tuple tuple) {
Country country = new Country();
country.setCountryName(tuple.getCountryName());
return country;
}
}
#Data(staticConstructor = "of")
public static class State {
private String stateName;
private Set<City> cities = new HashSet<>();
public static State of(Tuple tuple) {
State state = new State();
state.setStateName(tuple.getStateName());
return state;
}
}
#Data(staticConstructor = "of")
public static class City {
private String cityName;
public static City of(Tuple tuple) {
City city = new City();
city.setCityName(tuple.getCityName());
return city;
}
}
}
There are 2 steps in normalize method, is there a way to get this in one step. Like, is there a way to get it just by using Java 8+ Collectors methods?

Java Spring, unmarshal dynamic json

I am trying to unmarshal a json response which comes from a server. But I would like to know which is the best way, approach to use when the json response changes.
For example, if I have a json response like this:
{
"name": "John",
"last_name": "John Last name",
"date_of_birth": "01.01.1990"
}
With jackson, I could deserialize the json object into a Person.class like this:
#NoARgsConstructor
#Setter
public class Person(){
private String name;
private String lastName;
private String dateOfBirth;
}
But what if the json struct changes, and now the attributes of the person comes inside a person object.
{
"person": {
"name": "John",
"last_name": "John Last name",
"date_of_birth": "01.01.1990"
}
}
What would be the best way to avoid this things or to avoid this problems? Is there any possible solution or approach to implement in java spring?
How about searching in the JSON yourself?
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class Foo {
public static void main(String args[]) throws Exception {
String jsonString = "{\"foo\":\"bar\"}";
ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.readValue(jsonString, ObjectNode.class);
if(node.has("foo")) {
System.out.println("foo: " + node.get("foo"));
}
}
}
To make it completely dynamic, I have used reflection api and json-simple-1.1 jar and jackson
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
#JsonProperty("name")
private String name;
#JsonProperty("last_name")
private String lastName;
#JsonProperty("date_of_birth")
private String dateOfBirth;
}
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Demo {
public static void main(String a[]) {
try {
String json1 = "{\r\n" + " \"person\": {\r\n" + " \"name\": \"John\",\r\n"
+ " \"last_name\": \"John Last name\",\r\n" + " \"date_of_birth\": \"01.01.1990\"\r\n"
+ " } \r\n" + " }";
String json2 = "{\r\n" + " \"name\": \"John\",\r\n" + " \"last_name\": \"John Last name\",\r\n"
+ " \"date_of_birth\": \"01.01.1990\"\r\n" + "} ";
extractedPersonObject(json1);
System.out.println("*****************************");
extractedPersonObject(json2);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void extractedPersonObject(String json2) throws ParseException {
Person person = new Person();
Object obj = new JSONParser().parse(json2);
JSONObject jo = (JSONObject) obj;
Map finalMap;
Field[] fields = Person.class.getDeclaredFields();
if (jo.get(fields[0].getName()) == null) {
finalMap = ((Map) jo.get("person"));
} else
finalMap = (Map) jo;
for (Field field : fields) {
JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class);
invokeSetter(person, field.getName(), finalMap.get(jsonProperty.value()));
}
System.out.println(person.getDateOfBirth());
System.out.println(person.getLastName());
System.out.println(person.getName());
}
public static void invokeSetter(Object obj, String propertyName, Object variableValue) {
PropertyDescriptor pd;
try {
pd = new PropertyDescriptor(propertyName, obj.getClass());
Method setter = pd.getWriteMethod();
try {
setter.invoke(obj, variableValue);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
}
A generic way to deserialize such wrapped is to write a deserializer of your own, like:
#SuppressWarnings("serial")
public class UnwrappingDeserializer<T> extends StdDeserializer<T> {
#Setter
private String fieldName;
private ObjectMapper innerMapper = new ObjectMapper();
public UnwrappingDeserializer(Class<T> vc) {
super(vc);
fieldName = handledType().getSimpleName().toLowerCase();
}
#SuppressWarnings("unchecked")
#Override
public T deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode rootT = p.readValueAsTree();
// Check if there is a node with specified field name.
// There is also a setter for it if the field name is not
// directly resolvable
JsonNode valueT = rootT.get(fieldName);
if (valueT == null) {
// If no such node it is the root tha has the value
valueT = rootT;
}
return innerMapper.convertValue(valueT, (Class<T>)handledType());
}
}
Assuming you have Person as:
#Getter #Setter
// Below is because of your JSON key format
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Person {
private String name;
private String lastName;
private String dateOfBirth;
}
you can just add the deserializer to your ObjectMapper like:
ObjectMapper om = new ObjectMapper();
SimpleModule sm = new SimpleModule();
sm.addDeserializer(Person.class, new UnwrappingDeserializer<Person>(Person.class));
om.registerModule(sm);

Set<Object> to Map<String, Set<Long>> java8

Assume I have the next class structure:
#Getter
#Setter
public class Section {
private Long id;
private Set<Grid> grids;
}
#Getter
#Setter
public class Grid {
private Long id;
private Set<Row> rows;
}
#Getter
#Setter
public class Row {
private Long id;
private String email;
}
and I have this set of objects:
Set<Section> sections;
let's imagine this section set values as a JSON in the next structure :
[
{
"id": 1,
"grids": [
{
"id": 10,
"rows" [
{
"id": 50,
"email": "email1#test.com"
},
{
"id": 51,
"email": "email2#test.com"
}
]
}
]
},
{
"id": 2,
"grids": [
{
"id": 11,
"rows" [
{
"id": 60,
"email": "email1#test.com"
}
]
}
]
}
]
Just imagine I have multiple sections and these sections have multiple grids and each grid has multiple rows and the email attribute in each row could exist in different grids.
Now I need to convert this Set to java.util.Map<String, Set> and this map represent Row object email as a key and group of Section ids as a value of that map key.
so I need the result like that Map<email, Set<section1Id, section2id, etc...>>
something like this in JSON (it's just for clarifying the idea):
[
{
"key": "email1#test.com",
"value": [1, 2] // Section ids
},
{
"key": "email2#test.com",
"value": [1] // Section ids
}
]
OR like that (whatever)
[
"email1#test.com": {1, 2},
"email2#test.com": {1}
]
How I can achieve this using Java 8 streaming?
Try something like this:
import static java.util.stream.Collectors.*;
import org.apache.commons.lang3.tuple.Pair;
// ...snip...
sections.stream()
.flatMap(section->section.getGrids()
.stream()
.map(Grid::getRows)
.flatMap(Set::stream)
.map(row->new Pair(row.getEmail(), section.getId())))
.collect(groupingBy(Pair::getKey, mapping(Pair::getValue, toSet())));
If you're using Java 9 or newer, your can do it in a very concise way without the need of third party libraries:
import java.util.Map;
import java.util.Set;
import static java.util.Map.Entry;
import static java.util.Map.entry;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toSet;
Map<String, Set<Long>> result = sections.stream()
.flatMap(section -> section.getGrids().stream()
.flatMap(grid -> grid.getRows().stream())
.map(row -> entry(row.getEmail(), section.getId())))
.collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toSet())));
It's not about streaming. It can be achieved with a simple foreach:
public static void main(String[] args) {
Set<Section> sections = Set.of(....);
Map<String, Set<Long>> result = new HashMap<>();
sections.forEach(section ->
section.getGrids()
.forEach(grid ->
grid.getRows().forEach(row -> {
if (result.containsKey(row.getEmail()))
result.get(row.getEmail()).add(section.getId());
else result.put(row.getEmail(), Set.of(section.getId()));
})));
}
Here's a two step operation to get the desired output format. Have a look at it, if fits your use case
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javafx.util.Pair;
public class P5 {
public static void main(String[] args) {
Row r1 = new Row(50L, "email1#test.com");
Row r2 = new Row(51L, "email2#test.com");
Row r3 = new Row(60L, "email1#test.com");
Row[] arr1 = {r1, r2};
Row[] arr2 = {r3};
Grid[] g1 = {new Grid(10L, new HashSet<>(Arrays.asList(arr1)))};
Grid[] g2 = {new Grid(11L, new HashSet<>(Arrays.asList(arr2)))};
Set<Section> sections = new HashSet<>();
sections.add(new Section(1L, new HashSet<>(Arrays.asList(g1))));
sections.add(new Section(2L, new HashSet<>(Arrays.asList(g2))));
Map<Long, List<String>> minify = sections.stream()
.collect(Collectors.toMap(section -> section.id,
section -> section.grids.stream().flatMap(grid -> grid.rows.stream())
.map(row -> row.email)
.collect(Collectors.toList())));
Map<String, Set<Long>> result = minify.keySet().stream()
.flatMap(key -> minify.get(key).stream().map(email -> new Pair<>(
key, email))).collect(Collectors.groupingBy(
Pair::getValue, Collectors.mapping(Pair::getKey, Collectors.toSet())));
System.out.println(result);
}
static class Section {
private Long id;
private Set<Grid> grids;
public Section(Long id, Set<Grid> grids) {
this.id = id;
this.grids = grids;
}
}
static class Grid {
private Long id;
private Set<Row> rows;
public Grid(Long id, Set<Row> rows) {
this.id = id;
this.rows = rows;
}
}
static class Row {
private Long id;
private String email;
public Row(Long id, String email) {
this.id = id;
this.email = email;
}
}
}
RESULT
{email2#test.com=[1], email1#test.com=[1, 2]}

Ignore absent property when mapping json response

I have a form that should return list of customers.
This form should behave differently in two case:
User starts the research using only "surname"
User starts the research using surname AND name
In the first case the json response has less fields than the response in the second case so I have to ignore all these fields.
I've tried using #JsonInclude(JsonInclude.Include.NON_ABSENT), #JsonInclude(JsonInclude.Include.NON_EMPTY) and #JsonInclude(JsonInclude.Include.NON_NULL) but with each and everyone of these the error returned is always the same:
java.lang.Exception: Could not write content: (was java.lang.NullPointerException) (through reference chain: it.gruppoitas.itasacquire.pojo.Cliente["DATA_NASCITA"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: it.gruppoitas.itasacquire.pojo.Cliente["DATA_NASCITA"])
This is the pojo Cliente:
package it.gruppoitas.itasacquire.pojo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
#JsonInclude(JsonInclude.Include.NON_ABSENT)
public class Cliente {
#JsonProperty("TIPO_PERSONA")
private String tipoPersona;
#JsonProperty("PRO_CLIE")
private String proClie;
#JsonProperty("CODICE_FISCALE")
private String codiceFiscale;
#JsonProperty("DATA_NASCITA")
private String dataNascita;
#JsonProperty("SESSO")
private String sesso;
#JsonProperty("NOME")
private String nome;
#JsonProperty("COGNOME")
private String cognome;
public String getTipoPersona() {
return tipoPersona;
}
public void setTipoPersona(String tipoPersona) {
this.tipoPersona = tipoPersona;
}
public String getProClie() {
return proClie;
}
public void setProClie(String proClie) {
this.proClie = proClie;
}
public String getCodiceFiscale() {
return codiceFiscale;
}
public void setCodiceFiscale(String codiceFiscale) {
this.codiceFiscale = codiceFiscale;
}
public String getDataNascita() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
Date data = null;
try {
data = sdf.parse(dataNascita);
dataNascita = new SimpleDateFormat("dd/MM/yyyy").format(data);
} catch (ParseException e) {
System.err.println(e);
}
return dataNascita;
}
public void setDataNascita(String dataNascita) {
this.dataNascita = dataNascita;
}
public String getSesso() {
return sesso;
}
public void setSesso(String sesso) {
this.sesso = sesso;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
#Override
public String toString() {
return "Cliente [tipoPersona=" + tipoPersona + ", proClie=" + proClie + ", codiceFiscale=" + codiceFiscale + ", dataNascita="
+ dataNascita + ", sesso=" + sesso + ", nome=" + nome + ", cognome=" + cognome + "]";
}}
Any idea?
EDIT: this is an example of the json response structure in case 1
{
"TIPO_PERSONA" : "G",
"PRO_CLIE" : "123456789",
"CODICE_FISCALE" : "123456789",
"PARTITA_IVA" : "123456789",
"SESSO" : "S",
"COGNOME" : "CUSTOMER SRL"
}
And this is an example of the json response in case 2:
{
"TIPO_PERSONA" : "F",
"PRO_CLIE" : "123456789",
"CODICE_FISCALE" : "123456789",
"DATA_NASCITA" : "1969-09-07 00:00:00.0",
"SESSO" : "F",
"NOME" : "Foo",
"COGNOME" : "Fie"
}
As you can see there are less fields in case 1 and STS goes in full-panic mode...
You need to configure your object mapper not to fail on empty beans.
Here is a sample code since you didn't provide the creation of the ObjectMapper code yourself:
private ObjectMapper jacksonMapper = new ObjectMapper();
jacksonMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
jacksonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
You can also use:
jacksonMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES,false);

Converting Json into a DTO array

I have an interesting JSON parsing problem, at least to me since I am doing this for the first time. I have the following sample JSON and I want to map it to equivalent DTOs:
{
"modules":
[
{
"name":"module1",
"shortId":23425,
"pmns":
[
{
"name":"pmn1",
"position":1,
"pmnType":"D3"
},
{
"name":"pmn3",
"position":3,
"pmnType":"R2"
},
{
"name":"pmn7",
"position":5,
"pmnType":"S1"
},
]
},
{
"name":"module2",
"shortId":1572,
"pmns":
[
{
"name":"pmn1",
"position":3,
"pmnType":"D3"
},
{
"name":"pmn12",
"position":35,
"pmnType":"R2"
},
]
}
]
}
This is my ModuleDTO class:
public class ModuleDTO {
private String _name;
private short _shortId;
private PmnDTO[] _pmns;
public String getName() {
return _name;
}
public short getShortId() {
return _shortId;
}
public PmnDTO[] getPmns() {
return _pmns;
}
#JsonProperty("name")
public void setName(String name) {
this._name = name;
}
#JsonProperty("shortId")
public void setShortId(short shortId) {
this._shortId = shortId;
}
#JsonProperty("pmns")
public void setPmns(PmnDTO[] pmns) {
this._pmns = pmns;
}
}
Not copied here but my PmnDTO class is similar, i.e. getters and setters for each property in the pmn object of JSON.
I wrote the following code to try to map it to DTO. The library I am using is com.FasterXml.jackson (version 2.3.1)
// Got the response, construct a DTOs out of it ...
ObjectMapper mapper = new ObjectMapper();
StringReader reader = new StringReader(response); // Json Response
// Convert the JSON response to appropriate DTO ...
ModuleDTO moduleDto = mapper.readValue(reader, ModuleDTO.class);
Obviously, this code didn't work. Can someone tell, how can I map the JSON response to my DTOs, given that "modules" is an array in the JSON and it also contains a variable size array within itself.
Thank You.
(*Vipul)() ;
First of all your JSON is invalid, so I suspect you want this instead:
{
"modules": [
{
"name": "module1",
"shortId": 23425,
"pmns": [
{
"name": "pmn1",
"position": 1,
"pmnType": "D3"
},
{
"name": "pmn3",
"position": 3,
"pmnType": "R2"
},
{
"name": "pmn7",
"position": 5,
"pmnType": "S1"
}
]
},
{
"name": "module2",
"shortId": 1572,
"pmns": [
{
"name": "pmn1",
"position": 3,
"pmnType": "D3"
},
{
"name": "pmn12",
"position": 35,
"pmnType": "R2"
}
]
}
]
}
Then you can use the online conversion from JSON to POJO here and you'll get the follwing result:
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import javax.validation.Valid;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"modules"
})
public class Example {
#JsonProperty("modules")
#Valid
private List<Module> modules = new ArrayList<Module>();
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("modules")
public List<Module> getModules() {
return modules;
}
#JsonProperty("modules")
public void setModules(List<Module> modules) {
this.modules = modules;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
-----------------------------------com.example.Module.java-----------------------------------
package com.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import javax.validation.Valid;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"name",
"shortId",
"pmns"
})
public class Module {
#JsonProperty("name")
private String name;
#JsonProperty("shortId")
private Integer shortId;
#JsonProperty("pmns")
#Valid
private List<Pmn> pmns = new ArrayList<Pmn>();
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("name")
public String getName() {
return name;
}
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
#JsonProperty("shortId")
public Integer getShortId() {
return shortId;
}
#JsonProperty("shortId")
public void setShortId(Integer shortId) {
this.shortId = shortId;
}
#JsonProperty("pmns")
public List<Pmn> getPmns() {
return pmns;
}
#JsonProperty("pmns")
public void setPmns(List<Pmn> pmns) {
this.pmns = pmns;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
-----------------------------------com.example.Pmn.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"name",
"position",
"pmnType"
})
public class Pmn {
#JsonProperty("name")
private String name;
#JsonProperty("position")
private Integer position;
#JsonProperty("pmnType")
private String pmnType;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("name")
public String getName() {
return name;
}
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
#JsonProperty("position")
public Integer getPosition() {
return position;
}
#JsonProperty("position")
public void setPosition(Integer position) {
this.position = position;
}
#JsonProperty("pmnType")
public String getPmnType() {
return pmnType;
}
#JsonProperty("pmnType")
public void setPmnType(String pmnType) {
this.pmnType = pmnType;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}

Categories

Resources