Моё весеннее загрузочное приложение хочет использовать Webclient для выполнения http-запроса (XML тело запроса) и получает XML ответ. Поэтому я создал другое приложение с загрузочной пружиной с помощью jackson-dataformat- xml и создал конечную точку для получения и возврата 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 может быть без учета регистра.
Теперь в моем первом приложении я хочу использовать этот 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
Эту проблему можно решить, пометив MyXmlResponse с помощью XmlRootElement следующим образом
@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 структуры будут чрезвычайно сложными. Я хочу знать, правильно ли я это делаю.