2013-12-07 60 views
0

所以,讓我們有這個簡單的控制器:春3.2.x中:跳過的406情況下,控制器方法不接受

@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,一切工作正常,aj兒子表示在具有200 Ok狀態的http響應中返回。

如果我發送一個GET請求accept=application/xml,則返回406。

我在第二種情況下的問題是,即使最終返回406,仍然調用getSomething()方法(我可以在日誌中看到)。雖然這對GET方法沒什麼大不了的,但它可能會導致POST方法混淆(資源被改變,但是返回406)。

有沒有簡單的方法告訴SpringMVC檢查accept標題並返回406 之前調用控制器方法?還是我必須開發一個自定義的http SpringMVC攔截器?

回答

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> 

(沒有測試的代碼,但它應該是大約右)

0

也許這是你想要什麼:

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

是,同樣可以使用實現'@RequestMapping (value =「/ entities」,method = RequestMethod.GET,產生=「application/json」)'。但問題是我必須將'produce'子句放在每個控制器中的每個'@ RequestMapping'中。我想在應用程序級別上設置它。 –