Search code examples
springspring-mvcspring-annotations

Spring custom view resolver


I've tried to change the prefix of the view based on the useragent.

If the request comes from IE then trying to forward it to "legacy" folder otherwise "modern" folder.

@Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setViewClass(JstlView.class);
        internalResourceViewResolver.setSuffix(".jsp");

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        if(request.getHeader("User-Agent").contains("Internet Explorer")){
                    internalResourceViewResolver.setPrefix("/WEB-INF/views/legacy/");
        } else {
                    internalResourceViewResolver.setPrefix("/WEB-INF/views/modern/");
        }
        return internalResourceViewResolver;
    }

Its not at all working. Can anyone suggest?


Solution

  • Don't hack around in the ViewResolver write a HandlerInterceptor instead.

    public class BrowserPrefixHandlerInterceptor extends HandlerInterceptorAdapter {
    
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
    
            if(request.getHeader("User-Agent").contains("Internet Explorer")){
               modelAndView.setViewName("legacy/" + modelAndView.getViewName());
           } else {
               modelAndView.setViewName("modern/" + modelAndView.getViewName());
           }
        }
    }
    

    Then register is like a regular interceptor.

    @Configuration
    public YourWebConfiguration extends WebMvcConfigurerAdapter {
    
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new BrowserPrefixHandlerInterceptor());
        }
    }
    

    Just leave the ViewResolver alone. This will work for each ViewResolver and not just for your own customized version. You might want to make the interceptor a little smarter (check if there is actually a viewName and maybe skip it for certain URLs).