Spring Boot Webflux 不能 return application/xml
SpringBoot Webflux cannot return application/xml
在我的反应式 REST API 中,我正在尝试 return 一个 XML
响应。但是,我总是得到一个JSON
,即406 NOT_ACCEPTABLE
。知道为什么吗?
@RestController
@RequestMapping(path = "/xml", produces = APPLICATION_XML_VALUE)
public class RestApi {
@GetMapping(path = "/get")
public Publisher<ResponseEntity> get() {
return Mono.just(ResponseEntity.ok().contentType(APPLICATION_XML).body(new Datta("test")));
}
@PostMapping(path = "/post", consumes = APPLICATION_XML_VALUE)
public Publisher<ResponseEntity<Datta>> post(@RequestBody Datta datus) {
datus.setTitle(datus.getTitle() + "!");
return Mono.just(ResponseEntity.ok().contentType(APPLICATION_XML).body(datus));
}
}
java.lang.AssertionError:
Expected :application/xml
Actual :application/json;charset=UTF-8
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id "io.spring.dependency-management" version "1.0.7.RELEASE"
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
这些是我的 REST controller and a unit test 的链接。谢谢!
显然,jackson-dataformat-xml
does not yet 支持 WebFlux 中的 XML 编组。至于现在我看到两种可能性:
- 在类路径中添加
org.springframework.boot:spring-boot-starter-web
(应该有starter-web和starter-webflux)。但是,这仅适用于 Servlet 3.1 运行时(例如 Tomcat)。
- 或者,如果您想要一个完全成熟的反应式 Web 服务器(例如 Netty)use xml 从 JAXB 编组(
Jaxb2XmlEncoder
和 Jaxb2XmlDecoder
):
build.gradle:
sourceCompatibility = '11'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Java 11 removed these Java EE modules
implementation "javax.xml.bind:jaxb-api:2.3.1"
implementation "com.sun.xml.bind:jaxb-core:2.3.0.1"
implementation "com.sun.xml.bind:jaxb-impl:2.3.2"
compileOnly "org.projectlombok:lombok"
annotationProcessor "org.projectlombok:lombok"
}
POJO:
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement
public class Datta {
private String title;
}
注意 3 个 javax.xml.bind
依赖项(Java 8
不需要这些)和 @XmlRootElement
注释。此解决方案立即生效,但如果您想要进一步自定义,请实施您自己的 WebFluxConfigurer
:
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.registerDefaults(false);
configurer.customCodecs().decoder(new Jaxb2XmlDecoder()); // <- here
configurer.customCodecs().encoder(new Jaxb2XmlEncoder()); // <- here
}
}
Here是源代码的link。
在我的反应式 REST API 中,我正在尝试 return 一个 XML
响应。但是,我总是得到一个JSON
,即406 NOT_ACCEPTABLE
。知道为什么吗?
@RestController
@RequestMapping(path = "/xml", produces = APPLICATION_XML_VALUE)
public class RestApi {
@GetMapping(path = "/get")
public Publisher<ResponseEntity> get() {
return Mono.just(ResponseEntity.ok().contentType(APPLICATION_XML).body(new Datta("test")));
}
@PostMapping(path = "/post", consumes = APPLICATION_XML_VALUE)
public Publisher<ResponseEntity<Datta>> post(@RequestBody Datta datus) {
datus.setTitle(datus.getTitle() + "!");
return Mono.just(ResponseEntity.ok().contentType(APPLICATION_XML).body(datus));
}
}
java.lang.AssertionError: Expected :application/xml Actual :application/json;charset=UTF-8
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id "io.spring.dependency-management" version "1.0.7.RELEASE"
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
这些是我的 REST controller and a unit test 的链接。谢谢!
显然,jackson-dataformat-xml
does not yet 支持 WebFlux 中的 XML 编组。至于现在我看到两种可能性:
- 在类路径中添加
org.springframework.boot:spring-boot-starter-web
(应该有starter-web和starter-webflux)。但是,这仅适用于 Servlet 3.1 运行时(例如 Tomcat)。 - 或者,如果您想要一个完全成熟的反应式 Web 服务器(例如 Netty)use xml 从 JAXB 编组(
Jaxb2XmlEncoder
和Jaxb2XmlDecoder
):
build.gradle:
sourceCompatibility = '11'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Java 11 removed these Java EE modules
implementation "javax.xml.bind:jaxb-api:2.3.1"
implementation "com.sun.xml.bind:jaxb-core:2.3.0.1"
implementation "com.sun.xml.bind:jaxb-impl:2.3.2"
compileOnly "org.projectlombok:lombok"
annotationProcessor "org.projectlombok:lombok"
}
POJO:
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement
public class Datta {
private String title;
}
注意 3 个 javax.xml.bind
依赖项(Java 8
不需要这些)和 @XmlRootElement
注释。此解决方案立即生效,但如果您想要进一步自定义,请实施您自己的 WebFluxConfigurer
:
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.registerDefaults(false);
configurer.customCodecs().decoder(new Jaxb2XmlDecoder()); // <- here
configurer.customCodecs().encoder(new Jaxb2XmlEncoder()); // <- here
}
}
Here是源代码的link。