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]}
Related
Firstly, my project has MinIO server where I use minio api to upload my files via spring boot application. The MinIO server integrated with Elasticsearch. When I uploaded a file, MinIO automatically update Elasticsearch minio_events index (I have configured this settings before). I want to run following query in my spring boot application and match result into File.java:
POST http://localhost:9200/minio_events/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"Records.s3.object.userMetadata.X-Amz-Meta-Filename": "myfile.txt"
}
},
{
"match": {
"Records.s3.object.userMetadata.X-Amz-Meta-User_id": "40b3c4e0-fea8-4aca-9dec-b4b905f33df0"
}
}
]
}
},
"fields": [
"Records.s3.object.userMetadata.X-Amz-Meta-Filename",
"Records.s3.object.userMetadata.X-Amz-Meta-Description",
"Records.s3.object.userMetadata.X-Amz-Meta-Foldername",
"Records.s3.object.userMetadata.X-Amz-Meta-Tags",
"Records.s3.object.userMetadata.X-Amz-Meta-User_id"
],
"_source": false
}
The query result is:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.7260925,
"hits": [
{
"_index": "minio_events",
"_type": "_doc",
"_id": "AUuxte4_W8625RK6e6oT7tCJmJkSQJ0L9LGx6eAf0Dw=",
"_score": 1.7260925,
"fields": {
"Records.s3.object.userMetadata.X-Amz-Meta-Foldername": [
"helloworld"
],
"Records.s3.object.userMetadata.X-Amz-Meta-Description": [
"des"
],
"Records.s3.object.userMetadata.X-Amz-Meta-User_id": [
"40b3c4e0-fea8-4aca-9dec-b4b905f33df0"
],
"Records.s3.object.userMetadata.X-Amz-Meta-Filename": [
"MyFile.txt"
],
"Records.s3.object.userMetadata.X-Amz-Meta-Tags": [
"hello,world"
]
}
}
]
}
}
In my Spring Boot App, I wrote following repository class to fetch Elasticsearch results.
CustomFileRepository.java:
package com.oktaykcr.fileservice.repository;
import com.oktaykcr.fileservice.model.File;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
#Component
public class CustomFileRepository {
private final ElasticsearchOperations elasticsearchOperations;
private final List<String> fields = List.of(
"Records.s3.object.userMetadata.X-Amz-Meta-Filename",
"Records.s3.object.userMetadata.X-Amz-Meta-Description",
"Records.s3.object.userMetadata.X-Amz-Meta-Foldername",
"Records.s3.object.userMetadata.X-Amz-Meta-Tags",
"Records.s3.object.userMetadata.X-Amz-Meta-User_id"
);
public CustomFileRepository(ElasticsearchOperations elasticsearchOperations) {
this.elasticsearchOperations = elasticsearchOperations;
}
public List<File> findByFileNameAndUserId(String fileName, String userId) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("Records.s3.object.userMetadata.X-Amz-Meta-Filename", fileName))
.must(QueryBuilders.matchQuery("Records.s3.object.userMetadata.X-Amz-Meta-User_id", userId));
Query query = new NativeSearchQuery(queryBuilder);
query.setFields(fields);
SearchHits<File> result = elasticsearchOperations.search(query, File.class);
if(result.isEmpty()) {
return Collections.emptyList();
}
List<File> files = result.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
return files;
}
}
File.java:
package com.oktaykcr.fileservice.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.List;
#Document(indexName = "minio_events")
public class File {
#Id
private String id;
#Field(type = FieldType.Object, value = "fields")
private Fields fields;
public File() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Fields getFields() {
return fields;
}
public void setFields(Fields fields) {
this.fields = fields;
}
static class Fields {
#Field(type = FieldType.Nested, value = "Records.s3.object.userMetadata.X-Amz-Meta-Foldername")
public List<String> folderName;
#Field(type = FieldType.Nested, value = "Records.s3.object.userMetadata.X-Amz-Meta-Description")
public List<String> description;
#Field(type = FieldType.Nested, value = "Records.s3.object.userMetadata.X-Amz-Meta-User_id")
public List<String> userId;
#Field(type = FieldType.Nested, value = "Records.s3.object.userMetadata.X-Amz-Meta-Filename")
public List<String> fileName;
#Field(type = FieldType.Nested, value = "Records.s3.object.userMetadata.X-Amz-Meta-Tags")
public List<String> tags;
public Fields() {
}
public List<String> getFolderName() {
return folderName;
}
public void setFolderName(List<String> folderName) {
this.folderName = folderName;
}
public List<String> getDescription() {
return description;
}
public void setDescription(List<String> description) {
this.description = description;
}
public List<String> getUserId() {
return userId;
}
public void setUserId(List<String> userId) {
this.userId = userId;
}
public List<String> getFileName() {
return fileName;
}
public void setFileName(List<String> fileName) {
this.fileName = fileName;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
}
}
However, the result of List<File> files = customFileRepository.findByFileNameAndUserId(fileName, userId); is:
result = {ArrayList#15401} size = 1
0 = {File#15403}
id = "AUuxte4_W8625RK6e6oT7tCJmJkSQJ0L9LGx6eAf0Dw="
fields = null
id was mapped by #Document model but fields was not.
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?
I am trying to use ModelMapper to map a collection of sub-objects to a list of id numbers.
public class Child {
private int id;
private String childName;
}
public class Parent {
private Set<Child> children;
private String parentName;
}
public class ParentDto {
private int[] children; // Or use ArrayList<Integer>
private String parentName;
}
How do I tell ModelMapper to flatten the set of Child objects to an array of id numbers?
My first attempt is this but does not seem correct:
modelMapper.addMappings(new PropertyMap<Parent, ParentDto>() {
#Override
protected void configure() {
using(ctx -> ctx.getSource().stream().map(Parent::getId).collect(Collectors.toList())
.map().setChildren(source.getId()));
};
});
Type listType = new TypeToken<ArrayList<ParentDto>>() {}.getType();
ArrayList<ParentDto> parentDtos = new ArrayList<>();
parentDtos = modelMapper.map(parents, listType);
The setChildren call seems like it needs to be map().add() but that does not work either.
Ideas are welcome.
One way of doing this is to create a Set<Child> to int[] converter and use it to map Parent.children to ParentDTO.children:
ModelMapper mapper = new ModelMapper();
Converter<Set<Child>, int[]> childSetToIntArrayConverter =
ctx -> ctx.getSource()
.stream()
.mapToInt(Child::getId)
.toArray();
mapper.createTypeMap(Parent.class, ParentDto.class)
.addMappings(map -> map
.using(childSetToIntArrayConverter)
.map(
Parent::getChildren,
ParentDto::setChildren
)
);
Here is the complete demo (using lombok 1.18.10 and modelmapper 2.3.5):
import lombok.AllArgsConstructor;
import lombok.Data;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Parent parent = new Parent();
parent.setParentName("Parent");
parent.setChildren(Set.of(
new Child(1, "A"),
new Child(2, "B"),
new Child(3, "C")
));
ModelMapper mapper = new ModelMapper();
Converter<Set<Child>, int[]> childSetToIntArrayConverter =
ctx -> ctx.getSource()
.stream()
.mapToInt(Child::getId)
.toArray();
mapper.createTypeMap(Parent.class, ParentDto.class)
.addMappings(map -> map
.using(childSetToIntArrayConverter)
.map(
Parent::getChildren,
ParentDto::setChildren
)
);
ParentDto dto = mapper.map(parent, ParentDto.class);
System.out.println(parent);
System.out.println(dto);
}
#Data
#AllArgsConstructor
public static class Child {
private int id;
private String childName;
}
#Data
public static class Parent {
private Set<Child> children;
private String parentName;
}
#Data
public static class ParentDto {
private int[] children;
private String parentName;
}
}
Output
Main.Parent(children=[Main.Child(id=3, childName=C), Main.Child(id=2, childName=B), Main.Child(id=1, childName=A)], parentName=Parent)
Main.ParentDto(children=[3, 2, 1], parentName=Parent)
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
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);
}
}