Convert composite java object to CSV with Jackson - java

With Jackson, I need to convert an instance of my class Test in CSV but I'm getting problems with a class that contains one list (Inner)
Ex:
public class Test {
String testName;
#JsonUnwrapped
Simple simple;
#JsonUnwrapped
Inner inner;
public Test(String testName, Simple simple, Inner inner) {
this.testName = testName;
this.simple = simple;
this.inner = inner;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public Simple getSimple() {
return simple;
}
public void setSimple(Simple simple) {
this.simple = simple;
}
public Inner getInner() {
return inner;
}
public void setInner(Inner inner) {
this.inner = inner;
}
}
class Inner {
#JsonUnwrapped
List<Person> persons;
public Inner(List<Person> persons) {
this.persons = persons;
}
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
}
class Person {
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Simple {
String simpleName;
public Simple(String simpleName) {
this.simpleName = simpleName;
}
public String getSimpleName() {
return simpleName;
}
public void setSimpleName(String simpleName) {
this.simpleName = simpleName;
}
}
class Main {
public static void main(String[] args) {
Simple simple = new Simple("simple");
Person person = new Person("jesus");
Inner inner = new Inner(Arrays.asList(person));
Test test = new Test("test", simple, inner);
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(Test.class);
try {
String csv = mapper.writer(schema).writeValueAsString(test);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
For objects properties, I used the annotation #JsonUnwrapped as recommended on this link ,
but I get one exception when jackson try to convert the list Inner.persons:
How can I fix that ?

Related

Is there a way with Jackson ObjectMapper (without a custom #JsonCreator) to unmarshall this Json to the supplied Java Dto?

I have two Java classes:
public class Request
{
private List<Item> subItems;
public Request()
{
}
public List<Item> getSubItems()
{
return subItems;
}
public void setSubItems(List<Item> subItems)
{
this.subItems = subItems;
}
}
class Item
{
private String name;
private String functionName;
//...elided...
}
The subItems that will be passed can be complex (include a function) or simple (just a name). There can be a mix of these. To simplify the JSON, I'd like to be able to accept the following:
JSON:
{
"subItems": [
{
"name": "complexType",
"function": "someFunction"
},
"simpleType"
]
}
and then have this turned into the equivalent of the following instance:
Request request = new Request();
request.setSubItems(
Arrays.asList(
new Item( "complexType", "SomeFunction" ),
new Item( "simpleType" )
)
);
Is this possible with Jackson/ObjectMapper?
What settings and annotations would I need?
If your Item class has a string constructor, it will be called with the "simpleType" value.
class Item {
private String name;
private String functionName;
public Item() {
}
public Item(String name) {
this.name = name;
}
// getters and setters here
}
Full demo
public class Request {
public static void main(String[] args) throws IOException {
String json = "{\"subItems\":[" +
"{\"name\":\"complexType\",\"functionName\":\"SomeFunction\"}," +
"\"simpleType\"" +
"]}";
Request request = new ObjectMapper().readValue(json, Request.class);
System.out.println(request);
}
private List<Item> subItems;
public Request() {
}
public Request(Item... subItems) {
this.subItems = Arrays.asList(subItems);
}
public List<Item> getSubItems() {
return this.subItems;
}
public void setSubItems(List<Item> subItems) {
this.subItems = subItems;
}
#Override
public String toString() {
return "Request [subItems=" + this.subItems + "]";
}
}
class Item {
private String name;
private String functionName;
public Item() {
}
public Item(String name) {
this.name = name;
}
public Item(String name, String functionName) {
this.name = name;
this.functionName = functionName;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getFunctionName() {
return this.functionName;
}
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
#Override
public String toString() {
return "Item [name=" + this.name + ", functionName=" + this.functionName + "]";
}
}
Output
Request [subItems=[Item [name=complexType, functionName=SomeFunction], Item [name=simpleType, functionName=null]]]

Spark java.lang StackOverFlow Error When converting Custom class Object to DataSet

public class OuterClass implements Serializable {
int id;
ArrayList<InnerClass> listofInner;
public int getId() {
return id;
}
public void setId(int num) {
this.id = num;
}
public ArrayList<InnerClass> getListofInner() {
return listofInner;
}
public void setListofInner(ArrayList<InnerClass> list) {
this.listofInner = list;
}
public static class InnerClass implements Serializable {
String streetno;
private List<InnerClass> children = new ArrayList<InnerClass>();
public void setStreetno(String streetno) {
this.streetno = streetno;
}
public String getStreetno() {
return streetno;
}
public List<InnerClass> getChildren() {
return children;
}
public void setChildren(List<InnerClass> children) {
this.children = children;
}
}
}
OuterClass us = new OuterClass();
us.setId(111);
//Inner
OuterClass.InnerClass ic = new OuterClass.InnerClass();
ic.setStreetno("My Street");
ic.getChildren().add(new OuterClass.InnerClass());
ArrayList<OuterClass.InnerClass> ar = new ArrayList<OuterClass.InnerClass>();
ar.add(ic);
us.setListofInner(ar);
//DF
Encoder<OuterClass> outerClassEncoder = Encoders.bean(OuterClass.class);
Dataset<OuterClass> ds = spark.createDataset(Collections.singletonList(us), outerClassEncoder);
In the above InnerClass class has property
List children = new ArrayList(); this is a type ofInnerClass list. Because of this when I am trying to covert this Custom Object to Dataset. I am getting error
java.lang.StackOverflowError: null
at sun.reflect.generics.reflectiveObjects.TypeVariableImpl.equals(TypeVariableImpl.java:189).
If I remove the children property from InnerClass. It works fine.
So Any one please help me..:)

Jackson: Json having json array to java class having list of another Java class

I am using jackson 2.6.x
I am unable to convert the json to java class
public class ParentTest {
#JsonProperty("ParentTest")
public List<Test> getTestList() {
return testList;
}
public void setTestList(List<Test> testList) {
this.testList = testList;
}
#JsonProperty("ParentTest")
List<Test> testList;
public ParentTest(List<Test> testList)
{
this.testList = testList;
}
public ParentTest()
{
super();
testList = new ArrayList<Test>();
}
public String toString()
{
String r = "";
if(testList!=null)
for(Test t : testList)
{
r += "Test:"+t.field1+t.field2;
}
else
r = "null";
return r;
}}
And the class used for list is
#JsonRootName("Test")public class Test {
#JsonProperty("field1")
String field1;
#JsonProperty("field2")
String field2;
public Test(String field1,String field2)
{
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}}
And My Json is
{"ParentTest": [{
"Test":{
"field1":"t1",
"field2":"t2"
}
},
{
"Test":{
"field1":"t3",
"field2":"t4"
}
}]}
And to read it I have used
public final class HandlerJacksonUtils {
private static ObjectMapper m = new ObjectMapper();
private static JsonFactory jf = new JsonFactory();
public static <T> Object fromJson(String jsonAsString, Class<T> pojoClass) throws IOException {
m.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return m.readValue(jsonAsString, pojoClass);
}}
and then
ParentTest pt = (ParentTest) HandlerJacksonUtils.fromJson(json, ParentTest.class);
The ParentTest object pt prints nothing on System.out.print(pt.toString);
#JsonRootName does not work alone, as stated in javadocs.
You should use it in combination with SerializationFeature#WRAP_ROOT_VALUE and/or DeserializationFeature#UNWRAP_ROOT_VALUE.
But it works only for root object that you want to serialize/deserialize. So, it won't work in your case.
Instead, you can make a wrapper class for Test
public class TestWrapper {
#JsonProperty("Test")
private Test test;
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
}
And use it instead of Test in ParentTest

Set Data in Bean Class

I am stuck in an operation. I have 2 POJO Bean Classes
class A{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
..................................................................
class B {
private String company;
private Object object;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
}
..........................................................
class SampleTest {
public static void main(String[] args) {
A a = new A();
a.setName("Some Data");
B b = new B();
b.setCompany("Stack Overflow");
b.setObject(a);
//...... Next Lines.....
}
}
Is there any way to set data in B pojo class by reading any Property file?
Example Property file:
#Property File<br>
B.company = Stack Overflow<br>
B.object.name = Some Data
Please help.
Thank you
One way can be :
Properties prop = new Properties();
try
{
// load a properties file
prop.load(new FileReader("config.properties"));
// get the property value
B b = new B();
b.setCompany(prop.getProperty("B.company"));
}
catch (IOException ex)
{
ex.printStackTrace();
}

apache commons beanutils, how to set property value?

In the java, commons beanutils, try to set property 'address' and 'creditCardList' to object, but it gave me error :
java.lang.NoSuchMethodException: Property 'address' has no setter method in class 'class com.dao.Student'
but I have this method there. The code is here:
public class Main {
public static void main(String[] args) {
Object student = new Student("John");
Object address = new Address("NJ");
try {
PropertyUtils.setProperty(student, "address", address);
//----------
List list = new ArrayList();
Object creditCard = new CreditCard();
list.add(creditCard);
PropertyUtils.setProperty(student, "creditCardList", list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Student {
private String name;
private Address address;
private List<CreditCard> creditCardList;
public Student(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<CreditCard> getCreditCardList() {
return creditCardList;
}
public void setCreditCardList(List<CreditCard> creditCardList) {
this.creditCardList = creditCardList;
}
}
class Address {
private String name;
public Address(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class CreditCard{
private String cardName;
public String getCardName() {
return cardName;
}
public void setCardName(String cardName) {
this.cardName = cardName;
}
}
Your class Student should be a public class , try making it public and rerun your code.
I moved Student to a own file and made it public, that worked fine :)

Categories

Resources