1

I'm writting custom handler interceptor in order to have multilangual url addresses. For example, when user accesses uri /de/auto the deutsch content will appear, when user accesses /en/car then english content will appear. I want both requests redirect to same controller and same method:

@Controller
public class MultiLangController {

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

        return "some content";
    }

and my interceptor is implemented like this (simplified version):

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;        
    }
}

Now when I access /en/car url in browser, correct page is returned (with message "some content") and logs shows that request passed through my interceptor. When I access /de/auto, 404 error is returned and according to logs request didn't make it to my interceptor. But why? Shouldn't request go through all interceptors till one of them stops it by returning false?

For clarity, I'm not using mvc:annotation-driven because it was hidding my custom interceptor. I've defined all 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"/> 

Thanks for answers!

Community
  • 1
  • 1
kurochenko
  • 1,214
  • 3
  • 19
  • 43

1 Answers1

5

It can't really send every single incoming request to the interceptors before determining if there's a mapping. Notice that one of the arguments to the interceptor is the Controller itself! If the URL that's coming in is one that's not mapped anywhere, how is it supposed to know what handler that would be to pass in as a method argument? URL rewriting needs to be done further up the stack, before the request hits the dispatcher servlet. E.G., in a servlet filter for that purpose.

Another possible option is to map your Controller this way

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

As long as you don't have other mappings of /something/car in the same dispatcher that will collide.

Affe
  • 47,174
  • 11
  • 83
  • 83