Spring Controller 不适用接受媒体类型

问题描述 投票:0回答:0

我的任务可不简单。非常遗留的项目(Spring 4.3、xml-configuration、web.xml 等) Spring Controller 只生成一种媒体类型(application/xml)。客户决定他还需要 application/json。毫无疑问,一些重构,添加必要的注释和魔术作品。在配置中添加了默认使用 application/xml 的说明。全部在本地测试,一切正常。 问题 - 客户有一个旧应用程序,它使用 org.springframework.web.client.RestTemplate,并且在没有任何标头的情况下使用它。惊喜!带有空标头的 RestTemplate,在发送请求之前添加默认标头。端点接收带有标头 Accept="application/octet-stream, application/json, application/*+json, /" 的 httprequest。客户收到 json 格式的对象(但等待 xml)。 决定 - 不太好,但原样 - 添加过滤器,它将检查 Accept 的标头,如果它包含不止一种媒体类型,则将其替换为 application/xml。过滤器工作正常,所有需要的标题都被替换了。调试器显示控制器已经接收到新的标头,但仍然继续在响应正文中返回 application/json。 怎么了?

config.xml

...
    <bean id="mvcContentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="favorParameter" value="true"/>
        <property name="mediaTypes">
            <value>
                xml=application/xml
                json=application/json
            </value>
        </property>
        <property name="defaultContentType" value="application/xml"/>
    </bean>
...

web.xml

...
    <filter>
        <filter-name>acceptFilter</filter-name>
        <filter-class>la.la.AcceptFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>acceptFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
...

AcceptFilter.java

...
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;

        String accept = req.getHeader("Accept");
        if (accept.split(",").length > 1) {
            MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(req);
            mutableRequest.putHeader("accept", "application/xml");
            mutableRequest.putHeader("Content-Type", "application/xml");
            ((HttpServletResponse) servletResponse).setHeader("Accept", "application/xml");
            ((HttpServletResponse) servletResponse).setHeader("Content-Type", "application/xml");
            servletResponse.setContentType("application/xml");
            filterChain.doFilter(mutableRequest, servletResponse);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    final class MutableHttpServletRequest extends HttpServletRequestWrapper {
...

LaLaController.java

...
    @RestController
    @RequestMapping(value = CONTROLLER_PATH,
        produces = {APPLICATION_XML_VALUE, APPLICATION_JSON_VALUE})
    public class LaLaController {

        @GetMapping("/firstEndpoint")
        public JustObject firstEndpoint() {
            return new JustObject("some information", "some details");
        }

...

请求示例:

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, byte[].class);
    byte[] body = responseEntity.getBody();

我试过拦截器,但也没有办法改变标题。我没有想法。如果在请求中设置接受 - 一切正常。 如果有人为我的问题提供更好的决定,我将不胜感激。

spring-mvc filter controller rest-client media-type
© www.soinside.com 2019 - 2024. All rights reserved.