Change name of property while deserializing response in Java - java

JSON Response from API :
{
"result":[
{
"ResultType":"SUCCESS"
}
]
}
After Converting to ResultClass.class :
{
"result":[
{
"resultType":null
}
]
}
Expected Output After Converting to ResultClass.class :
{
"result":[
{
"resultType":"SUCCESS"
}
]
}
I am integrating with third party API.I want to change property name while deserializing .I have tried #JsonProperty on filed getter and setter.But the value is not reflected in field resultType.
ResultClass.java
#JsonProperty("result")
List<TestClass> result = new ArrayList<>();
public List<TestClass> getResult() {
return result;
}
public void setResult(List<TestClass> result) {
this.result = result;
}
TestClass.java
#JsonProperty("ResultType")
private String resultType;
public String getResultType() {
return resultType;
}
public void setResultType(String resultType) {
this.resultType = resultType;
}
Note : I have tried JsonObject and it is working fine.I am using HttpClient and HttpResponse for making request.Jackson Version : 2.5.0

2 Solutions are available:
1. Make case-insensitive deserializing
Add this feature on your object mapper:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
2. Serialize and deserialize with different property names
To change the name of the property ResultType to resultType, you should rather use both #JsonGetter and #JsonSetter:
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonSetter;
public class TestClass {
private String resultType;
#JsonGetter("resultType")
public String getResultType() {
return resultType;
}
#JsonSetter("ResultType")
public void setResultType(String resultType) {
this.resultType = resultType;
}
}

Related

Gson fromJson returning null data

I'm having a null return using Gson.fromJson() and I don't understand why.
I'm calling an API that returns some data with this format:
{
"RealisedItems":{
"realisedItem":[
{
"actionItem1":1,
"actionItem2":"ITEM_ANSWER",
"actionItem3":"CREATE_ITEM",
"actionItem4":[
"XXXXXXX"
]
},
{
"actionItem1":2,
"actionItem2":"ITEM_ANSWER",
"actionItem3":"LINK_ITEM",
"actionItem5":"202007050000",
"actionItem4":[
"XXXXXXX"
]
}
]
}
}
Here's my objects to receive the data :
public class RealisedItems {
private List<RealisedItem> realisedItem = null;
public List<RealisedItem> getRealisedItem() {
return realisedItem;
}
public void setRealisedItem(List<RealisedItem> realisedItem) {
this.realisedItem = realisedItem;
}
}
And
public class RealisedItem {
private Long actionItem1;
private String actionItem2;
private String actionItem3;
private List<String> actionItem4 = null;
private String actionItem5;
public Long getActionItem1() {
return actionItem1;
}
public void setActionItem1(Long actionItem1) {
this.actionItem1 = actionItem1;
}
public String getActionItem2() {
return actionItem2;
}
public void setActionItem2(String actionItem2) {
this.actionItem2 = actionItem2;
}
public String getActionItem3() {
return actionItem3;
}
public void setActionItem3(String actionItem3) {
this.actionItem3 = actionItem3;
}
public List<String> getActionItem4() {
return actionItem4;
}
public void setActionItem4(List<String> actionItem4) {
this.actionItem4 = actionItem4;
}
public String getActionItem5() {
return actionItem5;
}
public void setActionItem5(String actionItem5) {
this.actionItem5 = actionItem5;
}
}
Using the debug mode, I can see by that the response object from this line : gson.fromJson(response, RealisedItems.class); contains the Json in String format that you can see above but my list is null after this. I'm using the same code for another response from a different service and I have my object filled with data.
From what I can see, in the fist "realisedItem" object, I have 4 items while in the second, I have 5. Can this cause this issue?
I tried to change the list to an array (RealisedItem[]) but it's not working either.
I also tried to use the #Expose with #SerializedName and changing Gson gson = new Gson(); to Gson gson = new GsonBuilder().create(); and Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); with the fifth item not having the #Expose annotation, but I'm still having my list null.
Can you please enlight me? Thanks!
Thanks to #Andreas, I realized I've made a mistake and used RealisedItems as root object. I just created a new object called ItemsOutput which contains RealisedItems field. I added a #SerializedName annotation to indicate it's called "RealisedItems" with an uppercase and changed my Gson.fromJson() call with the newly created object. It's working.
Thanks!

Jackson objectMapper mapping different json properties to same pojo

I have a very simple json which I am trying to map to an object.
JSON :
[
{
"cust_lpid": "0119b9f7f99ad2161de7b0b",
"cust_uid": "soumavtestflow"
}
]
My Mapper Class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class CustomerSegmentRequest {
#JsonProperty("LPID")
String cust_lpid;
#JsonProperty("UserId")
String cust_uid;
public String getCust_lpid() {
return cust_lpid;
}
public void setCust_lpid(String cust_lpid) {
this.cust_lpid = cust_lpid;
}
public String getCust_uid() {
return cust_uid;
}
public void setCust_uid(String cust_uid) {
this.cust_uid = cust_uid;
}
}
When I do a
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
LPIDCustIDMapper[] custSegResp = objectMapper.readValue(responseBody,CustomerSegmentRequest [].class);
I don't get any values populated in custSegResp.
However when i remove the #JsonProperty it works.
I need the json property name to map an incoming request and hence don't wanna create a separate mapping class.
Is there a way to achieve the same?
use #JsonAlias
#JsonIgnoreProperties(ignoreUnknown = true)
public class CustomerSegmentRequest {
#JsonAlias({"cust_lpid", "LPID" })
String cust_lpid;
#JsonAlias({"cust_uid", "UserId" })
String cust_uid;
public String getCust_lpid() {
return cust_lpid;
}
public void setCust_lpid(String cust_lpid) {
this.cust_lpid = cust_lpid;
}
public String getCust_uid() {
return cust_uid;
}
public void setCust_uid(String cust_uid) {
this.cust_uid = cust_uid;
}
}
#JsonProperty("keyName") is to specify what is the key is the JSON which maps to this field.
The reason it works without it is, without it Jackson tries to first match via getters/setters after removing the get/set prefix keys and normalizing the case (getAbCd -> abCd), which in your case gives the keys as in the JSON.
You need to modify your #JsonProperty("LPID") to #JsonProperty("cust_lpid") or if you need to map to multiple keys use #JsonAlias({"cust_lpid", "LPID" })

Deserialize a JSON containing a list of objects using Gson

I'm trying to deserialize a JSON which containes a String and a list of objects in my Spring web application.
JSON
[
{
"jsonrpc":"2.0",
"result":[
{
"event":{
"id":"27809810",
"name":"Spezia v Trapani",
"countryCode":"IT",
"timezone":"Europe/London",
"openDate":"2016-05-28T16:30:00.000Z"
},
"marketCount":13
},
{
"event":{
"id":"27811083",
"name":"Torino U19 v Atalanta U19",
"countryCode":"IT",
"timezone":"Europe/London",
"openDate":"2016-05-29T16:15:00.000Z"
},
"marketCount":18
},
...
]
My classes are:
ListEventsResponse class
public class ListEventsResponse {
private String jsonrpc;
private List<ListEventsResult> result;
public ListEventsResponse() { }
public String getJsonrpc() {
return jsonrpc;
}
public void setJsonrpc(String jsonrpc) {
this.jsonrpc = jsonrpc;
}
public List<ListEventsResult> getResult() {
return result;
}
public void setResult(List<ListEventsResult> result) {
this.result = result;
}
}
ListEventsResult class
public class ListEventsResult {
private Event event;
private int marketCount;
public ListEventsResult() { }
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public int getMarketCount() {
return marketCount;
}
public void setMarketCount(int marketCount) {
this.marketCount = marketCount;
}
}
I have also Event class, composed by 5 String (id, name, etc.).
Controller
[...]
ListEventsResponse listEvents = new Gson().fromJson(response.toString(), ListEventsResponse.class);
List<ListEventsResult> eventsList = listEvents.getResult();
return new ModelAndView("page", "eventsList", eventsList);
My .jsp page
[...]
<c:forEach items="${eventsList}" var="listEventsResult">
Match: <c:out value="${listEventsResult.name}"/>
</c:forEach>
[...]
My code runs and doesn't give any error, but no match is shown on my page, in fact listEvents doesn't contains any object.
I can't understand how to deserialize properly the list of objects, so my question is: which logic is behind the deserialization of a json which contains a list of objects?
I post my code just to explain better my problem.
As you have a Json Array as response , you need to deserialize like below
Gson gson = new Gson();
Type type = new TypeToken<List<ListEventsResponse>>(){}.getType();
List<ListEventsResponse> events = (List<ListEventsResponse>) gson.fromJson(response.toString(), type);

How do I deserialize this JSON type

I have a JSON that looks like this:
{
"results": {
"exchange": [
"site.com",
{
"currency": "usd",
"last_traded": "2015.24"
}
]
}
}
How do I get the last_traded value?
I wrote some POJO for this, but I can't seem to find a way to get the key-value inside exchange array.
public class ExchangeContainer {
#Expose
private Results results;
public Results getResults() {
return results;
}
public void setResults(Results results) {
this.results = results;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
public class Results {
#Expose
private List<String> exchange = new ArrayList<String>();
public List<String> getExchange() {
return exchange;
}
public void setExchange(List<String> exchange) {
this.exchange = exchange;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
I'm using GSON to deserialize this JSON.
So in order for me to traverse through the model is:
ExchangeContainer response;
String rate = response.getResults().getExchange().get(1); // how to continue?
and I'm stuck.
Implement interface using implements JsonDeserializer in your class
and override deserialize method.
Example link - http://www.javacreed.com/gson-deserialiser-example/
As you have created list of Strings by
private List<String> exchange = new ArrayList<String>();
& setting another list in created list i.e., in exchange
public void setExchange(List<String> exchange)
When you get value by invoking line
String rate = response.getResults().getExchange().get(1);
it contains "last_traded": "2015.24" is it right ?
Now to get 2015.24, you have following choices :-
String[] split(":")
String substring(int beginIndex)
I hope this will solve your problem.

Deserializing JSON objects as List<type> not working in HTTPHandler

I am facing problem while deserializing to below entity using Javascript Serializer. Please help
JSON String:
{"AccountNo":0,"EmailAddress":"test#gmail.com","Destination_Prefernce":[{"Value":"Test Data"}]}
Java Code
public class EMailPreferenceEntity
{
private int _accountNo;
private string emailAddress;
private DestinationPreferences _destinationPrefernce = new DestinationPreferences();
public int AccountNo
{
get { return _accountNo; }
set { _accountNo = value; }
}
public string EmailAddress
{
get { return emailAddress; }
set { emailAddress = value; }
}
public DestinationPreferences Destination_Prefernce
{
get { return _destinationPrefernce; }
set { _destinationPrefernce = value; }
}
}
Handler File:
public class AjaxHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest (HttpContext context) {
string jsData = context.Request["Data"];
if (!string.IsNullOrEmpty(jsData))
{
JavaScriptSerializer ser = new JavaScriptSerializer();
EMailPreferenceEntity jsEntity = ser.Deserialize<EMailPreferenceEntity>(jsData);
}
}
Type erasure means your List will just become List after compilation so, when your http request arrives, it will try to deserialize List, and probably won't hit whatever you registered for List.
I'm not sure how your serializer handles it, but in Gson's case, you create a TypeToken out of the generic, so that the connection between type and serializer doesn't get lost after compilation.

Categories

Resources