Json Object conversion to java object using jackson - java

I have following json data
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
I want to set this data to my pojo object
public class TestObject {
private Long id;
private String name;
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
}
Here i am able to set id and name in my test object but for object map i am not able to set data.
So i have made on more class for ObjectMap which contains programmeTitle & workingTitle this works fine but i can't set this fields directly to my pojo object
is this possible to set?
I am using Jackson Object Mapper to convert json data.
It is working fine if i create another java object inside my pojo like:
public class TestObject {
private Long id;
private String name;
#JsonProperty("objectMap")
private ObjectMap objectMap;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ObjectMap getObjectMap() {
return objectMap;
}
public void setObjectMap(ObjectMap objectMap) {
this.objectMap = objectMap;
}
}
public class ObjectMap {
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
public String getProgrammeTitle() {
return programmeTitle;
}
public void setProgrammeTitle(String programmeTitle) {
this.programmeTitle = programmeTitle;
}
public String getWorkingTitle() {
return workingTitle;
}
public void setWorkingTitle(String workingTitle) {
this.workingTitle = workingTitle;
}
}

If your JSON is like this
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
then you may write your object mapper class like this..
public class Program{
public static class ObjectMap{
private String programme_title, working_title;
public String getprogramme_title() { return programme_title; }
public String getworking_title() { return working_title; }
public void setprogramme_title(String s) { programme_title= s; }
public void setworking_title(String s) { working_title= s; }
}
private ObjectMap objMap;
private String name;
public ObjectMap getobjectMap () { return objMap; }
public void setObjectMap (ObjectMap n) { objMap= n; }
private Long id;
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
please refer this check it

You can write your own deserializer for this class:
class EntityJsonDeserializer extends JsonDeserializer<Entity> {
#Override
public Entity deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Root root = jp.readValueAs(Root.class);
Entity entity = new Entity();
entity.setId(root.id);
entity.setName(root.name);
if (root.objectMap != null) {
entity.setProgrammeTitle(root.objectMap.programmeTitle);
entity.setWorkingTitle(root.objectMap.workingTitle);
}
return entity;
}
private static class Root {
public Long id;
public String name;
public Title objectMap;
}
private static class Title {
#JsonProperty("programme-title")
public String programmeTitle;
#JsonProperty("working-title")
public String workingTitle;
}
}
Your entity:
#JsonDeserialize(using = EntityJsonDeserializer.class)
class Entity {
private Long id;
private String name;
private String programmeTitle;
private String workingTitle;
//getters, setters, toString
}
And usage example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper.readValue(jsonString, Entity.class);
System.out.println(entity);
}
}
Above program prints:
Entity [id=10606, name=ProgrammerTitle, programmeTitle=TestProgramme, workingTitle=TestProgramme]

Related

How to implement a Custom DataType in Hibernate?

We would like to type various properties in Java.
e.g. the e-mail address
But now I get the message all the time:
Could not set field value [test#test.de] value by reflection : [class customer.email] setter of customer.email;
Can not set dataType.EmailAddress field customer.email to java.lang.String
How should I proceed?
#Entity
public class customer {
#Id
#GeneratedValue
private Long id;
private String name;
private EmailAddress email;
}
public class EmailAddress {
public String value;
public EmailAddress(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
public boolean setValue(String s) {
this.value = s;
return true;
}
public String mailbox() ...
public String host() ...
public String tld() ...
}
Getter and Setter from HibernateDefaultType not called.
EDIT:
At the end. I want to store a String in the database with the email-Address. In Java I want the EmailAddress Object.
it is much easier. An AttributeConverter make it very easy.
https://thorben-janssen.com/jpa-attribute-converter/
Thank you very much
EDIT:
Here is the Code:
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
#Converter(autoApply = true)
public class EmailAddressConverter implements AttributeConverter<EmailAddress, String> {
#Override
public String convertToDatabaseColumn(EmailAddress emailAddress) {
return emailAddress.value;
}
#Override
public EmailAddress convertToEntityAttribute(String s) {
return new EmailAddress(s);
}
}
And in the Entity:
#Convert(converter = EmailAddressConverter.class)
private EmailAddress email;
Here is some example of making your own custom type.
public class EmailAddressDescriptor extends AbstractTypeDescriptor<String> {
protected EmailAddressDescriptor() {
super(String.class, new ImmutableMutabilityPlan<>());
}
#Override
public String toString(String value) {
return null;
}
#Override
public String fromString(String string) {
return null;
}
#Override
public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
return null;
}
#Override
public <X> String wrap(X value, WrapperOptions options) {
return null;
}
#Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
return null;
}
}
Then you would make the Email address class with all your methods
public class EmailAddress extends AbstractSingleColumnStandardBasicType<String> {
private String value;
public EmailAddress() {
super(new VarcharTypeDescriptor(), new EmailAddressDescriptor());
}
#Override
public String getName() {
return "EmailAddress";
}
#Override
public Object resolve(Object value, SharedSessionContractImplementor session, Object owner, Boolean overridingEager) throws HibernateException {
return null;
}
}
public String mailbox() ...
public String host() ...
public String tld() ...
How you would use it with your entity will be something like this
#Entity
#TypeDef(name = "emailAddress", typeClass = EmailAddress.class)
public class customer {
#Id
#GeneratedValue
private Long id;
private String name;
#Type (type = "emailAddress")
private EmailAddress emailAddress;
}
Hope this helps

How to Serialize circular referenced object using JSON-B (Java API for JSON Binding)

I am using JSON-B for output object to json and there is a circular reference in the object (please do not ask me to remove the circular reference), sample code as follows
The Person class contains a list of Property
and the Property class reference back the person which form a circular reference.
In the first print the json can be output, however in the second print statement, stack overflow error due to touch the circular reference of the object, I do not want to use #JsonbTransient to ignore any of them, how can I solve this?
I am expecting the json output as
{"id":1,"name":"Jhon","propertyList":[{"person":1, "propertyName":"Palace"},{"person":1, "propertyName":"Apartment"}]}
Sample Code:
import java.util.ArrayList;
import java.util.List;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
public class JsonTest {
public static void main(String[] args) throws InterruptedException {
Person person = new Person(1, "Jhon");
Jsonb jsonb = JsonbBuilder.create();
//no error as no property is added
System.out.println("jsonPerson without property: " + jsonb.toJson(person));
Property p1 = new Property();
p1.setPropertyName("Palace");
p1.setPerson(person);
Property p2 = new Property();
p2.setPropertyName("Apartment");
p2.setPerson(person);
person.getPropertyList().add(p1);
person.getPropertyList().add(p2);
/**
* stackoverflow here
*/
System.out.println("jsonPerson with property: " + jsonb.toJson(person));
}
public static class Property {
private Person person;
private String propertyName;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
}
public static class Person {
private int id;
public Person() {
super();
}
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
private String name;
private List<Property> propertyList = new ArrayList<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
}
Finally I give up using JSON-B and instead use Jackson, use the annotation #JsonIdentityInfo here is my solution for information:
import java.util.ArrayList;
import java.util.List;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonTest {
private static Person person = null;
private static List<Property> propertyList = new ArrayList<>();
public static void main(String[] args) throws Exception {
person = new Person(1, "Jhon");
propertyList.add(new Property(1, person, "Palace"));
propertyList.add(new Property(2, person, "Apartment"));
person.setPropertyList(propertyList);
jacksonTest();
//jsonbTest();
}
private static void jacksonTest()
throws Exception
{
String result = new ObjectMapper().writeValueAsString(person);
System.out.println("result: " + result);
}
private static void jsonbTest()
throws Exception
{
Jsonb jsonb = JsonbBuilder.create();
/**
* stackoverflow here
*/
System.out.println("jsonPerson with property: " + jsonb.toJson(person));
}
public static class Property extends BaseEntity {
private Person person;
private String propertyName;
public Property(int id, Person person, String propertyName) {
super();
setId(id);
this.person = person;
this.propertyName = propertyName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
}
public static class Person extends BaseEntity {
public Person() {
super();
}
public Person(int id, String name) {
super();
setId(id);
this.name = name;
}
private String name;
private List<Property> propertyList = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static abstract class BaseEntity {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
}
Jackson output:
result: {"id":1,"name":"Jhon","propertyList":[{"id":1,"person":1,"propertyName":"Palace"},{"id":2,"person":1,"propertyName":"Apartment"}]}

Hazelcast Deserialization: Parent class attributes values are null after deserializatioin

I have two class Parent Class and Child classes as below:
#MappedSuperclass
public class ParentEntity implements DataSerializable {
private String createdBy;
private Date createdAt;
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Long getCreatedAt() {
return createdAt.getTime();
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(createdBy);
out.writeLong(this.getCreatedAt());
}
#Override
public void readData(ObjectDataInput in) throws IOException {
createdBy = in.readUTF();
createdAt = new Date(in.readLong());
}
}
Child class is as below:-
public class Child_Entity extends ParentEntity implements DataSerializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(id);
out.writeUTF(name);
}
#Override
public void readData(ObjectDataInput in) throws IOException {
id = in.readUTF();
name = in.readUTF();
}
}
I fetch these value from database and put into hazelcast cache iMap.
While getting values from cache I am getting id and name value correct, but createdAt and createdBy (Parent Class attributes ) values are null.
How can it is possible to serialize parent class also with child class.
You need to call super-class serialization methods in the child class methods. For instance;
public class Child_Entity extends ParentEntity implements DataSerializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id; }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
super.writeData(out);
out.writeUTF(id);
out.writeUTF(name);
}
#Override
public void readData(ObjectDataInput in) throws IOException {
super.readData(in);
id = in.readUTF();
name = in.readUTF();
}}

Converting json format using java bean

I have a json string something similar
{"results":
[{"_type":"Position","_id":377078,"name":"Potsdam, Germany","type":"location","geo_position":{"latitude":52.39886,"longitude":13.06566}},
{"_type":"Position","_id":410978,"name":"Potsdam, USA","type":"location","geo_position":{"latitude":44.66978,"longitude":-74.98131}}]}
I am trying to convert to
{"results":
[{"_type":"Position","_id":377078,"name":"Potsdam, Germany","type":"location","latitude":52.39886,"longitude":13.06566},
{"_type":"Position","_id":410978,"name":"Potsdam, USA","type":"location","latitude":44.66978,"longitude":-74.98131}]}
I am converting to java and again converting back using But I am gettin null in data
SourceJSON data=new Gson().fromJson(jsonArray, SourceJSON.class);
DestinationJSON destdata = new DestinationJSON();
destdata.setLatitide(data.getGeoLocation().getLatitide());
destdata.setLongitude(data.getGeoLocation().getLongitude());
destdata.setId(data.getId());
destdata.setType(data.getType());
destdata.setName(data.getName());
destdata.set_type(data.get_type());
Gson gson = new Gson();
String json = gson.toJson(destdata);
below are my beans
public class SourceJSON implements Serializable {
private List<GEOLocation> geoLocations;
private String _type;
private String id;
private String name;
private String type;
public String get_type() {
return _type;
}
public List<GEOLocation> getGeoLocations() {
return geoLocations;
}
public void setGeoLocations(List<GEOLocation> geoLocations) {
this.geoLocations = geoLocations;
}
public void set_type(String _type) {
this._type = _type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
and
public class GEOLocation implements Serializable{
private String latitide;
private String longitude;
public String getLatitide() {
return latitide;
}
public void setLatitide(String latitide) {
this.latitide = latitide;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
}
and destination java
public class DestinationJSON implements Serializable {
private String _type;
private String id;
private String name;
private String type;
private String latitide;
private String longitude;
public String get_type() {
return _type;
}
public void set_type(String _type) {
this._type = _type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLatitide() {
return latitide;
}
public void setLatitide(String latitide) {
this.latitide = latitide;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
}
All you need is this. You can try this class in your IDE with a simple copy&paste.
package stackoverflow.questions;
import java.util.*;
import com.google.gson.Gson;
public class Q20433539{
public static void main(String[] args){
String json = "{\"results\":"+
"[{\"_type\":\"Position\",\"_id\":377078,\"name\":\"Potsdam, Germany\",\"type\":\"location\",\"geo_position\":{\"latitude\":52.39886,\"longitude\":13.06566}},"+
"{\"_type\":\"Position\",\"_id\":410978,\"name\":\"Potsdam, USA\",\"type\":\"location\",\"geo_position\":{\"latitude\":44.66978,\"longitude\":-74.98131}}]}";
Gson gson = new Gson();
Map m = gson.fromJson(json, Map.class);
List<Map> innerList = (List<Map>) m.get("results");
for(Map result: innerList){
Map<String, Double> geo_position = (Map<String, Double>) result.get("geo_position");
result.put("latitude", geo_position.get("latitude"));
result.put("longitude", geo_position.get("longitude"));
result.remove("geo_position");
}
System.out.println(gson.toJson(m));
}
}
Of course, it works under the assumption that you always want to flat geo information.
Explanation: It's convenient to use POJO when working with Gson, but it's not the only way. Gson can also deseralize to Arrays/Maps if you do not specify the expected result. So I did, and then I manipulated the structure to unfold your data. After that, Gson can serialize Arrays/Maps structure again to your desidered JSON.

JAXB #XmlIDREF in XmlAdapter for immutable objects

I'm using XmlAdapter for immutable objects as proposed in this blog post: http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html. This works fine, but not with references to other immutable objects in my adapters. Is there any way to handle this with JAXB?
Below there is an example which does not work if the person's xml tag comes after the company's xml tag which references the person.
Immutable objects:
#XmlJavaTypeAdapter(PersonAdapter.class)
public class Person {
private final String id;
private final String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
#XmlJavaTypeAdapter(CompanyAdapter.class)
public class Company {
private final String name;
private final Person principal;
public Company(String name, Person principal) {
this.name = name;
this.principal = principal;
}
public String getName() {
return name;
}
public Person getPrincipal() {
return principal;
}
}
PersonAdapter:
public class PersonAdapter extends XmlAdapter<AdaptedPerson, Person> {
public static class AdaptedPerson {
#XmlID
#XmlAttribute
String id;
#XmlAttribute
String name;
}
#Override
public AdaptedPerson marshal(Person v) throws Exception {
AdaptedPerson a = new AdaptedPerson();
a.id = v.getId();
a.name = v.getName();
return a;
}
#Override
public Person unmarshal(AdaptedPerson v) throws Exception {
return new Person(v.id, v.name);
}
}
CompanyAdapter:
public class CompanyAdapter extends XmlAdapter<AdaptedCompany, Company> {
public static class AdaptedCompany {
#XmlAttribute
String name;
#XmlIDREF
#XmlAttribute
Person principal;
}
#Override
public AdaptedCompany marshal(Company v) throws Exception {
AdaptedCompany a = new AdaptedCompany();
a.name = v.getName();
a.principal = v.getPrincipal();
return a;
}
#Override
public Company unmarshal(AdaptedCompany v) throws Exception {
return new Company(v.name, v.principal);
}
}

Categories