Spring 3 HandlerInterceptorAdapter。请求以404之前的拦截器结束

时间:2011-07-26 17:54:00

标签: java spring url interceptor multilingual

我正在编写自定义处理程序拦截器以获得多语言URL地址。例如,当用户访问uri /de/auto时,将显示deutsch内容,当用户访问/en/car时,将显示英语内容。我希望两个请求都重定向到同一个控制器和相同的方法:

@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 url时,返回正确的页面(带有“some content”消息),日志显示请求通过我的拦截器传递。当我访问/de/auto时,会返回404错误,并且根据日志请求未将其发送到我的拦截器。 但为什么呢?不应该请求通过所有拦截器,直到其中一个拦截器通过返回false来阻止它?

为清楚起见,我没有使用mvc:annotation-driven,因为它是hidding my custom interceptor。我已经定义了所有manualy

<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"/> 

感谢您的回答!

1 个答案:

答案 0 :(得分:5)

在确定是否存在映射之前,它无法真正将每个传入请求发送到拦截器。请注意,拦截器的一个参数是Controller本身!如果进入的URL是未映射到任何地方的URL,那么它应该如何知道将作为方法参数传入的处理程序?在请求到达调度程序servlet之前,需要在堆栈中进一步完成URL重写。 E.G.,在servlet filter for that purpose

另一种可能的选择是以这种方式映射您的控制器

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

只要您在同一个调度程序中没有/ something / car的其他映射就会发生冲突。