gpt4 book ai didi

xml - Spring Boot 找不到可接受的 XML 响应表示

转载 作者:可可西里 更新时间:2023-11-01 16:59:17 31 4
gpt4 key购买 nike

我找到了针对此异常和原因的多种解决方案,但没有一个有效,而且似乎不合逻辑。

我有如下 REST 服务类

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);
}
}

如您所见,我尝试创建一个请求正文为 JSON 且响应为 XML 的 POST 请求,并在此过程中打印请求。这只是一个简单的示例,但是当请求被正确打印时,这意味着它已被接收并编码到 Map。然而响应状态是406( Not Acceptable )

日志中的异常是

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

请求 header 只是有

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 用于 @RequestMappingproduces 属性,则响应为 { "name":"John", “年龄”:30,“汽车”:null

如果 MediaType.APPLICATION_XML_VALUE 用于 @RequestMappingjackson-dataformat-xmlproduces 属性时的响应用的是

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

为什么在此使用 JAXB 失败?

更新 01

好的@Simon 评论,我创建了一个示例对象(类)来获取请求和响应。 完全相同的效果。这是更新后的代码

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);
}

最佳答案

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

@XmlRootElement
public class MockupResponse {

private String name;
private Integer age;
private String car;
...
}

然后 XML 序列化工作。

在 Spring Doc 中阅读更多相关信息:

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>

关于xml - Spring Boot 找不到可接受的 XML 响应表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51876595/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com