I want to 'pase xml and serve objects in rest api - java

` This is my xml code.Iam very new to restservice.
<?xml version="1.0" encoding="UTF-8"?>
<departments>
<deptname name="Research">
<employee>
<eid>r-001</eid>
<ename>Dinesh R</ename>
<age>35</age>
<deptcode>d1</deptcode>
<deptname>Research</deptname>
<salary>20000</salary>
</employee>
</deptname>
<deptname name="Sales">
<employee>
<eid>s-001</eid>
<ename>Kanmani S</ename>
<age>35</age>
<deptcode>d2</deptcode>
<deptname>Sales</deptname>
<salary>30000</salary>
</employee>
</deptname>
</departments>
By using this xml i want to create Restservice.I have tried , i created java classes for that(i don't know that correct or not ).but i am stuck in controller in that area how i will mapping.

Here is a simplest way, in my opinion
1) create a Departments pojo
2) create Department pojo which will be composed (composition) into departments
3) create a regular springboot controller, ensure the controller method produces and consumes application/xml
4) include below dependency in your pom.xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
here is my example,
Departments.java
import org.springframework.stereotype.Component;
#Component
public class Departments {
private List<Department> department;
public List<Department> getDepartment() {
return department;
}
public void setDepartment(List<Department> department) {
this.department = department;
}
}
Department.java
import org.springframework.stereotype.Component;
#Component
public class Department {
private String name;
private String id;
private int employeeCount;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getEmployeeCount() {
return employeeCount;
}
public void setEmployeeCount(int employeeCount) {
this.employeeCount = employeeCount;
}
#Override
public String toString() {
return "Department [name=" + name + ", id=" + id + ", employeeCount=" +
employeeCount + "]";
}
public Department() { }
public Department(String name) {
this.name = name;
}
public Department(String name, String id) {
this.name=name;
this.id=id;
}
public Department(String name, String id, int employeeCount) {
this.name=name;
this.id=id;
this.employeeCount = employeeCount;
}
}
SpringBootApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackages = {"test.controllers","test.main", "test.model"})
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
SpringController
#RestController
public class GreetingController {
#RequestMapping("/hello/{name}")
String hello(#PathVariable String name) {
return "Hello, " + name + "!";
}
#PostMapping(path = "/departments", produces = MediaType.APPLICATION_XML_VALUE, consumes = MediaType.APPLICATION_XML_VALUE)
#ResponseBody
Departments newEmployee(#RequestBody List<Department> departments) {
Departments departmentsObj = new Departments();
for(Department department : departments) {
System.out.println(department);
}
departmentsObj.setDepartment(departments);
return departmentsObj;
}
}

Related

"status": 404 Error for POST Request in Spring Boot CRUD

I developed Spring Boot CRUD application. The database I have connected is PostgreSQL. #GetMapping is working properly and an empty array of objects can be retrieved by the GET request. But in #PostMapping, the POST request gives a 404 error.
đź“ŚSpringRecapApplication.java
package com.example.SpringRecap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#SpringBootApplication(exclude = SecurityAutoConfiguration.class)
//#RequestMapping("api/v1/customers")
//#EnableWebMvc
#RequestMapping(name = "api/v1/customers" ,method = RequestMethod.POST)
public class SpringRecapApplication {
//dependency injection
private static CustomerRepository customerRepository;
public SpringRecapApplication(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
public static void main(String[] args) {
SpringApplication.run(SpringRecapApplication.class, args);
}
#GetMapping
public List<Customer> getCustomer() {
return customerRepository.findAll();
}
record NewCustomerRequest(
String name,
String email,
Integer age
) {
#PostMapping
public void addCustomer(#RequestBody NewCustomerRequest newCustomerRequest) {
Customer customer = new Customer();
customer.setAge(newCustomerRequest.age());
customer.setName(newCustomerRequest.name());
customer.setEmail(newCustomerRequest.email());
customerRepository.save(customer);
}
}
}
customerRepository.save(customer); doesn't allow to make the dependency injection final. ( private static CustomerRepository customerRepository;). IDEA suggests making it static. But it didn't work. When I was using #RequestMapping("api/v1/customers"), a 405 error was received. Then I fixed that issue by doing as below,
#RequestMapping(name = "api/v1/customers" ,method = RequestMethod.POST)
đź“ŚCustomerRepository.java
package com.example.SpringRecap;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CustomerRepository extends JpaRepository<Customer,Integer> {
}
đź“ŚCustomer.java
package com.example.SpringRecap;
import jakarta.persistence.*;
import java.util.Objects;
#Entity
public class Customer {
#Id
#SequenceGenerator(
name = "customer_id_sequence",
sequenceName = "customer_id_sequence",
allocationSize = 1
)
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "customer_id_sequence"
)
private Integer id;
private String name;
private String email;
private Integer age;
public Customer(Integer id, String name, String email, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
public Customer() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return Objects.equals(id, customer.id) && Objects.equals(name, customer.name) && Objects.equals(email, customer.email) && Objects.equals(age, customer.age);
}
#Override
public int hashCode() {
return Objects.hash(id, name, email, age);
}
#Override
public String toString() {
return "Customer{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
Postman:
Please put a comment if further information is needed to get the solution.
The problem with your code is that you specified the POST endpoint as part of your DTO and not as part of your controller. As your DTO is not a Spring managed bean, Spring won't map the URL to your endpoint. Anyways, you should move your endpoints into a seperate class. Example:
#RestController
#RequestMapping("api/v1/customers")
public class CustomerController {
private final CustomerRepository customerRepository;
public SpringRecapApplication(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
#GetMapping
public List<Customer> getCustomer() {
return customerRepository.findAll();
}
#PostMapping
public void addCustomer(#RequestBody NewCustomerRequest newCustomerRequest) {
Customer customer = new Customer();
customer.setAge(newCustomerRequest.age());
customer.setName(newCustomerRequest.name());
customer.setEmail(newCustomerRequest.email());
customerRepository.save(customer);
}
// Helper classes
record NewCustomerRequest(String name, String email, Integer age) { }
}
It would be best if you moved your DTO in a seperate class as well. I recommend placing the DTOs in a dto package and your controllers in a controller package.
Two side notes: you shouldn't expose your entities via your API. You should use DTOs for incoming and outgoing data. Check out lombok and mapstruct, they make this pretty easy.

Spring Boot Hibernate CRUD REST API 404 Error

I am simply trying to create a Spring boot Hibernate CRUD REST API through this code:
EmployeController.java
#RestController
#RequestMapping("/api")
public class EmployeController {
#Autowired
private EmployeService employeService;
#GetMapping("/employe")
public List<Employe> get(){
return employeService.get();
}
}
Employe.java
#Entity
#Table(name="employe")
public class Employe {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private int id;
#Column
private String name;
#Column
private String gender;
#Column
private String department;
#Column
private Date dob;
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
#Override
public String toString() {
return "Employe [id=" + id + ", name=" + name + ", gender=" + gender + ", department=" + department + ", dob="
+ dob + "]";
}
}
EmployeService.java
public interface EmployeService {
List<Employe> get();
Employe get(int id);
void save(Employe employe);
void delete(int id);
}
EmployeServiceImplement.java
#Service
public class EmployeServiceImplement implements EmployeService {
#Autowired
private EmployeDAO employeDAO;
#Transactional
#Override
public List<Employe> get() {
return employeDAO.get();
}
}
EmployeDAO.java
public interface EmployeDAO {
List<Employe> get();
Employe get(int id);
void save(Employe employe);
void delete(int id);
}
EmployeDAOImplement.java
#Repository
public class EmployeDAOImplement implements EmployeDAO {
#Autowired
private EntityManager entityManager;
#Override
public List<Employe> get() {
Session currentSession = entityManager.unwrap(Session.class);
Query<Employe> query = currentSession.createQuery("from Employe", Employe.class);
List<Employe>list = query.getResultList();
return list;
}
}
I have write all the configuration related to MySQl database into the application.properties and when i run this project as Spring Boot App and go to the Postman and tried like this
and i a unable to understan why it always throws 404 error every time , can anyone tell me what i am missing in this code.
Try with this GET request, it may help you:
http://localhost:8080/api
I checked your code.
where is #RestController for your Controller file and where is #RequestMapping For your method in Controller class?
maybe you should write something like this according to your need.
tell me if you need more help.
#RestController
#RequestMapping("/api")
public class EmployeController {
#RequestMapping(value = "/employ")
public void employ() {
}
}
Instead of this -
#Override
public List get()
Use this -
#RequestMapping(value = "/Employe", method = RequestMethod.GET)
public List get()

Null values for XML attribute unmarshaling

This is my xml file and it is returning null values for type and currency when unmarshalling and rest all values are getting printed. I have used unmarshalling here and all Parent and Child POOJ are specified and finally my Main method calls unmarshall function
1) Vehicle.xml
<?xml version="1.0" encoding="UTF-8"?>
<Vehicle>
<car>
<manufacturer>Maruti</manufacturer>
<cost currency="INR">675000</cost>
<name type="sedan">Ciaz</name>
<fuelType>Petrol</fuelType>
<driverType>Manual</driverType>
</car>
<car>
<manufacturer>Maruti</manufacturer>
<cost currency="INR">575000</cost>
<name type="sedan">Dezire</name>
<fuelType>Petrol</fuelType>
<driverType>Manual</driverType>
</car>
</Vehicle>
Respective file are as
2) Vehicle.java
package jaxb;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "Vehicle")
public class Vehicle {
#XmlElement
private List<Car> car;
public List<Car> getCar() {
return car;
}
#Override
public String toString() {
return "Vehicle[ Car=" + car + "]";
}
}
3) Child for POJO Car.java
package jaxb;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="Car")
public class Car {
private String manufacturer;
private String name;
private String driverType;
private String fuelType;
private String currency;
#XmlAttribute
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
#XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String type;
private int cost;
#XmlElement
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
#XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement
public String getDriverType() {
return driverType;
}
public void setDriverType(String driverType) {
this.driverType = driverType;
}
#XmlElement
public String getFuelType() {
return fuelType;
}
public void setFuelType(String fuelType) {
this.fuelType = fuelType;
}
#XmlElement
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
#Override
public String toString() {
return "Car [name=" + name + ", fuelType=" + fuelType + ", cost=" + cost+",driverType="+driverType +",currency="+currency+ " , type="+type +"]";
}
}
4) Fie for unmarshalling
package jaxb;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class VehicleJxb {
public void unmarhalling() {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Vehicle.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Vehicle vehicle = (Vehicle) jaxbUnmarshaller.unmarshal(new File("src\\main\\java\\Data\\Vehicle.xml"));
System.out.println(vehicle);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
5) Final Output
Vehicle[ Car=[Car [name=Ciaz, fuelType=Petrol, cost=675000,driverType=Manual,currency=null , type=null], Car [name=Dezire, fuelType=Petrol, cost=575000,driverType=Manual,currency=null , type=null]]]
With JAXB you can map attributes only on the same level. To map attributes on embedded elements you should use separate classes for these elements.
Here is how you can map attributes (publci attributes used for simplicity):
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
#XmlRootElement(name = "Car")
public class Car {
public static class Cost {
#XmlValue
public String value;
#XmlAttribute
public String currency;
#Override
public String toString() {
return "Cost[value=" + value + ", currency=" + currency + "]";
}
}
public static class Name {
#XmlValue
public String value;
#XmlAttribute
public String type;
#Override
public String toString() {
return "Name[value=" + value + ", type=" + type + "]";
}
}
private String manufacturer;
private Name name;
private String driverType;
private String fuelType;
#XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String type;
private Cost cost;
#XmlElement
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
#XmlElement
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
#XmlElement
public String getDriverType() {
return driverType;
}
public void setDriverType(String driverType) {
this.driverType = driverType;
}
#XmlElement
public String getFuelType() {
return fuelType;
}
public void setFuelType(String fuelType) {
this.fuelType = fuelType;
}
#XmlElement
public Cost getCost() {
return cost;
}
public void setCost(Cost cost) {
this.cost = cost;
}
#Override
public String toString() {
return "Car [name=" + name + ", fuelType=" + fuelType + ", cost=" + cost + ",driverType=" + driverType + "]";
}
}
One common approach would be to add an extra class to handle the attribute + value. If you don't want the extra indirection when using Car. You can add a shortcut getter to it.
public class Car {
// .....
private Money cost;
public Money getCost() {
return cost;
}
public void setCost(Money cost) {
this.cost = cost;
}
/* Optional shortcut getter */
public String getCurrency(){
if(getCost()==null){
return null;
}
return getCost().getCurrency();
}
}
public static class Money {
private String currency;
private int amount;
#XmlAttribute
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
#XmlValue
public int getAmount() {
return amount;
}
public void setAmount(int cost) {
this.amount = cost;
}
}
try this:
#XmlAttribute(name = "cost currency")
public String getCurrency() {
return currency;
}
#XmlAttribute(name = "name type")
public String getType() {
return type;
}

Spring Data JPA ManyToOne Bidirectional

Problem: it works till i try to add Student obejcts to Database, but the tables are being created correctly .
I can't simplify the post any further. But it's mainly code that doesn't require a lot of reading, it's a simple spring data repository service model. I posted it all due to the fact idk what am i doing wrong. Problem is in the JPA mapping.
I got the example from over here http://www.java2s.com/Tutorial/Java/0355__JPA/OneToManyBidirectional.htm
MDOELS
#Entity
public class Department {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
#OneToMany(mappedBy="department")
private Collection<Student> students;
public Department() {
}
public Department(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String deptName) {
this.name = deptName;
}
public Collection<Student> getStudents() {
return students;
}
public void setStudent(Collection<Student> students) {
this.students = students;
}
public String toString() {
return "Department id: " + getId() +
", name: " + getName();
}
}
#Entity
public class Student {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
#ManyToOne (cascade=CascadeType.ALL)
private Department department;
public Student() {
}
public Student(String name, Department department) {
this.name = name;
this.department = department;
}
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 Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public String toString() {
return "\n\nID:" + id + "\nName:" + name + "\n\n" + department;
}
}
REPOSITORIES
#Repository
public interface DepartmentRepository extends JpaRepository<Department, Integer> {
Department findByName(String name);
}
#Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {
Student findByName(String name);
}
SERVICES
#Service
public class StudentService {
private final StudentRepository studentRepository;
#Autowired
public StudentService(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
public void addToDatabase(Student student) {
this.studentRepository.saveAndFlush(student);
}
public Student getStudentByName(String name) {
return studentRepository.findByName(name);
}
}
#Service
public class DepartmentService {
private final DepartmentRepository departmentRepository;
#Autowired
public DepartmentService(DepartmentRepository departmentRepository) {
this.departmentRepository = departmentRepository;
}
public void addToDataBase(List<Department> department) {
this.departmentRepository.save(department);
department.forEach(this.departmentRepository::saveAndFlush);
}
public Department getDepartmentByName(String name){
return this.departmentRepository.findByName(name);
}
}
My main method
#Component
public class Terminal implements CommandLineRunner {
private final StudentService studentService;
private final DepartmentService departmentService;
#Autowired
public Terminal(StudentService studentService, DepartmentService departmentService) {
this.studentService = studentService;
this.departmentService = departmentService;
}
#Override
public void run(String... strings) throws Exception {
Department department = new Department("dep1");
Department department1 = new Department("dep2");
Department department2 = new Department("dep3");
Department department3 = new Department("dep4");
List<Department> departments = new ArrayList<>(Arrays.asList(department, department1, department2, department3));
this.departmentService.addToDataBase(departments);
//
Student student = new Student("pesho", department);
Student student11 = new Student("gosho", department1);
this.studentService.addToDatabase(student11);
this.studentService.addToDatabase(student);
student = new Student("sasho", department2);
this.studentService.addToDatabase(student);
// System.out.println(this.studentService.getStudentByName("gosho").getDepartment1());
// System.out.println("CHECKING ONE TO ONE BIDIRECTIONAL: " + this.departmentService.getDepartmentByName("dep1").getStudent());
}
}
So here when i try to add students in the students table it gives an error
The error is the fallowing
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: app.models.Department
you added cascade= CascadeType.ALL for Department in Student class and save departments separete. this.departmentService.addToDataBase(departments);
fix : dont call
departmentService.addToDataBase(departments);
or remove CascadeType.ALL from Student
Well I can't understand you problem completely but here's what I would like to add. Cascading for add operation is not implemented or it's incomplete. Hope it helps.

JAXB : 2 counts of IllegalAnnotationExceptions

This is my Parser class
public class Test {
public static void main(String args[]) throws Exception {
File file = new File("D:\\Test.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(MyOrder.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MyOrder customer = (MyOrder) jaxbUnmarshaller.unmarshal(file);
System.out.println(customer.getOrder().getSide());
}
}
This is MyOrder.java file
#XmlRootElement(name = "BXML")
public class MyOrder {
#XmlElement(name = "Bag")
protected Order order;
public MyOrder() {
}
#XmlAttribute
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
This is my Domain Object (Order.java )
#XmlRootElement(name = "BXML")
public class Order {
public Order() {
}
#XmlAttribute(name = "Side")
protected BigInteger Side;
#XmlValue
public BigInteger getSide() {
return Side;
}
public void setSide(BigInteger side) {
Side = side;
}
}
This is the exception that I am getting when I tried to run the program
Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
#XmlAttribute/#XmlValue need to reference a Java type that maps to text in XML.
this problem is related to the following location:
at public com.Order com.MyOrder.getOrder()
at com.MyOrder
Class has two properties of the same name "order"
this problem is related to the following location:
at public com.Order com.MyOrder.getOrder()
at com.MyOrder
this problem is related to the following location:
at protected com.Order com.MyOrder.order
at com.MyOrder
For the #XmlAttribute/#XmlValue need to reference a Java type that maps to text in XML. issue you need to change your initialization of JAXBContext to the following:
JAXBContext jaxbContext = JAXBContext.newInstance(MyOrder.class, Order.class);
For the Class has two properties of the same name "order" issue, you need to change the definition of protected Order order; to private Order order;.
Also, you want to change the #XmlRootElement(name = "BXML") of your Order class to #XmlRootElement(name = "Order").
You can see the below sample code to generate Java Object from given XML.It is working fine in my system.
customer.xml
<?xml version="1.0" encoding="UTF-8"?>
<company>
<customer id="100">
<age>25</age>
<name>Ram</name>
<Address>
<city>Bangalore</city>
<country>India</country>
</Address>
<Address>
<city>Patna</city>
<country>India</country>
</Address>
</customer>
<customer id="200">
<age>26</age>
<name>Ashu</name>
<Address>
<city>Delhi</city>
<country>India</country>
</Address>
<Address>
<city>Madhubani</city>
<country>India</country>
</Address>
</customer>
</company>
Company.java
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="company")
public class Company {
#XmlElement(name="customer")
private List<Costumer> custList;
//
public List<Costumer> getCustList() {
return custList;
}
public void setCustList(List<Costumer> custList) {
this.custList = custList;
}
//
#Override
public String toString() {
return "Company [custList=" + custList + "]";
}
}
Costumer.java
#XmlAccessorType(XmlAccessType.FIELD)
class Costumer {
#XmlElement(name="name")
private String name;
#XmlElement(name="age")
private int age;
#XmlElement(name="id")
private int id;
#XmlElement(name="Address")
private List<Address> addressList;
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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
#Override
public String toString() {
return "Customer [name=" + name + ", age=" + age + ", id=" + id + ", addressList=" + addressList + "]";
}
}
Address.java
#XmlAccessorType(XmlAccessType.FIELD)
class Address {
#XmlElement(name="city")
private String city;
#XmlElement(name="country")
private String country;
//
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
//
#Override
public String toString() {
return "Address [city=" + city + ", country=" + country + "]";
}
}
TestMain.java
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class TestMain {
public static void main(String[] args) {
String xmlPath = "C:\\" + File.separator + "customer.xml";
try {
File file = new File(xmlPath);
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] {Company.class,Address.class,Costumer.class});
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Company customer = (Company) jaxbUnmarshaller.unmarshal(file);
System.out.println(customer);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Outout:
Company [custList=[Customer [name=Ram, age=25, id=0, addressList=[Address [city=Bangalore, country=India], Address [city=Patna, country=India]]], Customer [name=Ashu, age=26, id=0, addressList=[Address [city=Delhi, country=India], Address [city=Madhubani, country=India]]]]]
This is because the sub-elements of that class you are creating JAXBcontext instance ,doesn't have the same name as of the element names defined inside it.
Example:
#XmlType(name = "xyz", propOrder = { "a", "b", "c", "d" })
#XmlRootElement(name = "testClass")
public class TestClass
{
#XmlElement(required = true)
protected Status status;
#XmlElement(required = true)
protected String mno;
#XmlElement(required = true)
}
In the above class you don't have "xyz" , but if you will put the property name that is not available JAXBContext instantiation throws IlligalAnnotationException.
If anyone is curious about the usage of JAXB and Lombok.
My fix was to remove the getter and setter from the root object.

Categories

Resources