简体   繁体   中英

How to get a XML respose for a api which returns a response entity consisting of a list of object

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM