spring-boot - Spring Boot Web 客户端 XML
问题描述
我的 Spring Boot 应用程序想要使用 Webclient 发出 http 请求(XML 请求正文)并接收 XML 响应。因此,我使用 jackson-dataformat-xml 创建了另一个 Spring Boot 应用程序,并创建了一个端点来接收和返回 XML,如下所示。
spring-boot-version=2.2.5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
@PostMapping(value = "/api",
consumes = MediaType.APPLICATION_XML_VALUE,
produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<MyXmlResponse> trip(@RequestBody MyXmlRequest request) throws Exception {
MyXmlResponse response = new MyXmlResponse();
response.setStatus("SUCCESS");
response.setTripID(request.getTripID());
return ResponseEntity.ok().body(response);
}
它工作完美,显然不需要 JaxB 注释,因为我使用 jackson-dataformat-xml。此外,请求 XML 可以不区分大小写。
现在,在我的第一个应用程序中,我想通过 webclient 使用这个 API。我读到 Spring webflux 还不支持 Jackson-dataformat-xml。因此,我必须使用 Jaxb 注释来注释我的类。
spring-boot-version=2.2.5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
webClient.post()
.uri(URI.create("url-to-api-endpoint"))
.body(Mono.just(myXmlRequest), MyXmlRequest.class)
.exchange()
.doOnSuccess(response -> {
HttpStatus statusCode = response.statusCode();
log.info("Status code of external system request {}", statusCode);
})
.doOnError(onError -> {
log.error("Error on connecting to external system {}", onError.getMessage());
})
.flatMap(response -> response.bodyToMono(MyXmlResponse.class))
.subscribe(this::handleResponse);
上面的代码抛出异常如下
org.springframework.webreactive.function.UnsupportedMediaTypeException: Content type 'application/xml' not supported for bodyType=com.example.MyXmlRequest
at org.springframework.web.reactive.function.BodyInserters.unsupportedError(BodyInserters.java:391)
我通过使用 XmlRootElement 进行如下注释来解决此问题
@Getter @Setter @NoArgsConstructor @ToString
@XmlRootElement()
public class MyXmlRequest {
private String attribute1;
}
在下一次尝试中,我遇到了另一个错误,如下所示
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/xml' not supported for bodyType=com.example.MyXmlResponse
Caused by: org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/xml' not supported for bodyType=com.example.MyXmlResponse
这可以通过使用 XmlRootElement 注释 MyXmlResponse 来解决,如下所示
@Getter @Setter @NoArgsConstructor @ToString
@XmlRootElement()
public class MyXmlResponse {
private String attr1;
private String attr2;
}
这次我得到 unmarshallexception 如下
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.core.codec.DecodingException: Could not unmarshal XML to class com.example.MyXmlResponse; nested exception is javax.xml.bind.UnmarshalException
- with linked exception:
[com.sun.istack.internal.SAXParseException2; lineNumber: 1; columnNumber: 15; unexpected element (uri:"", local:"MyXmlResponse"). Expected elements are <{}myXmlResponse>]
Caused by: org.springframework.core.codec.DecodingException: Could not unmarshal XML to class com.example.MyXmlResponse; nested exception is javax.xml.bind.UnmarshalException
- with linked exception:
我使用传递给注释的附加属性来修复它,如下所示。
@XmlRootElement(name = "MyXmlResponse", namespace = "")
public class MyXmlResponse {
将来,我的 XML 结构将变得非常复杂。我想知道我的做法是否正确。
解决方案
推荐阅读
- javascript - 在条形下方移动 Google 图表(条形)中的数据标签
- excel - Power Query - 根据前一行更新列
- python - 无法读取 Raspberry Pi UART 引脚
- excel - 创建一个 VBA 程序,将执行两个十六进制数的加法或减法
- typescript - 如何在强制执行值时将对象的键提取到类型?
- swift - 限制 UITextVIew 中允许的字符数量时出现 Xcode 错误
- arrays - 遍历数组时无法输入If语句
- sql - 从 SQL Server 中的 JSON 文本中提取值
- c - 关于 C 中整数和浮点运算的新手问题
- python - UpdateView 中的查询集不匹配