Have searched in different sites but couldn't find correct answer, hence posting this request though it could possible duplicates.sorry for that.
I am sending the below json request to my back-end service and converting to java object for processing. I can see the request body passed to my service but when i convert from json to java object , values are not populating
{
"data":{
"username":"martin",
"customerId":1234567890,
"firstName":"john",
"lastName":"smith",
"password":"p#ssrr0rd##12",
"email":"john.smith#gmail.com",
"contactNumber":"0342323443",
"department":"sports",
"location":"texas",
"status":"unlocked",
"OrderConfigs":[
{
"vpnId":"N4234554R",
"serviceId":"connectNow",
"serviceType":"WRLIP",
"ipAddress":"10.101.10.3",
"fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
"timeout":1800,
"mapId":"test_map"
}
]
}
}
My Parser class have something like,
JSONObject requestJSON = new JSONObject(requestBody).getJSONObject("data");
ObjectMapper mapper = new ObjectMapper();
final String jsonData = requestJSON.toString();
OrderDTO mappedObject= mapper.readValue(jsonData , OrderDTO .class);
// I can see value coming from front-end but not populating in the mappedObject
My OrderDTO.java
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true,value = {"hibernateLazyInitializer", "handler", "created"})
public class OrderDTO {
private String username;
private long customerId;
private String source;
private String firstName;
private String lastName;
private String email;
private String contactNumber;
private String password;
private String department;
private String location;
private String status;
private List<OrderConfig> OrderConfigs;
#JsonInclude(value = Include.NON_NULL)
public class OrderConfig {
private String vpnId;
private String serviceId;
private String serviceType;
private String ipAddress;
private String mapId;
private String[] fRoutes;
private Map<String, Object> attributes;
private SubConfig subConfig;
private String routeFlag;
getter/setters
.....
}
all setter/getter
}
Not sure what I'm missing here. Is this right way to do?
If your are trying to use inner class, correct way to use is to declare it static for Jackson to work with inner classes.
For reference check this
code changes made are
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
static class OrderConfig {
Make sure that your json tag names match with variable names of java object
Ex : "fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
private String[] fRoutes;
OrderConfigs fields will not be initialized, just modify your bean as
#JsonProperty("OrderConfigs")
private List<OrderConfig> orderConfigs;
// setter and getter as setOrderConfigs / getOrderConfigs
See my answer here. (same issue)
Related
I am using Jackson library with java 11 so basically I am able to read the below JSON into a string format
{
"schemas":[
"urn:params:core:2.0:User",
"urn:params:core:3.0:User"
],
},
}
here below is the set in which I have to fill the values of schemas from above json
private Set<String> setschemas = null;
right now I am able to read the above json into a string named finaljson , now please advise how can I read the differnt value of schemas from above json string named finaljson and set it to set named setschemas
if (node.has("schemas")) {
// *** here I want to read the differernt value of schemas and set it to a set
// named setschemas
// *****
}
you can create the following classes that represent the json structure
class MyJsonObject {
private AppIdentity appIdentity;
private Set<String> schemas;
private String userName;
}
class AppIdentity {
private String clientId;
private String username;
}
than you can use
final MyJsonObject myJsonObject = new ObjectMapper().readValue(finaljson, MyJsonObject.class); to read the json to JAVA object
so it can manipulated like myJsonObject.schemas.size() > 0 and such...
there are a lot of examples in the internet
*keep in mind, this solution only works when the json structure and fields name are known in advanced
With your approach, this would be simplest one:
if(node.has("schemas")) {
JsonNode schemaNode = node.get("schemas");
Set<String> schemaSet = objectMapper.convertValue(schemaNode, Set.class);
System.out.println("schemaSet" + schemaSet);
}
There are various ways to deal with JSON one is described here
1) You can create a class of JSON structure as follows with help online JSON to POJO convertor (Note:: Add Setters and Getters with help of IDE)
class AppJson {
private Set<AppIdentity> appIdentity;
private Set<String> schemas;
private String userName;
private Manager ManagerObject;
private String division;
private String organization;
private String costCenter;
private String employeeNumber;
}
class AppIdentity {
private String clientId;
private String username;
}
class Manager {
private String value;
private String $ref;
private String displayName;
private String $Ref;
}
2) Use above for object conversion.
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"appIdentity\":[{\"clientId\":\"9a41763c642\",\"username\":\"XXX\"}],\"schemas\":[\"urn:params:core:2.0:User\",\"urn:params:core:3.0:User\"],\"userName\":\"ajklmnop_699100\",\"manager\":{\"value\":\"string\",\"$ref\":\"sdkoirk\",\"displayName\":\"string\",\"$Ref\":\"sdkweoirk\"},\"division\":\"string\",\"organization\":\"string\",\"costCenter\":\"string\",\"employeeNumber\":\"string\"}\n"
+ "";
AppJson appJson = objectMapper.readValue(jsonString, AppJson.class);
System.out.println("json " + appJson.getSchemas());
Here you will get the schemas.
Is it possible with Jackson to deserialize json with Builder pattern as well as with default setter and getter approach?
My object is created with Builder that covers only required (final) fields, but I have non-final fields with some values as well that need to be deserialized with setters.
Here is the sample that throws an exception in an attempt to deserialize it with:
new ObjectMapper().readValue(json, Foo.class);
json - json representation serialized with default Jackson serializer, like:
objectMapper.writeValueAsString(foo);
class
#Getter
#Setter
#ToString
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonDeserialize(builder = Foo.Builder.class)
public class Foo {
private final String key;
private final Long user;
private final String action;
private final String material;
private final String currency;
private Foo(String key, Long user, String action, String material, String currency) {
this.key = key;
this.user = user;
this.action = action;
this.material = material;
this.currency = currency;
}
public static class Builder {
private String key;
private Long user;
private String action;
private String material;
private String currency;
#JsonProperty("key")
public Foo.Builder withKey(String key) {
this.key = key;
return this;
}
#JsonProperty("user")
public Foo.Builder withUser(Long user) {
this.user = user;
return this;
}
#JsonProperty("action")
public Foo.Builder withAction(String action) {
this.action = action;
return this;
}
/// other 'with' setters....
}
#JsonProperty("state")
private int state;
#JsonProperty("stat")
private String stat;
#JsonProperty("step")
private String step;
}
The exception it throws like :
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "state" (class com.Foo$Builder), not marked as
ignorable (5 known properties: "key", "user", "action", "material",
"currency",])
If not possible what workaround is the cheapest?
Two things that are suspicious:
You are willing to use the builder inside the Foo class. In that case you should correct the specification
(SessionData.Builder.class is not correct in that case).
You are indeed trying to use an external builder. In this case you should remove or at least mark as ignorable the inner builder, this seems to be the reason of the excetpion you are getting.
In both cases you should make sure the final method to get the Foo instance is called build() otherwise you should annotate the builder with a #JsonPOJOBuilder(buildMethodName = "nameOfMethod", withPrefix = "set").
I'm having trouble with mapping resulting json data to pojo class with Retrofit. I need to determine Firebase topics by token. This can be eaisly done with Google's json api, as described here: https://developers.google.com/instance-id/reference/server#get_information_about_app_instances
In my case, server response is simlar to this:
{
"applicationVersion": "36",
"connectDate": "2018-02-04",
"attestStatus": "ROOTED",
"application": "<my application id>",
"scope": "*",
"authorizedEntity": "205414012839",
"rel": {
"topics": {
"topic1": {
"addDate": "2018-02-04"
},
"topic2": {
"addDate": "2018-01-31"
}
}
},
"connectionType": "WIFI",
"appSigner": "<hash>",
"platform": "ANDROID"
}
The problem is basically rel and topics structure, because topics is dynamic and field list can by anything and it's unknown. So I can't generate simple POJO to get it mapped by Retrfofit automatically.
Can I force Retrofit to treat topics as single String field, I will able to parse it later to retrieve topics list? Or is there any other soulution?
Any ideas?
If you use gson, you can define rel as a JsonElement. If you use moshi, you can define it as a Map.
for gson:
public class Response{
private String applicationVersion;
private String connectDate;
private String attestStatus;
private String application;
private String scope;
private String authorizedEntity;
private String connectionType;
private String appSigner;
private String platform;
private JsonElement rel;
}
for moshi:
public class Response{
private String applicationVersion;
private String connectDate;
private String attestStatus;
private String application;
private String scope;
private String authorizedEntity;
private String connectionType;
private String appSigner;
private String platform;
private Map<String, Map<String, Map<String, String>>> rel;
}
I have one JSON object which I am trying to read from Jackson API Object Mapper.
{
"ddt_id":"605",
"ddt_batch_code":"5769005b-e8f0-4ae8-8971-1c59ac1f02fd",
"keyword":"ADP",
"keyword_operation":"and",
"keyword_extract_match":"F",
"search_in":"name",
"filter_type":"entity,others",
"category":"2,3,5",
"gender":"",
"date_year":"",
"date_month":"",
"date_day":"",
"country":"",
"search_filter_uuid":"570bd722-315c-40b3-b2d6-4522ac1f02fd",
"ddt_qsk_question":"0",
"search_for":"all",
"search_category":"2,3,5",
"search_includes_name":"T",
"search_includes_profile_notes":"F",
"search_for_person":"F",
"search_for_entity":"T",
"search_for_others":"T",
"search_from_module":"DDMT.V.2.20",
"client_id":667,
"ip_address":"52.23.94.13",
"search_requester_id":false,
"search_requester_name":false,
"batch_id":"5769005b-e8f0-4ae8-8971-1c59ac1f02fd",
"person_query_index":4,
"company_query_index":4,
"is_ongoing":1
}
The Class I used to read this JSON in Object is :
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.UUID;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class SswltSearchParams {
#JsonProperty("batch_id")
private UUID batchId;
#JsonProperty("country")
private String country;
#JsonProperty("criteria_id")
private String id;
#JsonProperty("date_day")
private Integer day;
#JsonProperty("date_month")
private Integer month;
#JsonProperty("date_year")
private Integer year;
#JsonProperty("gender")
private String gender;
#JsonProperty("keyword")
private String keyword;
#JsonProperty("keyword_exact_match")
private String keywordExactMatch;
#JsonProperty("keyword_operation")
private String keywordOperation;
#JsonProperty("search_category")
private String searchCategory;
#JsonProperty("search_for")
private String searchFor;
#JsonProperty("search_for_anti_corruption")
private String searchForAntiCorruption;
#JsonProperty("search_for_entity")
private String searchForEntity;
#JsonProperty("search_for_others")
private String searchForOthers;
#JsonProperty("search_for_person")
private String searchForPerson;
#JsonProperty("search_for_watchlist")
private String searchForWatchlist;
#JsonProperty("search_includes_name")
private String searchIncludesName;
#JsonProperty("search_includes_profile_notes")
private String searchIncludesProfileNotes;
#JsonProperty("update_only")
private String updateOnly;
// getters and setters
}
When I am trying to place this JSON in Onject, I am not getting any error but I am getting NULL value.
try {
SswltMigrationCollection sswltSearchParams = mapper.readValue(searchCriteria.getScrCriteria(), SswltSearchParams.class);
} catch (IOException e) {
return null;
}
Why I am getting this sswltSearchParams as null? Please Help.
Your JSON can be parsed into a SswltSearchParams instance without any problems. The following code works fine:
String json = "{\"ddt_id\":\"605\",\"ddt_batch_code\":\"5769005b-e8f0-4ae8-8971-1c59ac1f02fd\",\"keyword\":\"ADP\",\"keyword_operation\":\"and\",\"keyword_extract_match\":\"F\",\"search_in\":\"name\",\"filter_type\":\"entity,others\",\"category\":\"2,3,5\",\"gender\":\"\",\"date_year\":\"\",\"date_month\":\"\",\"date_day\":\"\",\"country\":\"\",\"search_filter_uuid\":\"570bd722-315c-40b3-b2d6-4522ac1f02fd\",\"ddt_qsk_question\":\"0\",\"search_for\":\"all\",\"search_category\":\"2,3,5\",\"search_includes_name\":\"T\",\"search_includes_profile_notes\":\"F\",\"search_for_person\":\"F\",\"search_for_entity\":\"T\",\"search_for_others\":\"T\",\"search_from_module\":\"DDMT.V.2.20\",\"client_id\":667,\"ip_address\":\"52.23.94.13\",\"search_requester_id\":false,\"search_requester_name\":false,\"batch_id\":\"5769005b-e8f0-4ae8-8971-1c59ac1f02fd\",\"person_query_index\":4,\"company_query_index\":4,\"is_ongoing\":1}";
ObjectMapper mapper = new ObjectMapper();
SswltSearchParams sswltSearchParams = mapper.readValue(json, SswltSearchParams.class);
Not sure why the SswltMigrationCollection class came into play.
I am using to Retrofit to handle Calls to my API for an Android Application. I am trying to get Retrofit to handle the parsing of the JSON, and creating a list of Objects in accordance with the POJO i have created.
The error i receive is "com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 176".
I used JsonSchema2Pojo to generate my java classes. The classes and associated JSON are as follows.
{"status":"success","data":[{"sort_key":1,"event_id":1947357,"title":"2014 US Open Tennis Session 15 (Mens\/Womens Round of 16)","datetime_utc":"2014-09-01T15:00:00","venue":{"city":"Flushing","name":"Louis Armstrong Stadium","extended_address":"Flushing, NY 11368","url":"https:\/\/seatgeek.com\/venues\/louis-armstrong-stadium\/tickets\/?aid=10918","country":"US","display_location":"Flushing, NY","links":[],"slug":"louis-armstrong-stadium","state":"NY","score":0.73523,"postal_code":"11368","location":{"lat":40.7636,"lon":-73.83},"address":"1 Flushing Meadows Corona Park Road","timezone":"America\/New_York","id":2979},"images":["https:\/\/chairnerd.global.ssl.fastly.net\/images\/performers-landscape\/us-open-tennis-45e2d9\/5702\/huge.jpg","https:\/\/chairnerd.global.ssl.fastly.net\/images\/performers\/5702\/us-open-tennis-c1ccf7\/medium.jpg","https:\/\/chairnerd.global.ssl.fastly.net\/images\/performers\/5702\/us-open-tennis-01f513\/large.jpg","https:\/\/chairnerd.global.ssl.fastly.net\/images\/performers\/5702\/us-open-tennis-4e07f2\/small.jpg"]}
From this i believe i need to generate 3 POJO's, my higher level "EventObject" Class, A Location Class, and a Venue Class. These classes and their variables follow:
EventObject Class:
public class EventObject {
private Integer sortKey;
private Integer eventId;
private String title;
private String datetimeUtc;
private Venue venue;
private List<String> images = new ArrayList<String>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
Location Class:
public class Location {
private Float lat;
private Float lon;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
Venue Class:
public class Venue {
private String city;
private String name;
private String extendedAddress;
private String url;
private String country;
private String displayLocation;
private List<Object> links = new ArrayList<Object>();
private String slug;
private String state;
private Float score;
private String postalCode;
private Location location;
private String address;
private String timezone;
private Integer id;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
My interface for the Api Call is as follows:
public interface UserEvents {
#GET("/user/get_events")
void getEvents(#Header("Authorization")String token_id,
#Query("event_type")String event_type,
#Query("postal_code")int postalCode,
#Query("per_page") int perPage ,
#Query("lat") int lat,
#Query("lon") int lon,
#Query("month")int month,
#Query("page")int page,
Callback<List<EventObject>>callback) ;
}
Here is its implementation in my code :
UserEvents mUserEvents = mRestAdapter.create(UserEvents.class);
mUserEvents.getEvents(token_Id, "sports",11209,25,0, 0, 9, 2, new Callback <List<EventObject>>() {
#Override
public void success(List<EventObject> eventObjects, retrofit.client.Response response) {
Log.d(TAG,"Success");
}
There is alot going on here, but i believe that i am probably going wrong with how i am handling the JSON. When i copied and pasted in my JSON to the Pojo generator, i did not include "status:success, " data:{
I essentially just used the entire entry of an element in the Array ( everything from {sort_key onward until the next sort key ) and pushed that through the converter.
This is my first try at Retrofit and API work, and parsing anything this complicated.
I am hoping its something that someone else will be able to point out. I have googled as well i could to sort this out with no luck.
Thanks for looking.
The main problem is that you are not getting the root element of the response. You need to create an entity "response" that gets the items status and data. It would look something like this:
public class RootObject {
#Expose
private String status;
#Expose
private EventObject data;
//getters and setters here
}
Then when you make the callback you should point to your RootObject, mUserEvents.getEvents(token_Id, "sports",11209,25,0, 0, 9, 2, new Callback <RootObject>()
One more thing, Retrofit uses GSON to parse your json reponse. It means that when you create the entities, the variables need to match the name of the objects coming in the response. If it doesn't you need to tell GSON how to map the variables, like this:
#SerializedName("extended_address")
#Expose
private String extendedAddress;
In that case the value coming in the json is "extended_address" and will be mapped to the String extendedAddress. If you don't put that #SerializedName line the parsing will fail. If you want to skip that line then you can call your variable "extended_address" so it matches the response.
The #Expose is needed by GSON to parse the variable below it. If a variable doesn't have it then GSON will ignore that parsing. So you need to fix both the #Expose and #SerializedName on your entities so GSON works correctly.
Hope it helps.