I have written a REST API in spring boot. The API returns a list of object as a response. I am returning a ResponseEntity object from the API's controller class. But the XML output I get is not properly formatted. I am using com.fasterxml.jackson.dataformat
library.
The POM file for the Project is:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sampleapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
My controller class is:
TestController.java
package com.example.sampleapi.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.sampleapi.Entity.Student;
import com.example.sampleapi.Entity.StudentResponse;
import com.example.sampleapi.dao.StudentDAO;
@RestController
public class TestController {
@Autowired
private StudentDAO studentDao;
@RequestMapping(value = "/save", method =RequestMethod.GET,
produces = {
MediaType.APPLICATION_XML_VALUE})
public boolean saveAllStudents() {
return studentDao.saveStudents();
}
@RequestMapping(value = "/get", method =RequestMethod.GET, produces = {
MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<StudentResponse> getAllStudents() {
List<Student> studentList = studentDao.getAllStudent();
int count = studentList.size();
StudentResponse studentResponse = new StudentResponse();
studentResponse.setStudentList(studentList);
studentResponse.setCount(count);
return new ResponseEntity<StudentResponse>(studentResponse, HttpStatus.OK);
}
}
My DAO class is:
StudentDAOImpl.java
package com.example.sampleapi.dao.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.example.sampleapi.Entity.Student;
import com.example.sampleapi.dao.StudentDAO;
@Repository
public class StudentDAOImpl implements StudentDAO {
private List<Student> studentDetails = new ArrayList<>();
@Override
public boolean saveStudents() {
Student student1 = new Student();
student1.setName("A");
student1.setAge(23);
student1.setMarks(100);
Student student2 = new Student();
student2.setName("B");
student2.setAge(25);
student2.setMarks(90);
Student student3 = new Student();
student3.setName("C");
student3.setAge(19);
student3.setMarks(95);
studentDetails.add(student1);
studentDetails.add(student2);
studentDetails.add(student3);
if(studentDetails.size() > 0) {
return true;
} else {
return false;
}
}
@Override
public List<Student> getAllStudent() {
return studentDetails;
}
}
The Student Entity class is as follows:
Student.java
package com.example.sampleapi.Entity;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Student {
private String name;
private int age;
private double marks;
public Student() {
super();
// TODO Auto-generated constructor stub
}
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 double getMarks() {
return marks;
}
public void setMarks(double marks) {
this.marks = marks;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", marks=" + marks + "]";
}
}
The Response class is as follows:
StudentResponse.java
package com.example.sampleapi.Entity;
import java.util.List;
public class StudentResponse {
int count;
List<Student> studentList;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
}
The Xml response for the /get
RequestMapping is :
<StudentResponse>
<count>3</count>
<studentList>
<studentList>
<name>A</name>
<age>23</age>
<marks>100.0</marks>
</studentList>
<studentList>
<name>B</name>
<age>25</age>
<marks>90.0</marks>
</studentList>
<studentList>
<name>C</name>
<age>19</age>
<marks>95.0</marks>
</studentList>
</studentList>
</StudentResponse>
Why the Student objects inside the list are coming as <studentList></studentList>
, it should be <student></student>
instead?
The XML format I am expecting is:
<StudentResponse>
<count>3</count>
<studentList>
<student>
<name>A</name>
<age>23</age>
<marks>100.0</marks>
</student>
<student>
<name>B</name>
<age>25</age>
<marks>90.0</marks>
</student>
<student>
<name>C</name>
<age>19</age>
<marks>95.0</marks>
</student>
</studentList>
</StudentResponse>
The reason you get the outer studentList
is that that is the property name of that list in the StudentResponse
.
The reason you get the inner studentList
is that
When a collection property is annotated just with @XmlElement [as is assumed in Spring Boot when you don't have any annotation], each item in the collection will be wrapped by an element. Source
You'll need to put annotations on your Java classes to get the result you want, in this case something like shown here
public class Customer {
@XmlElementWrapper(name="studentList")
@XmlElement(name="student")
private List<Student> studentList;
}
Try this out
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "student")
public class Student {
...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.