0

所以,让我们有这个简单的控制器:

@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。

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

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

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

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

4

2 回答 2

0

也许这就是你想要的:

@RequestMapping(value = "/entities", method = RequestMethod.GET, headers = {"content-type=application/json"})
methodName() {
    ...
}
于 2013-12-08T09:56:09.120 回答
0

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

问题是我必须将生产子句放在每个控制器中的每个 @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>

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

于 2013-12-08T12:40:14.137 回答