Deserialize yaml to list of objects - java

Say I have a Yaml file like this,
people:
- name : Joe
surname : Barber
age : 16
- name : Andy
surname : Lots
age : 17
And I have a class like this,
public class people {
private String name;
private String surname;
private String age;
<!-- With getters and setters -->
}
How would i go about getting a list of people objects from the Yaml file?
Just getting the value from a key in the file is fairly simple but mapping it to a collection of objects is not.
I am using the snakeYaml lib.

i hope this can help you.
public class StackOverflow {
public static void main(String[] args) {
final URL resource = StackOverflow.class.getResource("people.yaml");
final Constructor peopleContructor = new Constructor(Group.class);
final TypeDescription peopleDescription = new TypeDescription(People.class);
peopleDescription.putMapPropertyType("people", People.class, Object.class);
peopleContructor.addTypeDescription(peopleDescription);
final Yaml yaml = new Yaml(peopleContructor);
try {
final Group group = (Group) yaml.load(resource.openStream());
for (final People people : group.getPeople()) {
System.out.println(people);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static class People {
private String name;
private String surname;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "People: {name: " + this.name + ", surname: " + this.surname + ", age: " + this.age + "}";
}
}
public static class Group {
private List<People> people;
public List<People> getPeople() {
return people;
}
public void setPeople(List<People> people) {
this.people = people;
}
}}

Related

How to change output from object class name + hashcode to string output based on custom class I used

I am new to Java and Im practicing creating classes, objects and getting variables from classes.
I created a class Factory which includes 2 string variables and one array of object from different class called Item which includes 2 string variables. In my main program I want to sout variables from Factory class. I managed to print name and address but getItem() obviously won't print getName() string from Item class. I tried overriding with toString in Factory class but it doesn't work with this type of custom class I guess. What can I do in this situation?
Class Factory:
public class Factory {
public static final int MAX_ODABRANIARTIKLI = 3;
String name;
String address;
Item[] items = new Item[MAX_ODABRANIARTIKLI];
public Factory(String name, String address, Item[] items) {
this.name = name;
this.address = address;
this.items = items;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public Item[] getItems() {
return items;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setItems(Item[] items) {
this.items = items;
}
}
class Item:
public class Item {
String name;
String category;
}
public Item(String name, String category) {
this.name = name;
this.category = category;
}
public String getName() {
return name;
}
public String getCategory() {
return category;
}
public void setName(String name) {
this.name = name;
}
public void setCategory(String category) {
this.category = category;
}
}
main code:
import hr.java.production.model.Factory;
public class Main {
public static final int MAX_TVORNICA = 2;
public static void main(String[] args) {
Factory[] tvornice = new Factory[MAX_TVORNICA];
System.out.println("Unijeli ste sljedeće tvornice:");
for(Factory factory : tvornice){
ispisTvornica(factory);
}
}
public static void ispisTvornica(Factory factory){
System.out.println("Naziv: " + factory.getName());
System.out.println("Web adresa: " + factory.getAddress());
System.out.println("Odabrani artikli: " + factory.getItems());
}
Override toString() method in Item class which returns name then you can use Arrays.toString(factory.getItems())
Try This
Factory.Java
public class Factory {
public static final int MAX_ODABRANIARTIKLI = 3;
String name;
String address;
Item[] items = new Item[MAX_ODABRANIARTIKLI];
public Factory(String name, String address, Item[] items) {
this.name = name;
this.address = address;
this.items = items;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public Item[] getItems() {
return items;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setItems(Item[] items) {
this.items = items;
}
}
Item.java
public class Item {
String name;
String category;
public Item(String name, String category) {
this.name = name;
this.category = category;
}
public String getName() {
return name;
}
public String getCategory() {
return category;
}
public void setName(String name) {
this.name = name;
}
public void setCategory(String category) {
this.category = category;
}
#Override
public String toString() {
return "Item [name=" + name + "]";
}
}
Main.java
public class Main {
public static final int MAX_TVORNICA = 2;
public static void main(String[] args) {
int i = 0;
Factory[] tvornice = new Factory[MAX_TVORNICA];
System.out.println("Unijeli ste sljedeće tvornice:");
Item[] items = { new Item("Joy", "category_Joy"), new Item("Roy", "category_Roy") };
tvornice[0] = new Factory("Jems", "ABC", items);
tvornice[1] = new Factory("ivuksan", "XYZ", items);
for (Factory factory : tvornice) {
ispisTvornica(factory, i++);
}
System.out.println("------------------------------------------------------------------------");
for (Factory factory : tvornice) {
ispisTvornicaAnother(factory);
}
}
public static void ispisTvornica(Factory factory, int i) {
System.out.println("Naziv: " + factory.getName());
System.out.println("Web adresa: " + factory.getAddress());
System.out.println("Odabrani artikli: " +factory.getItems()[i]);
}
public static void ispisTvornicaAnother(Factory factory) {
System.out.println("Naziv: " + factory.getName());
System.out.println("Web adresa: " + factory.getAddress());
for(Item item : factory.getItems())
System.out.println("Odabrani artikli: " + item);
}
}
I define two function:
ispisTvornica() function print for each iteration 1 by 1 item name present in Item class
ispisTvornicaAnother() function print for each iteration it print all items name.
Output:-
Unijeli ste sljedeće tvornice:
Naziv: Jems
Web adresa: ABC
Odabrani artikli: Item [name=Joy]
Naziv: ivuksan
Web adresa: XYZ
Odabrani artikli: Item [name=Roy]
------------------------------------------------------------------------
Naziv: Jems
Web adresa: ABC
Odabrani artikli: Item [name=Joy]
Odabrani artikli: Item [name=Roy]
Naziv: ivuksan
Web adresa: XYZ
Odabrani artikli: Item [name=Joy]
Odabrani artikli: Item [name=Roy]

How to map string json to POJO class?

I have a body return this:
{
"a_name": "Max",
"a_surname": "Miles",
"a_details": {
"DETAILS": [
{
"DATE": "1996-12-31T00:00:00.000",
"AGE": "24",
"ACCNUM": "17",
"FORSPEC": "Smth written here",
"EXIT": "1"
}, ] //list of json
}
By now I am able to return name and surname, but having trouble mapping json field. Here is how my POJO looks like:
class Value {
String name;
String surname;
List<AccountDetail> detail;
//setter getter
}
class AccountDetail {
LocalDateTime DATE;
Number AGE;
Number ACCNUM;
String FORSPEC;
Number EXIT;
//setter getter
}
Here is a mapper for this field:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(
DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
List<AccountDetails> details = mapper.readValue(stringJson, Value.class);
But I am getting errors like unrecognized fields and so on. What is a problem? Maybe I should realize my POJO class in other way or I have a problem with mapper?
You can use Jackson library for Json reading, and use annotation for different name #JsonProperty("a_name")
Few more issues I found in your code:
This is incorrect - List<AccountDetail> detail
You should declare a field DETAILS, as a new class, and inside should be the list.
Also "EXIT" field is missing in the class you defined.
Full working example.
public String test() throws JsonProcessingException
{
String json = "your json here....";
ObjectMapper mapper = new ObjectMapper();
mapper.setDefaultPrettyPrinter(new PrettyPrinter());
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping();
mapper.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule());
mapper.readValue(json, Value.class);
return "success";
}
public static class PrettyPrinter extends DefaultPrettyPrinter
{
private static final long serialVersionUID = 1L;
public PrettyPrinter()
{
indentArraysWith(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE);
}
}
private static class Value
{
#JsonProperty("a_name")
String name;
#JsonProperty("a_surname")
String surname;
#JsonProperty("a_details")
Details details;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getSurname()
{
return surname;
}
public void setSurname(String surname)
{
this.surname = surname;
}
public Details getDetails()
{
return details;
}
public void setDetails(Details details)
{
this.details = details;
}
}
private static class Details
{
#JsonProperty("DETAILS")
AccountDetail []detail;
public AccountDetail[] getDetail()
{
return detail;
}
public void setDetail(AccountDetail[] detail)
{
this.detail = detail;
}
}
private static class AccountDetail
{
LocalDateTime DATE;
Number AGE;
Number ACCNUM;
String FORSPEC;
Number EXIT;
public LocalDateTime getDATE()
{
return DATE;
}
public void setDATE(LocalDateTime DATE)
{
this.DATE = DATE;
}
public Number getAGE()
{
return AGE;
}
public void setAGE(Number AGE)
{
this.AGE = AGE;
}
public Number getACCNUM()
{
return ACCNUM;
}
public void setACCNUM(Number ACCNUM)
{
this.ACCNUM = ACCNUM;
}
public String getFORSPEC()
{
return FORSPEC;
}
public void setFORSPEC(String FORSPEC)
{
this.FORSPEC = FORSPEC;
}
public Number getEXIT()
{
return EXIT;
}
public void setEXIT(Number EXIT)
{
this.EXIT = EXIT;
}
}
You can used Gson library
public class JsonFormater {
public static void main(String[] args) {
Gson gs = new Gson();
// TODO Auto-generated method stub
String jsonstring = "{\n" + " \"a_name\":\"Max\",\n" + " \"a_surname\":\"Miles\",\n"
+ " \"a_details\":{\n" + " \"DETAILS\":[\n" + " {\n"
+ " \"DATE\":\"1996-12-31T00:00:00.000\",\n" + " \"AGE\":\"24\",\n"
+ " \"ACCNUM\":\"17\",\n" + " \"FORSPEC\":\"Smth written here\",\n"
+ " \"EXIT\":\"1\"\n" + " }\n" + " ]\n" + " }\n" + "}";
Information infomation = gs.fromJson(jsonstring, Information.class);
System.out.println(infomation.getaName());
System.out.println(infomation.getaSurname());
if (infomation.getaDetails() != null) {
TestData testdata = infomation.getaDetails();
for (Detail detail : testdata.getDetails()) {
System.out.println(detail.getAge());
}
}
}
}
public class Detail {
#SerializedName("DATE")
#Expose
private String date;
#SerializedName("AGE")
#Expose
private String age;
#SerializedName("ACCNUM")
#Expose
private String accnum;
#SerializedName("FORSPEC")
#Expose
private String forspec;
#SerializedName("EXIT")
#Expose
private String exit;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getAccnum() {
return accnum;
}
public void setAccnum(String accnum) {
this.accnum = accnum;
}
public String getForspec() {
return forspec;
}
public void setForspec(String forspec) {
this.forspec = forspec;
}
public String getExit() {
return exit;
}
public void setExit(String exit) {
this.exit = exit;
}
}
public class TestData {
#SerializedName("DETAILS")
#Expose
private List<Detail> details = null;
public List<Detail> getDetails() {
return details;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
}
public class Information {
#SerializedName("a_name")
#Expose
private String aName;
#SerializedName("a_surname")
#Expose
private String aSurname;
#SerializedName("a_details")
#Expose
private TestData aDetails;
public String getaName() {
return aName;
}
public void setaName(String aName) {
this.aName = aName;
}
public String getaSurname() {
return aSurname;
}
public void setaSurname(String aSurname) {
this.aSurname = aSurname;
}
public TestData getaDetails() {
return aDetails;
}
public void setaDetails(TestData aDetails) {
this.aDetails = aDetails;
}
}
format your json correctly and try like this

Deserialization fails when there is no default constructor

I 'm trying to use Fastjson library for JSON serialization.
When I try to deserialize , it fails showing no default constructor error.
Note: My class here is a toy example. I realty, it contains so many references to other classes which are in other maven projects and its practically not possible to modify every class.
Here is the code.
Student s = new Student("vineel", "20");
String hell = JSON.toJSONString(s);
Student model2 = JSON.parseObject(hell, Student.class);
System.out.println(model2);
public class Student {
private String name;
private String age;
Student(String name,String age){
this.name = name;
this.age = age;
}
#override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
Here is the error:
Exception in thread "main" com.alibaba.fastjson.JSONException: default constructor not found. class com.alibaba.fastjson.Student
at com.alibaba.fastjson.util.JavaBeanInfo.build(JavaBeanInfo.java:467)
at com.alibaba.fastjson.util.JavaBeanInfo.build(JavaBeanInfo.java:213)
at com.alibaba.fastjson.parser.ParserConfig.createJavaBeanDeserializer(ParserConfig.java:656)
at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:573)
at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:386)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:658)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:365)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:269)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:488)
at com.alibaba.fastjson.JSON.main(JSON.java:1068)
Change constructor to.
#JsonCreator
public Student(#JsonProperty("name") String name, #JsonProperty("age") String age){
this.name = name;
this.age = age;
}
So create a TO class.
Student model2 = JSON.parseObject(hell, StudentTO.class).asStudent();
System.out.println(model2);
public class StudentTO {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Student asStudent() {
return new Student(name, age);
}
}

How to iterate the arraylist of diffrent objects

In an ArrayList I have two different objects,
Student and Employee. I want to iterate through them one by one. I am able to iterate through the list and use the Employee objects but not the Student objects.
I have the following code:
package javaCollections;
import java.util.ArrayList;
import java.util.Iterator;
class Employee {
#Override
public String toString() {
return "employee [name=" + name + ", age=" + age + "]";
}
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
Employee(String name, int age) {
this.age = age;
this.name = name;
}
}
class Student {
#Override
public String toString() {
return "student [stud_name=" + stud_name + ", rollNumber=" + rollNumber
+ "]";
}
String stud_name;
int rollNumber;
public Student(String stud_name, int rollNumber) {
super();
this.stud_name = stud_name;
this.rollNumber = rollNumber;
}
public String getStud_name() {
return stud_name;
}
public void setStud_name(String stud_name) {
this.stud_name = stud_name;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
}
public class Arraylist {
ArrayList<Object> emparray;
public void addemp() {
Employee emp = new Employee("abc", 12);
emparray = new ArrayList<Object>();
emparray.add(emp);
Employee emp1 = new Employee("def", 12);
emparray.add(emp1);
Student std = new Student("efg", 123);
Student std1 = new Student("xyz", 123);
emparray.add(std);
emparray.add(std1);
}
public void iterateemp() {
/*
* Iterator<Object> itr=emparray.iterator();
*
* while(itr.hasNext()) { System.out.println(itr.next()); }
*/
for (Object e : emparray) {
System.out.println(((Employee) e).getAge());
System.out.println(((Employee) e).getName());
}
}
public static void main(String[] args) {
Arraylist al = new arraylist();
al.addemp();
al.iterateemp();
}
}
can someone please help me on this?
What you need to do is check the instance of the object.
for (Object e : emparray) {
if(e instanceof employee) {
System.out.println(((employee) e).getAge());
System.out.println(((employee) e).getName());
} else if(e instanceof student) {
// do something else
}
}
}
IMO this is a bad design.
The best practice is to create common base called Person that has shared fields like name. Then you can replace Object with Person in the loop.
import java.util.ArrayList;
import java.util.Iterator;
interface Person{
public String getName();
public void setName(String name);
}
class employee implements Person{
#Override
public String toString() {
return "employee [name=" + name + ", age=" + age + "]";
}
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
employee(String name, int age) {
this.age = age;
this.name = name;
}
}
class student implements Person{
#Override
public String toString() {
return "student [stud_name=" + name + ", rollNumber=" + rollNumber
+ "]";
}
String name;
int rollNumber;
public student(String stud_name, int rollNumber) {
super();
this.name = stud_name;
this.rollNumber = rollNumber;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name=name;
}
}
public class arraylist {
ArrayList<Person> emparray;
public void addemp() {
employee emp = new employee("abc", 12);
emparray = new ArrayList<Person>();
emparray.add(emp);
employee emp1 = new employee("def", 12);
emparray.add(emp1);
student std = new student("efg", 123);
student std1 = new student("xyz", 123);
emparray.add(std);
emparray.add(std1);
}
public void iterateemp() {
for (Person e : emparray) {
if (e instanceof employee) {
System.out.println(((employee) e).getAge());
}else{
/// do for student
}
System.out.println(e.getName());
}
}
public static void main(String[] args) {
arraylist al = new arraylist();
al.addemp();
al.iterateemp();
}
}
for (Object e : emparray) {
if(e instanceof employee) {
System.out.println(((employee) e).getAge());
System.out.println(((employee) e).getName());
} else if(e instanceof student) {
System.out.println(((student) e).getRollNumber());
System.out.println(((student) e).getStud_name());
}
}
}

LinkedList && Servlet

`I am a new to java and to servlet topic.
I write a little web application. it's collect some data from web-form and add it into a LinkedList.
But my debugger shown me that adding to LL doesnt occur. HELP PLEASE!
Here some code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String surname = request.getParameter("surname");
String fatherName = request.getParameter("fathername");
String department = request.getParameter("department").toLowerCase();
Integer age = Integer.valueOf(request.getParameter("age"));
System.out.println(name);
System.out.println(surname);
System.out.println(fatherName);
responseToUser(addEmployee(name,surname,fatherName,department, age),response);
}
public boolean addEmployee(String name, String surname, String fathername, String department, Integer age) {
AllWorkers workers = new AllWorkers();
if (!name.equals("") && !surname.equals("") && !fathername.equals("") && !dep artment.equals("") && age != null) {
Person person = new Person(surname, name, fathername, department, age);
Departments dep = Departments.valueOf(person.getDepartment());
if (dep == Departments.логистика) {
workers.addLogistic(person);
} else if (dep == Departments.продажи) {
workers.addSales(person);
}
return true;
} else {
return false;
}
}
public void responseToUser(boolean boo, HttpServletResponse response) throws IOException {
Gson gson = new Gson();
response.setContentType("application/json");
if(boo == true){
response.getWriter().write(gson.toJson(true));
}else if(boo == false){
response.getWriter().write(gson.toJson(false));
}
}
Departments:
public enum Departments {
логистика,продажи
}
AllWorkers.java
public class AllWorkers {
LinkedList<Person> logistic = new LinkedList<Person>();
LinkedList<Person> sales = new LinkedList<Person>();
public void addLogistic(Person person){
logistic.add(person);
}
public void addSales(Person person){sales.add(person);}
public LinkedList<Person> getLogistic() {
return logistic;
}
public LinkedList<Person> getSales() {
return sales;
}
}
Person.java
public class Person {
private String name;
private String surname;
private String fatherName;
private String department;
private int age;
Person(){
}
Person(String name, String surname, String fatherName,String department, int age){
this.name = name;
this.surname = surname;
this.fatherName = fatherName;
this.department = department;
this.age = age;
}
public String getDepartment() {
return department;
}
public String getFatherName() {
return fatherName;
}
public int getAge() {
return age;
}
public String getSurname() {
return surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setFatherName(String fatherName) {
this.fatherName = fatherName;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void setDepartment(String department) {
this.department = department;
}
}
(I assume you have checked your variables name, surname, fatherName, department and age have correct values)
I have tested your code and persons are added to LinkedLists contained in AllWorkers correctly. However, in method addEmploye() you do this:
AllWorkers workers = new AllWorkers();
which means you create a new workers every time you comsume the servlet, and each time that workers will be empty since it's a new object. Maybe that is the reason it seems that persons are not added to lists.
Regards,

Categories