[英]How do you configure spring boot 2 to return xml by default?
首先,我读过这个:
Spring 启动 - 如果请求中不存在,则设置默认内容类型 header
旧版本在 spring 启动 1 上工作。但是,当接收到以下请求时,接受 header Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
响应在 json 中。
我放了一个 class
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(
ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_XML);
}
}
我可以看到正在设置 defaultContentType 策略。 但是它被 AcceptHeaderConfig 策略覆盖。
看起来 defaultContentType 仅用作后备。
请注意,spring 引导 1 中的相同代码有效并且默认为 XML。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.annotation.XmlRootElement;
@SpringBootApplication
@RestController
public class CnApp {
@RequestMapping("/")
public Person person(HttpServletRequest request, ModelMap model){
return new Person();
}
public static void main(String[] args) throws Exception {
SpringApplication.run(CnApp.class, args);
}
@XmlRootElement
public static class Person {
public String firstName = "Jon";
public String lastName = "Doe";
}
@Configuration
public static class ServerConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_XML);
}
}
}
正如您通过运行curl localhost:8080 -H"Accept: text/html, image/gif, image/jpg;q=0.2, */*;q=0.2"
它默认为 json 即使 Z33061BB093D9B363
从我在下面发布的评论中
问题在于旧版本的 spring 我们可以发送接受 header 并获取默认为 XML 的请求。 但是 JSON 仍然受支持。
因此,当接受 header 进来,它同时支持 JSON 和 XML 时,我们需要返回 Z350867093D9BCFED100867B093D3501BB093D363810B671059B9CFED3F8Z。
您的WebMvc
配置与您配置的一样正常工作。
如果没有Accept
header 存在,则使用默认ContentType
。
要到达您的 scope,您必须使用内容协商策略打开 go,并禁用接受 header。 您的configureContentNegotiation
方法应如下所示:
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false)
.parameterName("mediaType")
.ignoreAcceptHeader(true)
.useJaf(false)
.defaultContentType(MediaType.APPLICATION_XML)
.mediaType("xml", MediaType.APPLICATION_XML;
}
对此进行进一步调查。 @thepaoloboi 在他的回答中建议的是正确的 defaultMessageConverter 只有在没有发生其他形式的内容协商时才会发生。
为了解决这个问题,我逐步完成了org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor
使用的代码,我看到它依赖于已配置的转换程序的顺序。
因此,作为 hack,以下内容在 spring 1 和 spring 2 中都有效。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2CollectionHttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@SpringBootApplication
@RestController
public class CnApp {
@RequestMapping("/")
public Person person(HttpServletRequest request, ModelMap model){
return new Person();
}
public static void main(String[] args) throws Exception {
SpringApplication.run(CnApp.class, args);
}
@XmlRootElement
public static class Person {
public String firstName = "Jon";
public String lastName = "Doe";
}
@Configuration
public static class ServerConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_XML);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, new Jaxb2CollectionHttpMessageConverter<>());
converters.add(0, new Jaxb2RootElementHttpMessageConverter());
System.out.println("Converters:" + converters);
}
}
}
其工作原理是设置 Jaxb2 转换器的优先级高于 jackson 转换器。
这可以测试如下
curl localhost:8080 -H"Accept: text/html, image/gif, image/jpg;q=0.2, */*;q=0.2"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><firstName>Jon</firstName><lastName>Doe</lastName></person>%
curl localhost:8080 -H"Accept: text/html, image/gif, image/jpg;q=0.2, application/json, */*;q=0.2"
{"firstName":"Jon","lastName":"Doe"}%
请注意,如果 application/json 在 header 中的任何位置指定,这仍然是首选。
这仍然感觉像是一种 hack,如果有一种方法可以对首选的 mime 类型进行排序而不求助于添加或重新排序转换器,那就太好了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.