After using http://www.jsonschema2pojo.org/ to create POJO class to convert JSON to Java Object I'm trying to get property of "distance" "inMeters" to compare them but I can't get them because it is List is there any way I can compare them
{
"originAddresses": [
"58 Oxford St, Fitzrovia, London W1D 1BH, UK"
],
"destinationAddresses": [
"109 Marylebone High St, Marylebone, London W1U 4RX, UK",
"143 Great Titchfield St, Fitzrovia, London W1W, UK",
"210 Great Portland St, Fitzrovia, London W1W 5BQ, UK",
"43-51 Great Titchfield St, Fitzrovia, London W1W 7PQ, UK"
],
"rows": [
{
"elements": [
{
"status": "OK",
"duration": {
"inSeconds": 457,
"humanReadable": "8 mins"
},
"distance": {
"inMeters": 1662,
"humanReadable": "1.7 km"
}
},
{
"status": "OK",
"duration": {
"inSeconds": 383,
"humanReadable": "6 mins"
},
"distance": {
"inMeters": 1299,
"humanReadable": "1.3 km"
}
},
{
"status": "OK",
"duration": {
"inSeconds": 376,
"humanReadable": "6 mins"
},
"distance": {
"inMeters": 1352,
"humanReadable": "1.4 km"
}
},
{
"status": "OK",
"duration": {
"inSeconds": 366,
"humanReadable": "6 mins"
},
"distance": {
"inMeters": 932,
"humanReadable": "0.9 km"
}
}
]
}
]
}
This is my Main POJO Class in the compareTo class it require int but it show only List :
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class LocationGoogle implements Comparable<LocationGoogle> {
public LocationGoogle(String originAddress, String destinationAddress,Row
rows){
super();
this.destinationAddresses = destinationAddresses;
this.originAddresses = originAddresses;
this.rows= (List<Row>) rows;
}
#SerializedName("originAddresses")
#Expose
private List<String> originAddresses = null;
#SerializedName("destinationAddresses")
#Expose
private List<String> destinationAddresses = null;
#SerializedName("rows")
#Expose
private List<Row> rows = null;
public List<String> getOriginAddresses(){
return originAddresses;
}
public void setOriginAddresses(List<String> originAddresses){
this.originAddresses = originAddresses;
}
public List<String> getDestinationAddresses(){
return destinationAddresses;
}
public void setDestinationAddresses(List<String> destinationAddresses){
this.destinationAddresses = destinationAddresses;
}
public List<Row> getRows(){
return rows;
}
public void setRows(List<Row> rows){
this.rows = rows;
}
#Override
public int compareTo(LocationGoogle compareTime){
int compare =((LocationGoogle)compareTime).getRows();
return 0;
}
}
Is JSON to Java Object is good or bad way to convert JSON to java data. Should I keep doing this or find another way?
This is class Row :
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Row {
#SerializedName("elements")
#Expose
private List<Element> elements = null;
public List<Element> getElements() {
return elements;
}
public void setElements(List<Element> elements) {
this.elements = elements;
}
#Override
public String toString(){
return String.valueOf(elements);
}
}
This is Elements class:
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Element {
#SerializedName("status")
#Expose
private String status;
#SerializedName("duration")
#Expose
private Duration duration;
#SerializedName("distance")
#Expose
private Distance distance;
#Override
public String toString(){
return String.valueOf(distance);
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Distance getDistance() {
return distance;
}
public void setDistance(Distance distance) {
this.distance = distance;
}
}
This is Duration class:
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Duration {
#SerializedName("inSeconds")
#Expose
private Integer inSeconds;
#SerializedName("humanReadable")
#Expose
private String humanReadable;
public Integer getInSeconds() {
return inSeconds;
}
public void setInSeconds(Integer inSeconds) {
this.inSeconds = inSeconds;
}
public String getHumanReadable() {
return humanReadable;
}
public void setHumanReadable(String humanReadable) {
this.humanReadable = humanReadable;
}
#Override
public String toString (){
return String.valueOf(inSeconds);
}
}
This is Distance class:
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Distance implements Comparable{
#SerializedName("inMeters")
#Expose
private Integer inMeters;
#SerializedName("humanReadable")
#Expose
private String humanReadable;
public Integer getInMeters() {
return inMeters;
}
public void setInMeters(Integer inMeters) {
this.inMeters = inMeters;
}
public String getHumanReadable() {
return humanReadable;
}
public void setHumanReadable(String humanReadable) {
this.humanReadable = humanReadable;
}
#Override
public String toString(){
return String.valueOf(inMeters);
}
#Override
public int compareTo(Object o){
int compare = ((Distance)o).getInMeters();
return compare-this.inMeters;
}
}
The code i using to compare them:
#Override
public int compareTo(LocationGoogle compareTime){
String i= getRows()
int compare =((LocationGoogle)compareTime).getRows();
return 0;
}
After seeing required int but have List i confusing.
FileReader reader = new FileReader("Path to json file");
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(reader);
System.out.println("json object = "+json.toString());
JSONArray result = (JSONArray) json.get("rows");
JSONObject result1 = (JSONObject)result.get(0);
JSONArray elements = (JSONArray) result1.get("elements");
JSONObject result2 = (JSONObject)elements.get(0);
JSONObject distance = (JSONObject)result2.get("distance");
JSONObject duration = (JSONObject)result2.get("duration");
Distance=(String)distance.get("inMeters");
use json_simple-1.0.2.jar file. It is step by step extraction.
Related
I am getting this response from my Express API Call.
Here's the Response:
{
"responseData": [{
"unitNames": [
"Matrices",
"Complex Numbers"
],
"subject": "maths",
"unitTopics": {
"1": [{
"topicName": "1.1 Introduction",
"topicURL": ""
},
{
"topicName": "1.2 Square Matrix",
"topicURL": ""
}
],
"2": [{
"topicName": "2.1 Numbers",
"topicURL": ""
}
]
}
}]
}
I got the response by using Retrofit in Android. It works great.But it can't parse Objects
Here's my Problem in Android Side.
{
"responseData": [{
"unitNames": [
"Matrices",
"Complex Numbers"
],
"subject": "maths",
"unitTopics": {
"1": [[Object],
[Object]
],
"2": [[Object]
]
}
}]
}
Its showing Object instead of my Data. How to fix this
Here's the Code:
System.out.println(response.body().getResponseData())
String received_data = response.body().getResponseData();
received_data_sub_units_topics_json = new JSONArray("["+received_data+"]");
System.out.println("MAIN2 "+received_data_sub_units_topics_json);
After converting to jsonarray, it shows like this,
{
"responseData": [{
"unitNames": [
"Matrices",
"Complex Numbers"
],
"subject": "maths",
"unitTopics": {
"1": [["Object"],
["Object"]
],
"2": [["Object"]
]
}
}]
}
Please help me with some solutions
For json i always use the library com.fasterxml.jackson.
You can use too org.json.JSONArray, org.json.JSONObject.
Here is an example of each one:
1- jackson
For implements this (is a bit long but you will convert it to java classes, so, you will can edit the values and obtain it more easily than if you use JSONObject), you have to create classes wich has the same structure than your json:
public class principalClass {
ArrayList<ResponseData> responseData;
...
//Getters, setters and constructors
}
public class ResponseData {
public ArrayList<String> unitNames;
public String subject;
public UnitTopics unitTopics;
...
//Getters, setters and constructors
}
public class UnitTopics {
public ArrayList<Topics> first;
public ArrayList<Topics> second;
...
//Getters, setters and constructors
}
public class Topics {
public String topicName;
public String topicURL;
...
//Getters, setters and constructors
}
Something like that, and then you use jackson to pass your json to you class principalClass:
ObjectMapper obj= new ObjectMapper();
PrincipalClass principal= obj.readValue(json, PrincipalClass.class);
The second posibility is to convert the values to JSONArray and JSONObject:
JSONObject bodyJSON = new JSONObject(json);
JSONArray responseData = bodyJSON.getJSONArray("responseData");
JSONArray unitNames= responseData.getJSONArray(0);
JSONObject subject= responseData.getJSONObject(1);
...
And if u want, u can loop through a JSONArray:
for (int i = 0; i < unitNames.length(); i++) {
String element = unitNames.getString(i);
}
You can use gson converter with retrofit to convert your json data to java object model class
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
Or you can convert json data to model class like
Gson gson = new Gson();
String jsonInString = "{your json data}";
ResponseModel response= gson.fromJson(jsonInString, ResponseModel.class);
Hey have you tried converting this JSON Object to a POJO.
I'd recommend using:
This website
It saves a lot of time and effort.
These will be your model classes:
package com.example.app;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ResponseDatum implements Serializable
{
#SerializedName("unitNames")
#Expose
private List<String> unitNames = null;
#SerializedName("subject")
#Expose
private String subject;
#SerializedName("unitTopics")
#Expose
private UnitTopics unitTopics;
public ResponseDatum() {
}
public ResponseDatum(List<String> unitNames, String subject, UnitTopics unitTopics) {
super();
this.unitNames = unitNames;
this.subject = subject;
this.unitTopics = unitTopics;
}
public List<String> getUnitNames() {
return unitNames;
}
public void setUnitNames(List<String> unitNames) {
this.unitNames = unitNames;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public UnitTopics getUnitTopics() {
return unitTopics;
}
public void setUnitTopics(UnitTopics unitTopics) {
this.unitTopics = unitTopics;
}
}
package com.example.app;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ResponseObject implements Serializable
{
#SerializedName("responseData")
#Expose
private List<ResponseDatum> responseData = null;
public ResponseObject() {
}
public ResponseObject(List<ResponseDatum> responseData) {
super();
this.responseData = responseData;
}
public List<ResponseDatum> getResponseData() {
return responseData;
}
public void setResponseData(List<ResponseDatum> responseData) {
this.responseData = responseData;
}
}
package com.example.app;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class UnitTopics implements Serializable
{
#SerializedName("1")
#Expose
private List<com.example.app._1> _1 = null;
#SerializedName("2")
#Expose
private List<com.example.app._2> _2 = null;
public UnitTopics() {
}
public UnitTopics(List<com.example.app._1> _1, List<com.example.app._2> _2) {
super();
this._1 = _1;
this._2 = _2;
}
public List<com.example.app._1> get1() {
return _1;
}
public void set1(List<com.example.app._1> _1) {
this._1 = _1;
}
public List<com.example.app._2> get2() {
return _2;
}
public void set2(List<com.example.app._2> _2) {
this._2 = _2;
}
}
package com.example.app;
import java.io.Serializable;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class _1 implements Serializable
{
#SerializedName("topicName")
#Expose
private String topicName;
#SerializedName("topicURL")
#Expose
private String topicURL;
public _1() {
}
public _1(String topicName, String topicURL) {
super();
this.topicName = topicName;
this.topicURL = topicURL;
}
public String getTopicName() {
return topicName;
}
public void setTopicName(String topicName) {
this.topicName = topicName;
}
public String getTopicURL() {
return topicURL;
}
public void setTopicURL(String topicURL) {
this.topicURL = topicURL;
}
}
package com.example.app;
import java.io.Serializable;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class _2 implements Serializable
{
#SerializedName("topicName")
#Expose
private String topicName;
#SerializedName("topicURL")
#Expose
private String topicURL;
public _2() {
}
public _2(String topicName, String topicURL) {
super();
this.topicName = topicName;
this.topicURL = topicURL;
}
public String getTopicName() {
return topicName;
}
public void setTopicName(String topicName) {
this.topicName = topicName;
}
public String getTopicURL() {
return topicURL;
}
public void setTopicURL(String topicURL) {
this.topicURL = topicURL;
}
}
I have created some Json file that contains shop's objects and i want to store it on Google drive and read it with Retrofit.
Currently, I can't store it in local memory or in-app.
Also, there is no server side yet, so it needs to be stored somewhere that Retrofit can access.
If you have any other ideas, I'd be more than happy to hear.
I make the link public to anyone, and here is my .json file:
{
"shop": [
{
"shopName": "Renuar",
"shopID": "1000",
"isPaid": "false",
"branches": [
{
"branchName": "Branch 1",
"branchPhone": "039599559",
"openingTime": "09:00",
"closingTime": "21:00",
"branchLat": "32.000",
"branchLon": "35.000",
"branchAddressNote": "Grand Canyon"
}
]
},
{
"shopName": "Castro",
"shopID": "1000",
"isPaid": "false",
"branches": [
{
"branchName": "Branch 1",
"branchPhone": "039599559",
"openingTime": "09:00",
"closingTime": "21:00",
"branchLat": "32.000",
"branchLon": "35.000",
"branchAddressNote": "Grand Canyon"
}
]
}
]
}
I've tried the next steps but it's not work for me.
public interface ApiService {
#GET("file/d/1-lsBIzI7Y5uCg8bG_531o49Dcu6E2RdH/view?usp=sharing")
Call<ShopsResponse> getAllShops();
}
public static class RetrofitInstance{
public static Retrofit retrofit = null;
private static final String BASE_URL = "https://drive.google.com/";
public static ApiService getApiService(){
if (retrofit == null){
Gson gson = new GsonBuilder()
.setLenient()
.create();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit.create(ApiService.class);
}
}
ApiService apiService = RetrofitInstance.getApiService();
apiService.getAllShops().enqueue(new Callback<ShopsResponse>() {
#Override
public void onResponse(Call<ShopsResponse> call, Response<ShopsResponse> response) {
ShopsResponse response1 = response.body();
Log.d(TAG, "onResponse: "+response1.getShop().size());
}
#Override
public void onFailure(Call<ShopsResponse> call, Throwable t) {
Log.d(TAG, "onResponse: "+t.getMessage());
}
});
That what i receive in logcat:
D/myDebug: onResponse: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 1 path $
I think there is something wrong with your pojo objects. It should be like this according to your response
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Branch {
#SerializedName("branchName")
#Expose
private String branchName;
#SerializedName("branchPhone")
#Expose
private String branchPhone;
#SerializedName("openingTime")
#Expose
private String openingTime;
#SerializedName("closingTime")
#Expose
private String closingTime;
#SerializedName("branchLat")
#Expose
private String branchLat;
#SerializedName("branchLon")
#Expose
private String branchLon;
#SerializedName("branchAddressNote")
#Expose
private String branchAddressNote;
public String getBranchName() {
return branchName;
}
public void setBranchName(String branchName) {
this.branchName = branchName;
}
public String getBranchPhone() {
return branchPhone;
}
public void setBranchPhone(String branchPhone) {
this.branchPhone = branchPhone;
}
public String getOpeningTime() {
return openingTime;
}
public void setOpeningTime(String openingTime) {
this.openingTime = openingTime;
}
public String getClosingTime() {
return closingTime;
}
public void setClosingTime(String closingTime) {
this.closingTime = closingTime;
}
public String getBranchLat() {
return branchLat;
}
public void setBranchLat(String branchLat) {
this.branchLat = branchLat;
}
public String getBranchLon() {
return branchLon;
}
public void setBranchLon(String branchLon) {
this.branchLon = branchLon;
}
public String getBranchAddressNote() {
return branchAddressNote;
}
public void setBranchAddressNote(String branchAddressNote) {
this.branchAddressNote = branchAddressNote;
}
}
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("shop")
#Expose
private List<Shop> shop = null;
public List<Shop> getShop() {
return shop;
}
public void setShop(List<Shop> shop) {
this.shop = shop;
}
}
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Shop {
#SerializedName("shopName")
#Expose
private String shopName;
#SerializedName("shopID")
#Expose
private String shopID;
#SerializedName("isPaid")
#Expose
private String isPaid;
#SerializedName("branches")
#Expose
private List<Branch> branches = null;
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getShopID() {
return shopID;
}
public void setShopID(String shopID) {
this.shopID = shopID;
}
public String getIsPaid() {
return isPaid;
}
public void setIsPaid(String isPaid) {
this.isPaid = isPaid;
}
public List<Branch> getBranches() {
return branches;
}
public void setBranches(List<Branch> branches) {
this.branches = branches;
}
}
I'm using Jackson to write a Java object to Json.
This is wath I am getting
{
"obj": [{
"Id": 1,
"type": "type1",
"properties": [{
"name": "PropN",
"value": "ValN"
}]
}, {
"id": 2,
"type": "type",
"properties": [{
"name": "Prop3",
"value": "Val3"
}]
}]
}
This is what i need to get:
{
"obj": [{
"id": 1,
"type": "type",
"properties": {
"name": "Eb1"
}
},
{
"id": 2,
"type": "type",
"properties": {
"name": "Eb2"
}
}
]
}
I dont know how to get the properties name and value "tags" from the json and also, remove the properties array to a list.
My Properties array is a simple POJO, and the Obj class has an ArrayList of properties.
Can someone tell me how to get this done?
Thanks.
You can use quicktype to generate the exact types you need. Here's what it produces with the JSON you require:
// Converter.java
// https://stackoverflow.com/questions/49055781/java-convert-to-correct-json-format-using-jackson
// import io.quicktype.Converter;
//
// Then you can deserialize a JSON string with
//
// StackOverflow data = Converter.fromJsonString(jsonString);
package io.quicktype;
import java.util.Map;
import java.io.IOException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.core.JsonProcessingException;
public class Converter {
// Serialize/deserialize helpers
public static StackOverflow fromJsonString(String json) throws IOException {
return getObjectReader().readValue(json);
}
public static String toJsonString(StackOverflow obj) throws JsonProcessingException {
return getObjectWriter().writeValueAsString(obj);
}
private static ObjectReader reader;
private static ObjectWriter writer;
private static void instantiateMapper() {
ObjectMapper mapper = new ObjectMapper();
reader = mapper.reader(StackOverflow.class);
writer = mapper.writerFor(StackOverflow.class);
}
private static ObjectReader getObjectReader() {
if (reader == null) instantiateMapper();
return reader;
}
private static ObjectWriter getObjectWriter() {
if (writer == null) instantiateMapper();
return writer;
}
}
// StackOverflow.java
package io.quicktype;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;
public class StackOverflow {
private Obj[] obj;
#JsonProperty("obj")
public Obj[] getObj() { return obj; }
#JsonProperty("obj")
public void setObj(Obj[] value) { this.obj = value; }
}
// Obj.java
package io.quicktype;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;
public class Obj {
private long id;
private String type;
private Properties properties;
#JsonProperty("id")
public long getID() { return id; }
#JsonProperty("id")
public void setID(long value) { this.id = value; }
#JsonProperty("type")
public String getType() { return type; }
#JsonProperty("type")
public void setType(String value) { this.type = value; }
#JsonProperty("properties")
public Properties getProperties() { return properties; }
#JsonProperty("properties")
public void setProperties(Properties value) { this.properties = value; }
}
// Properties.java
package io.quicktype;
import java.util.Map;
import com.fasterxml.jackson.annotation.*;
public class Properties {
private String name;
#JsonProperty("name")
public String getName() { return name; }
#JsonProperty("name")
public void setName(String value) { this.name = value; }
}
I'm getting the following error when using an ObjectMapper to de-serialize an object:
JSONMappingException Can not construct instance of
org.springframework.data.Page, problem: abstract types can only be
instantiated with additional type information.
I am trying to serialize a JSON string into a Spring data object org.springframework.data.Page which represents a page of type T.
The User class is a simple POJO with first and last name. The JSON string I am deserializing is:
{
"content": [
{
"firstname": "John",
"lastname": "Doe"
},
{
"firstname": "Jane",
"lastname": "Doe"
}
],
"size": 2,
"number": 0,
"sort": [
{
"direction": "DESC",
"property": "timestamp",
"ascending": false
}
],
"totalPages": 150,
"numberOfElements": 100,
"totalElements": 15000,
"firstPage": true,
"lastPage": false
}
This causes the exception:
Page<User> userPage = (Page<User>) new ObjectMapper().mapToJavaObject(json, new TypeReference<Page<User>>(){};
Since Page is a Spring object I cannot modify it which I think makes this a bit different from the way I see this question asked elsewhere. Any thoughts?
I ended up using something like this, creating a bean as #Perception suggested:
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
public class PageImplBean<T> extends PageImpl<T> {
private static final long serialVersionUID = 1L;
private int number;
private int size;
private int totalPages;
private int numberOfElements;
private long totalElements;
private boolean previousPage;
private boolean firstPage;
private boolean nextPage;
private boolean lastPage;
private List<T> content;
private Sort sort;
public PageImplBean() {
super(new ArrayList<T>());
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public int getNumberOfElements() {
return numberOfElements;
}
public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
}
public long getTotalElements() {
return totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
public boolean isPreviousPage() {
return previousPage;
}
public void setPreviousPage(boolean previousPage) {
this.previousPage = previousPage;
}
public boolean isFirstPage() {
return firstPage;
}
public void setFirstPage(boolean firstPage) {
this.firstPage = firstPage;
}
public boolean isNextPage() {
return nextPage;
}
public void setNextPage(boolean nextPage) {
this.nextPage = nextPage;
}
public boolean isLastPage() {
return lastPage;
}
public void setLastPage(boolean lastPage) {
this.lastPage = lastPage;
}
public List<T> getContent() {
return content;
}
public void setContent(List<T> content) {
this.content = content;
}
public Sort getSort() {
return sort;
}
public void setSort(Sort sort) {
this.sort = sort;
}
public PageImpl<T> pageImpl() {
return new PageImpl<T>(getContent(), new PageRequest(getNumber(),
getSize(), getSort()), getTotalElements());
}
}
and then modify your code to use the concrete class and get the PageImpl:
#SuppressWarnings("unchecked")
Page<User> userPage = ((PageImplBean<User>)new ObjectMapper().readValue(json, new TypeReference<PageImplBean<User>>() {})).pageImpl();
You can do this:
public class YourClass {
static class CustomPage extends PageImpl<User> {
#JsonCreator(mode = Mode.PROPERTIES)
public CustomPage(#JsonProperty("content") List<User> content, #JsonProperty("number") int page, #JsonProperty("size") int size, #JsonProperty("totalElements") long total) {
super(content, new PageRequest(page, size), total);
}
}
public Page<User> makeRequest(String json) {
Page<User> pg = new ObjectMapper().readValue(json, CustomPage.class);
return pg;
}
}
given the following json:
{ "response": {
"totalProcessingTime": "271.0",
"resultSets": {
"products": {
"firstHit": "1",
"lastHit": "10",
"totalHits": "77",
"hits": [
{
"number": "1",
"dmsubcategory": "TV, lyd og bilde",
"collection": "tilbud",
"title": "<b>TV</b> Panasonic 47 TX-LU 7ET5Y"
},
{
"number": "2",
"dmsubcategory": "TV, lyd og bilde",
"collection": "tilbud",
"title": "<b>TV</b> Panasonic 47 TX-LU 7ET5Y"
},
{
"number": "3",
"dmsubcategory": "TV, lyd og bilde",
"collection": "tilbud",
"title": "<b>TV</b> Panasonic 47 TX-LU 7ET5Y"
}
]
}
}
}
}
I'm using the following code to call jackson:
ObjectMapper mapper = new ObjectMapper();
SearchResult searchResult = mapper.readValue(new URL(jsonUrl + queryUrl), SearchResult.class);
I have ganerated POJOs for the whole hiearchy where the products class looks like:
public class Products {
public List<Hits> hits;
public String totalHits;
#JsonAnySetter
public void handleUnknown(String key, Object value) {
// do something: put to a Map; log a warning, whatever
}
public List<Hits> getHits() {
return hits;
}
public void setHits(List<Hits> hits) {
this.hits = hits;
}
public String getTotalHits() {
return totalHits;
}
public void setTotalHits(String totalHits) {
this.totalHits = totalHits;
}
}
and the hits class:
public class Hits {
public String number;
public String title;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#JsonAnySetter
public void handleUnknown(String key, Object value) {
// do something: put to a Map; log a warning, whatever
}
}
All the other properties are mapped correct, but not the list containing hits. It's all empty. How can I map this to get it right?
Thanks!
You model is not compatible.
In order to see what is going wrong, maybe it is a good idea to have some toStrings and you could easy see where the mapping is failing.
You have a Object that needs to hold a property response, that needs to hold a property resultSets that needs to hold a property products that needs to hold hits.
I implemented like this:
GeneralResponse
- Response
- ResultSets
- Products
- Hits
- number
- title
Please test following implementation:
package snippet;
public class GeneralResponse {
private Response response;
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
#Override
public String toString() {
return "GeneralResponse [response=" + response + "]";
}
}
package snippet;
public class ResultSets {
private Products products;
public Products getProducts() {
return products;
}
public void setProducts(Products products) {
this.products = products;
}
#Override
public String toString() {
return "ResultSets [products=" + products + "]";
}
}
package snippet;
import java.util.List;
import org.codehaus.jackson.annotate.JsonAnySetter;
public class Products {
public List<Hits> hits;
public String totalHits;
#JsonAnySetter
public void handleUnknown(String key, Object value) {
// do something: put to a Map; log a warning, whatever
}
public List<Hits> getHits() {
return hits;
}
public void setHits(List<Hits> hits) {
this.hits = hits;
}
public String getTotalHits() {
return totalHits;
}
public void setTotalHits(String totalHits) {
this.totalHits = totalHits;
}
#Override
public String toString() {
return "Products [hits=" + hits + ", totalHits=" + totalHits + "]";
}
}
package snippet;
import org.codehaus.jackson.annotate.JsonAnySetter;
public class Response {
private ResultSets resultSets;
public ResultSets getResultSets() {
return resultSets;
}
public void setResultSets(ResultSets resultSets) {
this.resultSets = resultSets;
}
#Override
public String toString() {
return "Response [resultSets=" + resultSets + "]";
}
#JsonAnySetter
public void handleUnknown(String key, Object value) {
// do something: put to a Map; log a warning, whatever
}
}
package snippet;
import org.codehaus.jackson.annotate.JsonAnySetter;
public class Hits {
public String number;
public String title;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#JsonAnySetter
public void handleUnknown(String key, Object value) {
// do something: put to a Map; log a warning, whatever
}
#Override
public String toString() {
return "Hits [number=" + number + ", title=" + title + "]";
}
}
after all you can do something like:
ObjectMapper om = new ObjectMapper();
Object r = om.readValue(inputStream, GeneralResponse.class);
The code looks fine. The error may be in json response
"title": "<b>TV</b> Panasonic 47”TX-LU 7ET5Y"
The backquotes after 47 and before TX, might be troublesome. Please check if you can parse this response.