2011-07-26 79 views
1

我正在寫自定義處理程序攔截器,以便有多語言URL地址。例如,當用戶訪問uri /de/auto時,會出現deutsch內容,當用戶訪問/en/car時,將顯示英文內容。我想這兩個請求重定向到同一個控制器和相同的方法:Spring 3 HandlerInterceptorAdapter。請求結束404前調用攔截器

@Controller 
public class MultiLangController { 

    @RequestMapping(value="/en/car", method = RequestMethod.GET) 
    public @ResponseBody String writePage() { 

     return "some content"; 
    } 

和我的攔截器像這樣(簡體版)實施:

public class MultiLangInterceptor extends HandlerInterceptorAdapter { 

    @Override 
    public boolean preHandle(HttpServletRequest request, 
    HttpServletResponse response, Object handler) throws Exception { 

     String requestUrl = request.getRequestURI().substring(request.getContextPath().length()); 

     if ("/de/auto".equals(requestUrl)) { 
      String redirect = request.getContextPath() + "/en/car"; 

      response.sendRedirect(redirect); 
      return false; 
     } 
     return true;   
    } 
} 

現在,當我在瀏覽器中訪問/en/car網址,正確的頁面返回(消息「一些內容」)和日誌顯示請求通過我的攔截器。當我訪問/de/auto時,會返回404錯誤,並根據日誌請求未將其發送給我的攔截器。 但是爲什麼?不應該請求通過所有攔截器,直到其中一個攔截器返回false爲止?

爲了清楚起見,我沒有使用mvc:annotation-driven,因爲它是hidding my custom interceptor。我已經定義所有手冊

<bean id="handlerMapping" 
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="interceptors"> 
     <ref bean="multiLangInterceptor" /> 
    </property> 
</bean> 

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="messageConverters"> 
     <list> 
      <ref bean="jacksonMessageConverter"/> 
      <ref bean="stringHttpMessageConverter"/> 
     </list> 
    </property> 
</bean> 

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> 

<bean id="multiLangInterceptor" class="example.MultiLangInterceptor" />  

<bean id="stringHttpMessageConverter" 
    class="org.springframework.http.converter.StringHttpMessageConverter"/> 

感謝您的答案!

回答

5

在確定是否存在映射之前,它不能真正將每個傳入請求發送到攔截器。注意攔截器的一個參數是Controller本身!如果進入的URL是未映射到任何地方的URL,它應該如何知道將作爲方法參數傳入的處理程序?在請求到達調度程序servlet之前,需要在堆棧中進一步完成URL重寫。 E.G.,在servlet filter for that purpose

另一個可能的選擇是映射您的控制器這樣

@RequestMapping(value="/{languageCode}/car", method = RequestMethod.GET) 

只要你沒有在同一個調度程序,將碰撞/事/車的其他映射。