In this json, what is the best way to get the object products.
usuly I create All Objects I have in my json return, until i find I whant. But now whant a direct form.
Products products = new Products();
JsonOrigin jsonOrigin = getJson();
getJson() = VALUE --->
{"content": {
"date": 1467045042000, "id": 228371,
"volume": [
{ "shipment_order_volume_number": "1",
"products": [{"id": 13, "sku": "CPM"},{"id": 14,"sku": "QAA"}]
},
{ "shipment_order_volume_number": "2",
"products": [{"id": 15, "sku": "AAA"},{"id": 16,"sku": "ABC"}]
}
]
}
}
I whan in my products object with the values:
[{"id": 13, "sku": "CPM"},{"id": 14,"sku": "QAA"}, {"id": 15, "sku": "AAA"},{"id": 16,"sku": "ABC"}]
You need to have several POJOs
class Content {
private long date;
private int id;
private List<ShipmentOrder> volume;
// getters/setters
}
class ShipmentOrder {
#JsonProperty("shipment_order_volume_number")
private int shipmentOrderVolumeNumber;
private List<Product> products;
// getters/setters
}
class Product {
private int id;
private String sku;
// getters/setters
}
If you need to collect all products per instance of Content as you showed in your example, you may implement the following method:
class Content {
Set<Product> getAllProducts() {
if (null == volume) {
return null;
}
return volume.stream()
.filter (shipment -> shipment.getProducts() != null)
.flatMap(shipment -> shipment.getProducts().stream())
.collect(Collectors.toSet());
}
}
Related
I have this object that I'm retrieving from antoher microservice.
#Service
public class WebClientService {
public Mono<CuCoPerson> getCuCoPerson(Integer cucoId, String GS_AUTH_TOKEN) {
WebClient webClient = WebClient.create();
return webClient.get()
.uri(GET_RELATION_BY_ID + cucoId)
.header("Accept", "application/json")
.header("Authorization", GS_AUTH_TOKEN)
.retrieve()
.bodyToMono(CuCoPerson.class)
.map(cuCoPerson -> {
List<CustomerRelation> matches = cuCoPerson.getRelatedCustomers()
.stream()
.filter(relation -> relation.getSystemId().equals(400) || relation.getSystemId().equals(300) || relation.getSystemId().equals(410))
.filter(relation -> relation.getCustomerId().contains("F"))
.collect(Collectors.toList());
cuCoPerson.setRelatedCustomers(matches);
return cuCoPerson;
});
}
The controller is as follows:
#GetMapping("/getCucoId/{cucoId}")
public Mono<CuCoPerson> getCucoRelationById(#PathVariable Integer cucoId, #RequestHeader(value="Authorization") String GS_AUTH_TOKEN) {
return webClientService.getCuCoPerson(cucoId, GS_AUTH_TOKEN);
}
It returns a list of related customers like this:
{
"id": 1,
"relatedCustomers": [
{
"customerId": "xxx",
"systemId": 999
}
]
}
And now I need to add this list of customers to my PeopleDTO class which is as follows:
public class PeopleDTO {
private String processType;
private String operation;
private String entity;
private String entityType;
private Long id;
private Document document;
#Getter
#Setter
class Customer {
private String systemId;
private String customerId;
}
private List<Customer> customers;
}
UPDATE:
Here I'm hardcoding my PeopleDTO just as an example:
public PeopleDTO createPeople(Long id) {
PeopleDTO people = new PeopleDTO();
people.setProcessType("ONLINE");
people.setOperation("UPDATE");
people.setEntity("DOCUMENT");
people.setEntityType("DOCUMENT");
people.setIdCuco(id);
people.setDocument(new Document());
people.setCustomers(......);
}
So the result should be something like this:
{
"type": "ONLINE",
"operation": "UPDATE",
"id": 1,
"entity": "DOCUMENT",
"entityType": "NIE",
"documents": {
"id": 1,
"additionals": {
"issuing_authority": "Spain",
"country_doc": "ES",
"place_of_birth": "",
"valid_from": "1995-08-09",
"valid_to": "0001-01-01"
},
"code": "X12345",
"typeDocument": "NIE"
},
"id": 1,
"relatedCustomers": [
{
"customerId": "xxx",
"systemId": 999
}
]
}
The controller that supposed to retrieve this info is:
#GetMapping("getId/{cucoId}")
public PeopleDTO getFullPeople(#PathVariable Long id) {
return webClientService.createPeople(id);
}
How should I set the customers in here?
I'm trying to populate a List<Object> that has as a attribute another List.
Here is The Scenario.
First Object
public class Student {
private String initials;
private String id;
private List<StudentDetail> listStudentDetail;
//Setters and Getters
}
Second Object
public class StudentDetail {
private String id;
private String name;
//Setters and getters
}
My final java object is as follows.
public class Response {
private String code;
private String message;
private List<Student> listStudent;
//Setters and getters
}
I get populated a List<Student>and a List<StudentDetail> from another process and what I want to achive is merge both list into my Response class but with theese particular conditions
In order to fill List<StudentDetail>
Student.initials must be "a"
Student.id = StudentDetail.id
These is what I want to Achieve.
{
"code": "0",
"message": "Succes",
"listStudent": [
{
"initials": "a",
"id": "104",
"listStudentDetail": [
{
"id": "104",
"name": "Kevin"
}
]
},
{
"initials": "b",
"id": "100",
"listStudentDetail": []
},
{
"initials": "a",
"id": "105",
"listStudentDetail": [
{
"id": "105",
"name": "Robert"
}
]
}
]
}
Here is the code.
I am assuming populatedStudentList and populatedStudentDetail as the given objects that have been populated in some other part of the code like you mentioned.
for (Student s in populatedStudentList){
if (s.getInitials().compareTo('a') != 0){
continue;
}
String findId = s.getId();
List<StudentDetail> tempListStudentDetail = new ArrayList<>();
for (StudentDetail d in populatedStudentDetail){
if (d.getId().compareTo(findId) == 0){
tempListStudentDetail.append(d);
}
}
s.setListStudentDetail(tempListStudentDetail);
}
This can be achieved in a more memory efficient manner using hashTables but I have tried to reproduce the desired result in the most basic manner.
Suppose I have JSON as follow.
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "users",
"_type": "students",
"_id": "AWAEqh945A0BWjveqnd0",
"_score": 1,
"_source": {
"college": {
"sport": {
"name": "cricket",
"category": "batsman"
}
}
}
}
]
}
}
I want to map data to College object which start from _source field.
Is there way to say to Jackson or Gson to from where mapping should start ?
in this example from _source
The Response we get from ES server.
ES server hosted on AWS.
So we suppose to communicate through ES Java API RestClient.
Is it ok Query through ES Java API QueryBuilder.
What is Recommended. ?
I used below mention way.
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(resultJson);
String sourceString = jsonNode.at("/hits/hits/0/_source").toString();
College college = objectMapper.readValue(sourceString, College.class);
You can do the following using Gson:
JSONObject object = new JSONObject(s); // s is you String Json
JSONObject hits1 = object.getJSONObject("hits");
JSONArray hits = hits1.getJSONArray("hits");
for (Object jsonObj : hits) {
JSONObject json = (JSONObject) jsonObj;
JSONObject source = json.getJSONObject("_source");
College college = new Gson().fromJson(source.getJSONObject("college").toString(), College.class);
}
You also need these two Pojos:
public class College {
private Sport sport;
public College() {
}
public Sport getSport() {
return sport;
}
public void setSport(Sport sport) {
this.sport = sport;
}
}
public class Sport {
private String name;
private String category;
public Sport() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
I am trying to convert JSON objects to POJO's with GSON.
JSON String
[
{
"automation_project": {
"user_id": null,
"name": "Untitled Project",
"updated_at": "2015-06-16T19:39:42Z",
"group_id": 764496,
"created_at": "2014-11-23T01:01:59Z",
"id": 16214
}
},
{
"automation_project": {
"user_id": null,
"name": "newintropage",
"updated_at": "2015-06-16T21:20:47Z",
"group_id": 764496,
"created_at": "2015-06-16T20:39:04Z",
"id": 29501
}
}
]
The AutomationProjectsList class used with GSON
public class AutomationProjectsList {
private List<AutomationProject> automationProject = new ArrayList<AutomationProject>();
public List<AutomationProject> getAutomationProject() {
return automationProject;
}
public void setAutomationProject(List<AutomationProject> automationProject) {
this.automationProject = automationProject;
}
#Override
public String toString() {
return "AutomationProjectsList [automationProject=" + automationProject
+ "]";
}}
Automation Project POJO
public class AutomationProject {
private Object userId;
private Integer groupId;
private Integer id;
private String name;
private String updatedAt;
private String createdAt;
public Object getUserId() {
return userId;
}
public void setUserId(Object userId) {
this.userId = userId;
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer groupId) {
this.groupId = groupId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(String updatedAt) {
this.updatedAt = updatedAt;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}}
The code I'm using
JSONArray jsonArray = new JSONArray(response.getEntity(String.class));
for(int i = 0; i < jsonArray.length(); i++){
if(jsonArray.get(i) instanceof JSONObject){
JSONObject jsnObj = (JSONObject)jsonArray.get(i);
AutomationProjectsList obj = new Gson().fromJson(jsnObj.toString(), AutomationProjectsList.class);
System.out.println(obj.getAutomationProject().get(0).getId());
}
}
But it gives an exception :
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at br.usp.icmc.teste.ConnectionRestClient.getBrowserStackProjects(ConnectionRestClient.java:74)
at br.usp.icmc.teste.TestePrincipal.main(TestePrincipal.java:9)
Why am I receiving an IndexOutOfBoundsException exception? Where am I wrong?
Your class or your JSON are incorrect. I'd suggest your JSON is.
A JSON matching your POJO class would be:
{
"automationProjects":[
{
"user_id": null,
"name": "Untitled Project",
"updated_at": "2015-06-16T19:39:42Z",
"group_id": 764496,
"created_at": "2014-11-23T01:01:59Z",
"id": 16214
},
{
"user_id": null,
"name": "newintropage",
"updated_at": "2015-06-16T21:20:47Z",
"group_id": 764496,
"created_at": "2015-06-16T20:39:04Z",
"id": 29501
}
]
}
Notice I used the name automationProjects for the list as it makes more sense, so your class would be:
public class AutomationProjectsList {
private List<AutomationProject> automationProjects = new ArrayList<AutomationProject>();
public List<AutomationProject> getAutomationProjects() {
return automationProjects;
}
public void setAutomationProjects(List<AutomationProject> automationProjects) {
this.automationProjects = automationProjects;
}
#Override
public String toString() {
return "AutomationProjectsList [automationProject=" + automationProject
+ "]";
}
}
And finally to convert JSON to AutomationProjectsList object:
AutomationProjectsList projectsList = new Gson().fromJson(jsonArray.toString(), AutomationProjectsList.class);
Then if you want to log each project:
for(AutomationProject project : projectsList.automationProjects){
System.out.println(porject.getId());
}
In conclusion, your code seems to have the fallowing issues:
Do you have a list of lists or just a single list of projects? If the list is just one, why do you iterate jsonArray like its sub-objects are lists themselves?
If you model your class correctly on the JSON then you don't need to iterate the JSON to obtain your objects
The JSON you posted is quite weird and uneasy to use with Gson, is it a requirement or can you edit it as you please?
Hope this helps
EDIT
Since you stated you cannot change the JSON you get, then it gets a little more complex, but everything is up to modelling the classes on the JSON format. So let's start form this JSON:
[
{
"automation_project": {
"user_id": null,
"name": "Untitled Project",
"updated_at": "2015-06-16T19:39:42Z",
"group_id": 764496,
"created_at": "2014-11-23T01:01:59Z",
"id": 16214
}
},
{
"automation_project": {
"user_id": null,
"name": "newintropage",
"updated_at": "2015-06-16T21:20:47Z",
"group_id": 764496,
"created_at": "2015-06-16T20:39:04Z",
"id": 29501
}
}
]
Now, this is quite nasty, but let's see what we have here: we have an unnamed array of objects with a single attribute "automationProject" which is our actual AutomationProject Object. So in terms of structure, it is a list of objects which wrap an actual AutomationProject.
Thus you'll need to get rid of your AutomationProjectList and change it with the more meaningful AutomationProjectWrapper looking as fallows:
public class AutomationProjectsWrapper {
private AutomationProject automation_project = new AutomationProject();
public AutomationProject getAutomationProject() {
return automation_project;
}
public void setAutomationProject(AutomationProject automationProject) {
this.automation_project = automationProject;
}
#Override
public String toString() {
return "AutomationProjectsList [automationProject=" + automation_project
+ "]";
}
}
See this class is equivalent to the JSON Object:
{
"automation_project": {
"user_id": null,
"name": "Untitled Project",
"updated_at": "2015-06-16T19:39:42Z",
"group_id": 764496,
"created_at": "2014-11-23T01:01:59Z",
"id": 16214
}
}
Finally you'll have an array of such wrapper objects as your jsonArray so you can write:
AutomationProjectWrapper[] projectsList = new Gson().fromJson(jsonArray.toString(), AutomationProjectWrapper[].class);
Then to log your objects:
for(AutomationProjectWrapper wrapper : projectsList){
System.out.println(wrapper.getAutomationProject().getId());
}
EDIT 2
Sorry for the mistake, in AutomationProjectWrapper class the AutomationProject field should be named automation_project.
Fixed in code above.
According to your JSON String the value you are trying to access is :
jsonString[i].automation_project.user_id
In your code you have: obj.getAutomationProject().get(0).getId()
I think is should be: obj[i].getAutomationProject().getId()
I'm trying to serialize to serialize the json string I have included below.
{
"mood": {
"is_featured": true,
"description": null,
"title": "2014 ",
"ordering": null,
"is_recently_modified": true,
"is_test": false,
"tracks": [
{
"album": {
"release_date": "2014-11-06",
"id": 359778,
"name": "Amansız Gücenik"
},
"name": "Hırpalandı Mayıs",
"artist": {
"id": 491169,
"name": "Ceylan Ertem"
},
"duration": 227,
"isrc": "TRA161400207",
"id": 3903997
},
{
"album": {
"release_date": "2013-08-05",
"id": 329129,
"name": "For Fuld Musik - 25 Danske Sommer Pop & Rock Hits Vol. 2"
},
"name": "Am I Wrong",
"artist": {
"id": 755957,
"name": "Nico & Vinz"
},
"duration": 387,
"isrc": "NO2G31301011",
"id": 3655085
}
],
"image_url": "some_url",
"is_recently_created": true,
"id": 128
}
}
I'm using this gson call to serialize it
Mood mood = new Gson().fromJson(result, Mood.class);
My class structers are like this.
public class Mood {
private boolean is_featured;
private boolean is_recently_modified;
private boolean is_recently_created;
private boolean is_test;
private String description;
private String title;
private String image_url;
private int id;
private int ordering;
private Track[] tracks;
public static class MoodContainer {
public Mood[] moods;
}
}
public class Track {
//variables
private Album album;
private Artist artist;
private Provider provider;
private String secure_url;
private String name;
private String region;
private String isrc;
private int duration;
private int track_order;
private int id;
}
And it goes on like this for any additional class variable. When I try to use the above call I end up with objects that have all null values. One thing to notice is some fields are not supplied in json string because different api calls supply different parts of these json strings. What I am doing wrong?
Root JSON object you provided has property mood - so you either have two options for deserialization to work properly:
Wrap your Mood class inside another object like this:
public class MoodWrapper { private Mood mood; }
and change de-serialization code to
MoodWrapper moodWrapper = new Gson().fromJson(result, MoodWrapper.class);
Skip a root object when deserializing:
final Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonObject rootObj = parser.parse(json).getAsJsonObject();
Mood mood = gson.fromJson(rootObj.getAsJsonObject("mood"), Mood.class);
The top-level elements in the JSON string should be your object's properties, not the outer element "mood" which you have.