Jackson deserializing json choosen fields - java

there is possibility to deserialize Json only choosen fields?
Eg:
{
"Version": 1,
"Key": "353301_PC",
"Type": "PostalCode",
"Rank": 500,
"LocalizedName": "Kleosin",
"EnglishName": "Kleosin",
"PrimaryPostalCode": "16-001",
"Region": {
"ID": "EUR",
"LocalizedName": "Europe",
"EnglishName": "Europe"
}
And i want only LocalizedName and EnglishName. Tried with objectMapper but getting errors.

Add JsonIgnoreProperties annotation to your data class
#JsonIgnoreProperties(ignoreUnknown = true)
public class YourClass {
private String LocalizedName;
private String EnglishName;
...
}

you can add #JsonIgnore to the fields inside the Region class

Related

Deserialize optional polymorphic fields with jackson

Problem
For example, I have a list of some products in my cart like cinema ticket, carsharing and new book.
[
{
"name": "Cinema Ticket"
},
{
"name": "Car Sharing",
"properties": { ... }
},
{
"name": "New Book",
}
]
As you can see, not all products have properties.
Note: this field is polymorphic.
Question
Can I turn "non-existing" field properties into null using Jackson or it's better to change api?
And if I can then how to do that?
Jackson Version: 2.10.1
Thanks for answers!
I suppose you have something like:
public class BaseProduct {
public String name;
}
public class CarSharing extends BaseProduct {
public String properties;
}
public class Book extends BaseProduct {
}
Instead of having the properties field set to null when is not there, you can use Jackson polymorphic functionality to not show it. Something like:
#JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
public class BaseProduct {
public String name;
}
The output would be:
[
{
"type": ".Book",
"name": "Book name"
},
{
"type": ".CarSharing",
"name": "Car share name",
"properties": "a property field"
}
]

Jackson Json to POJO mapping

i am i little lost in creating a mapping with jackson. My Json has the following structure
{
"d": {
"__metadata": {
"uri": "https://apisalesdemo8.successfactors.com:443/odata/v2/JobApplication(1463L)",
"type": "SFOData.JobApplication"
},
"lastName": "K",
"address": "123 Main Street",
"cellPhone": "12345",
"firstName": "Katrin",
"city": "Anytown",
"country": "United States",
"custappattachment": {
"results": [
{
"__metadata": {
"uri": "https://apisalesdemo8.successfactors.com:443/odata/v2/Attachment(1188L)",
"type": "SFOData.Attachment"
},
"fileExtension": "jpeg",
"fileName": "hp-hero-img.jpeg",
"fileContent": "/9j/4AA"
},
{
"__metadata": {
"uri": "https://apisalesdemo8.successfactors.com:443/odata/v2/Attachment(1189L)",
"type": "SFOData.Attachment"
},
"fileExtension": "jpeg",
"fileName": "hp-content-bkgd-img.jpeg",
"fileContent": "/9j/4AAQSk"
}]}}}
I do find a lot of tutorials handling arrays, but i fail already with the very first token "d".
and all the "__metadata" token are not needed at all.
I created a pojo containing attributes like lastName etc. and a collection attachments.
But my code always fails at token "d" or "__metadata"
public class ResponseDataObject {
private String lastName;
private String address;
private String cellPhone;
private String firstName;
private String city;
private String country;
private List<Attachment> attachments = new ArrayList<>();
.....getters and setters
and the jackson reader
ObjectReader objectReader =
mapper.readerFor(ResponseDataObject.class);
ResponseDataObject dataObject = objectReader.readValue(file);
Any hints would be appreciated.
Regards
Mathias
You can use #JsonIgnoreProperties annotation to ignore the properties that don't match any of the members defined in class, e.g.:
#JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseDataObject {
This will make sure all the matching properties are mapped and other properties are ignored.
You need to ignore properties, not present in POJO. Set following property in DeserializationFeature for ObjectMapper:
// for version 1.x
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// for newer versions
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
Deserialization code:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
ResponseDataObject dataObject = mapper.readValue(file, ResponseDataObject.class);
and add this annotation to ResponseDataObject class:
#JsonRootName(value = "d")
class ResponseDataObject {

How to ignore field depending on method?

How to ignore filed field depending on method?
I have a question about Spring Jackson annotations.
I have a model class. Code:
public class Tenant{
#JsonIgnore
private String id;
#JsonProperty("id")
#JsonDeserialize(using = StringValueDeserializer.class)
private String idSIMC;
#JsonProperty("name")
private String displayName;
#JsonProperty("description")
private String description;
#JsonProperty("default")
private boolean def;
#JsonProperty("geoLoc")
#JsonDeserialize(using = GeoLocationIdNameDeserializer.class)
private GeoLocation geoLoc;
#JsonProperty("asnId")
private String asnId;
#JsonProperty("devices")
#JsonDeserialize(using = StringArrayIdDeserializer.class)
private List<String> tempDevice = Collections.synchronizedList(new ArrayList<>());
#JsonIgnore
#JsonProperty("devices") // <-- I need to add this
private List<Device> devices = Collections.synchronizedList(new ArrayList());
//getters and setters...
}
Now my question. I have method#1 that instance above class and write in tempDevice IDs of devices. method#2 get all devices from servers and filter them by tempDevice (I need to do it) can I annotate ( or something else ) my fields to be ignored as Json Objects depending on method is called?
method#1
public List<Tenant> getTenantsFromServer() {
SSLVerification.disableSslVerification();
ArrayList<Tenant> tenants = new ArrayList<>(0);
String[] ids = getTenantIds();
for(int i=0; i<ids.length; i++){
ResponseEntity<ReturnUnique<Tenant>> result = getRestTemplate().exchange(getUrl() + SIEMCommands.ZONE_GET_ZONE + "?id=" + ids[i],
HttpMethod.GET, new HttpEntity(getHeader()), new ParameterizedTypeReference<ReturnUnique<Tenant>>(){});
Tenant newTenant = result.getBody().getValue();
newTenant.setParentNode(this);
newTenant.generateId();
tenants.add(newTenant);
}
return tenants;
}
In this method i have a key "devices" in that is stored id. In method#2 another json that also have "devices" key but with another dates.(name,ip, etc.) And when I execute this method I should to store all in devices list.
JSON used in first method#1
{"return": {
"asnId": 0,
"default": false,
"description": "",
"devices": [
{"id": 144121785900597248},
{"id": 144121785917374464},
{"id": 144121785934151680}
],
"geoLoc": {
"id": {"value": 0},
"name": ""
},
"id": {"value": 1},
"name": "HA_Zone"
}}
devices values are written in tempDevice;
method#2 use this JSON
"devices": [{
"CRuleRight": true,
"FTestRight": true,
"adRight": true,
"addDeleteRight": false,
"children": [],
"clientCount": 0,
"clientStatus": "0",
"clientVipsInSync": false,
"deviceActionRight": true,
"deviceDisabled": false,
"elmFile": false,
"elmHasSAN": false,
"eventRight": true,
"hostname": "",
"ipAddress": "172.28.60.17",
"ipsID": "144121785950928896",
"ipsRight": true,
"name": "ASA Admin CTX Site 2",
"parent": false,
"polRight": true,
"protocol": "gsyslog",
"reportRight": true,
"status": "6",
"statusAck": "0",
"tpcCollector": "syslog",
"tpcType": "278",
"type": "VIPS",
"viewRight": true,
"vipsEnabled": true,
"vipsID": "49",
"vipsInSync": false
},
{
"CRuleRight": true,
"FTestRight": true,
"adRight": true,
"addDeleteRight": false,
"children": [],
"clientCount": 0,
"clientStatus": "0",
"clientVipsInSync": false,
"deviceActionRight": true,
"deviceDisabled": false,
"elmFile": false,
"elmHasSAN": false,
"eventRight": true,
"hostname": "",
"ipAddress": "172.28.13.10",
"ipsID": "144121785179176960",
"ipsRight": true,
"name": "ASA-VPN-DC1",
"parent": false,
"polRight": true,
"protocol": "gsyslog",
"reportRight": true,
"status": "0",
"statusAck": "0",
"tpcCollector": "syslog",
"tpcType": "278",
"type": "VIPS",
"viewRight": true,
"vipsEnabled": true,
"vipsID": "3",
"vipsInSync": false
}
}]
this dates i have to write in devices
If I understand correctly, you are looking for a way to deserialize 2 different json datatype having same property name into a object in different situation. If that is the case, the suggestion of using JacksonMixInAnnotations from #Thomas should work. JacksonMixInAnnotations can provide a kind of way to add annotation from another class (called mix-in class) to the target class during run time.
In your case, you can left tempDevice and devices without Jackson annotation like follows:
public class Tenant {
private List<String> tempDevice;
private List<Device> devices;
}
and declare 2 mix-in classes:
abstract class TempDeviceMixIn {
#JsonProperty("devices")
private List<String> tempDevice;
}
abstract class DeviceMixIn {
#JsonProperty("devices")
private List<Device> devices;
}
When you need to deserialize a json string with a string property of devices, you can add mix-in class annotation likes:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Tenant.class, TempDeviceMixIn.class);
Tenant tenant = mapper.readValue(json, Tenant.class);
Deserialize a json string with a object property of devices is similar.
As you are using RestTemplate, you will need a MappingJacksonHttpMessageConverter with your ObjectMapper.

How to add root node in JSON

I need to include the top node in my JSON response. My JSON response in REST web service:
[
{
"address": "delhi",
"fristname": "xxxx",
"id": 1,
"lastname": "xxxx",
"phone": "0000000"
},
{
"address": "ssss",
"fristname": "yyyy",
"id": 2,
"lastname": "yyyyy",
"phone": "0000000"
},
{
"address": "wwww",
"fristname": "aaaa",
"id": 3,
"lastname": "aaaaa",
"phone": "0000000"
}
]
I want JSON response like this:
"employee": [
{
"address": "delhi",
"fristname": "xxxx",
"id": 1,
"lastname": "xxxx",
"phone": "0000000"
},
{
"address": "ssss",
"fristname": "yyyy",
"id": 2,
"lastname": "yyyyy",
"phone": "0000000"
},
{
"address": "wwww",
"fristname": "aaaa",
"id": 3,
"lastname": "aaaaa",
"phone": "0000000"
}
]
Please tell me how to add root node JSON. Thanks in advance.
You can do it like this in Java. Create a new JSON object and put your array in it.
JSONObject myobj = new JSONObject();
myobj.put("employees", <your_json_array>);
You could use Jackson annotation JsonRootName:
Annotation similar to XmlRootElement, used to indicate name to use for
root-level wrapping, if wrapping is enabled. Annotation itself does
not indicate that wrapping should be used; but if it is, name used for
serialization should be name specified here, and deserializer will
expect the name as well.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
And annotate your class as follows:
#JsonRootName(value = "employee")
public static class Employee {
private String address;
private String firstName;
// more... with getters and setters
}
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Employee
{
public string address { get; set; }
public int phone { get; set; }
}
public partial class Samplepage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<Employee> eList = new List<Employee>();
Employee employee = new Employee();
employee.address = "Minal";
employee.phone = 24;
eList.Add(employee);
employee = new Employee();
employee.address = "Santosh";
employee.phone = 24;
eList.Add(employee);
string ans = JsonConvert.SerializeObject(eList, Formatting.Indented);
JArray a = JArray.Parse(ans);
JObject UpdateAccProfile = new JObject(
new JProperty("employee", a)
);
}
}

katharsis collection of non primitives serialization

Trying to serialize a collection of non-primitive types using katharsis, but getting an empty collection all the time.
Response example:
{
"data": {
"type": "products",
"id": "1",
"attributes": {
"simpleAttributes": [
{}
],
"variationGroup": "variationGroup"
},
"relationships": {},
"links": {
"self": "http://localhost:8080/api/products/1"
}
},
"included": []
}
Expected response:
{
"data": {
"type": "products",
"id": "1",
"attributes": {
"simpleAttributes": [
{
tittle: "some title",
value: "some value"
}
],
"variationGroup": "variationGroup"
},
"relationships": {},
"links": {
"self": "http://localhost:8080/api/products/1"
}
},
"included": []
}
Domain objects (getters, setters, constructor and other stuff omitted by using lombok #Data annotation):
#JsonApiResource(type = "products")
#Data
public class Product {
#JsonApiId
private Integer id;
private List<SimpleAttribute> simpleAttributes = new ArrayList<>();
private String variationGroup;
}
#Data
public class SimpleAttribute implements Serializable{
private String title;
private String value;
}
I do not want to use relationships in this case or to include attributes to "included" field. Is it possible in katharsis?
Not sure what actually was wrong, but the problem disappeared after I changed katharsis-spring version from 2.3.0 to 2.3.1.

Categories

Resources