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

kur*_*nko 1 java url multilingual spring interceptor

我正在编写自定义处理程序拦截器以获得多语言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";
    }
Run Code Online (Sandbox Code Playgroud)

我的拦截器是这样实现的(简化版):

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;        
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当我/en/car在浏览器中访问url时,返回正确的页面(带有"some content"消息),日志显示请求通过我的拦截器传递.当我访问时/de/auto,返回404错误并根据日志请求没有进入我的拦截器.但为什么?不应该请求通过所有拦截器,直到其中一个拦截器通过返回false来阻止它?

为清楚起见,我没有使用,mvc:annotation-driven因为它隐藏了我的自定义拦截器.我已经定义了所有的手段

<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"/> 
Run Code Online (Sandbox Code Playgroud)

谢谢你的回答!

Aff*_*ffe 5

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

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

@RequestMapping(value="/{languageCode}/car", method = RequestMethod.GET)
Run Code Online (Sandbox Code Playgroud)

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