Spring Boot支持XML的REST服务

8

我使用Spring Boot 1.2.5开发了一个简单的REST webservice服务,对于JSON格式的数据它能正常工作,但是我无法让它返回XML格式的数据。

这是我的控制器:

@RestController
..
@RequestMapping(method = RequestMethod.GET,  produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
@ResponseStatus(HttpStatus.OK)
public List<Activity> getAllActivities() {
    return activityRepository.findAllActivities();
}

当我使用 Accept: application/json 进行调用时,一切正常,但当我尝试使用 application/xml 时,会收到带有406错误和消息的HTML。
The resource identified by this request is only capable of generating responses 
with characteristics not acceptable according to the request "accept" headers.

我的模型对象:

@XmlRootElement
public class Activity {

    private Long id;
    private String description;
    private int duration;
    private User user; 
    //getters & setters...
}

@XmlRootElement
public class User {

    private String name;
    private String id;
    //getters&setters...
}

My pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <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-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

我需要在我的pom.xml中添加一些额外的jar包才能使它工作吗?我尝试添加jaxb-api或jax-impl,但没有帮助。


你确定你设置的是 application/xml 而不是其他什么吗?启用调试日志并查看内部发生了什么。 - M. Deinum
你能分享一下你的 POM 文件吗? - Avis
@Avis,我粘贴了我的pom.xml文件。 - jgr
2个回答

22

要在Spring Boot中实现此功能而不使用Jersey,需要添加以下依赖项:

<dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

输出结果可能会有点丑陋,但它可以正常工作:

<ArrayList 
    xmlns="">
    <item>
        <id/>
        <description>Swimming</description>
        <duration>55</duration>
        <user/>
    </item>
    <item>
        <id/>
        <description>Cycling</description>
        <duration>120</duration>
        <user/>
    </item>
</ArrayList>

这里有一个不错的教程:http://www.javacodegeeks.com/2015/04/jax-rs-2-x-vs-spring-mvc-returning-an-xml-representation-of-a-list-of-objects.html


我使用Tomcat,但仍然无法正常工作... https://stackoverflow.com/questions/54223494/how-to-make-jackson2codesupport-to-support-the-xml - ses
有人知道如何避免XML转义,如果项目的主体是字符串(实际上是格式良好的XML)?必须使用XmlMapper进行修改吗? - Simon Logic

0
我们可以按照以下方式实现:
代码
        package com.subu;

        import java.io.Serializable;

        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.Id;
        import javax.persistence.Table;
        import javax.xml.bind.annotation.*;

        @Entity
        @XmlRootElement(name = "person")
        @Table(name="person")

        public class Person implements Serializable{
            private static final long serialVersionUID = 1L;

            @Id
            @GeneratedValue
            private Long id;

            @XmlAttribute(name = "first-name")
            private String first_name;

            public Long getId() {
                return id;
            }

            public void setId(Long id) {
                this.id = id;
            }

            public String getFirst_name() {
                return first_name;
            }

            public void setFirst_name(String first_name) {
                this.first_name = first_name;
            }

            public String getLast_name() {
                return last_name;
            }

            public void setLast_name(String last_name) {
                this.last_name = last_name;
            }

            public String getDate_of_birth() {
                return date_of_birth;
            }

            public void setDate_of_birth(String date_of_birth) {
                this.date_of_birth = date_of_birth;
            }

            @XmlAttribute(name = "last-name")
            private String last_name;

            @XmlAttribute(name = "dob")
            private String date_of_birth;


        }

        @RestController
        public class PersonController {

            @Autowired
            private PersonRepository personRepository;

            @RequestMapping(value = "/persons/{id}", method = RequestMethod.GET,produces={MediaType.APPLICATION_XML_VALUE},headers = "Accept=application/xml")
            public ResponseEntity<?> getPersonDetails(@PathVariable Long id, final HttpServletRequest request)throws Exception {
                Person personResponse=personRepository.findPersonById(id);
                return ResponseEntity.ok(personResponse);
            }

        }

        package com.subu;

        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.boot.builder.SpringApplicationBuilder;
        import org.springframework.boot.context.web.SpringBootServletInitializer;
        import org.springframework.context.annotation.ComponentScan;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.scheduling.annotation.EnableScheduling;


        @SpringBootApplication
        @Configuration
        @ComponentScan
        @EnableAutoConfiguration
        @EnableScheduling
        public class Application extends SpringBootServletInitializer{



           public static void main(String[] args) {
              SpringApplication.run(Application.class, args);
           }

           @Override
           protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
               return application.sources(Application.class);
           }

           private static Class<Application> applicationClass = Application.class;

        }

ScreenShot


1
当答案包含数百行代码和配置时,你就知道这是一个Java主题。 - EralpB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接