代码之家  ›  专栏  ›  技术社区  ›  Anddo

Spring Boot找不到XML响应的可接受表示形式

  •  1
  • Anddo  · 技术社区  · 6 年前

    我为这个异常和原因找到了多种解决方案,但都没有奏效,似乎不合逻辑。

    我有如下的休息服务班

    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.http.MediaType;
    
    import java.util.Map;
    @RestController
    public class UserRestService {
    
        @RequestMapping(value = "/userLogin", method = RequestMethod.POST, produces = MediaType.APPLICATION_XML_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
        public @ResponseBody ResponseEntity<Map> login(@RequestBody Map<String, String> name) {
            ResponseEntity<Map> res = null;
            name.values().forEach(System.out::println);
            return new ResponseEntity<Map>(name, HttpStatus.OK);
        }
    }
    

    日志中的异常是

    John
    30
    null
    2018-08-16 14:05:48.440  WARN 22820 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    2018-08-16 14:05:48.481  WARN 22820 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    

    Accept:*/*
    Content-Type:application/json
    

    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.cms</groupId>
        <artifactId>business</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.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-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.6</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>javax.xml.bind</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>2.3.0</version>
            </dependency>
            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-core</artifactId>
                <version>2.3.0.1</version>
            </dependency>
            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-impl</artifactId>
                <version>2.3.0.1</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    注意添加以下依赖项可以解决问题

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

    请求正文 { "name":"John", "age":30, "car":null }

    MediaType.APPLICATION_JSON_UTF8_VALUE 用于 produces @RequestMapping {“name”:“John”,“age”:30,“car”:空}

    如果 MediaType.APPLICATION_XML_VALUE 生产 属性 @请求映射 jackson-dataformat-xml 使用的是

    <Map>
        <name>John</name>
        <age>30</age>
        <car/>
    </Map>
    

    更新01

    同样精确的效果 . 这是更新的代码

    public class MockupResponse {
    
        private String name;
        private Integer age;
        private String car;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getCar() {
            return car;
        }
    
        public void setCar(String car) {
            this.car = car;
        }
    
    @Override
    public String toString() {
            StringBuffer sb = new StringBuffer();
            if (null != name)
                sb.append("Name: " + name + "\n");
            if (null != age)
                sb.append("Age: " + age + "\n");
            if (null != car)
                sb.append("Car: " + car + "\n");
    
            return sb.toString();
    }
    }
    

    @RequestMapping(value = "/userLogin", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
        public @ResponseBody ResponseEntity<MockupResponse> login(@RequestBody MockupResponse sample) {
            System.out.println(sample);
    
            return new ResponseEntity<MockupResponse>(sample, HttpStatus.OK);
        }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Simon Martinelli    6 年前

    将@XmlRootElement添加到必须由JAXB类序列化的类中

    @XmlRootElement
    public class MockupResponse {
    
        private String name;
        private Integer age;
        private String car;
    ...
    }
    

    然后XML序列化工作。

    https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html

    如果使用Java 9及更高版本,则必须将JAXB和javax.activation添加到依赖项中:

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>