繁体   English   中英

Spring 3.2.x:在“ 406不可接受”的情况下跳过控制器方法

[英]Spring 3.2.x: skip the controller method in case of 406 Not Acceptable

因此,让我们有一个简单的控制器:

@Controller
public class MyController {

    private static final Logger logger = LoggerFactory.getLogger(MyController.class);

    @RequestMapping(value="/entities", method = RequestMethod.GET)
    public @ResponseBody ResultPojo getSomething() {
        logger.info("getSometing");
        return new ResultPojo();
    }
}

...以及以下上下文片段:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        </bean> 
    </mvc:message-converters>
</mvc:annotation-driven>

这基本上意味着我希望除了返回结果bean的json表示形式之外,什么都不能返回,否则返回406。

如果我发送一个带有accept=application/json的GET请求,那么一切正常,在http响应中返回状态为200 Ok的json表示形式。

如果我发送带有accept=application/xml的GET请求,则返回406。

在第二种情况下,我的问题是,即使最终返回了406,仍然会调用getSomething()方法(我可以在日志中看到)。 虽然这对于GET方法来说没什么大不了的,但可能会导致POST方法混乱(资源已更改,但返回了406)。

有没有一种简单的方法可以告诉SpringMVC 调用controller方法之前检查accept头并返回406? 还是我必须开发一个自定义的http SpringMVC拦截器?

也许这就是您想要的:

@RequestMapping(value = "/entities", method = RequestMethod.GET, headers = {"content-type=application/json"})
methodName() {
    ...
}

有没有一种简单的方法可以告诉SpringMVC在调用controller方法之前检查accept头并返回406? 还是我必须开发一个自定义的http SpringMVC拦截器?

问题是我必须将Produces子句放到每个控制器中的每个@RequestMapping中。 我想在应用程序级别进行设置。

据我所知,SpringMVC没有更简单的方法。 但是,使用标准JEE过滤器也不是很难。 只需执行以下操作:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class YourFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        if (request.getRequestHeader("Accept").contains("application/json")) {
            chain.doFilter(req, res);
        } else {
            ((HttpServletResponse)response).setStatus(SC_NOT_ACCEPTABLE);
        }
    }
    public void init(FilterConfig config) throws ServletException {
         // any startup stuff here if needed
    }
    public void destroy() {
        // add code to release any resource
    }
}

和:

<filter>
    <filter-name>YourFilter</filter-name>
    <filter-class>
        path.to.YourFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>YourFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

(没有测试代码,但是应该是正确的)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM