Spring 自定义视图解析器

Spring custom view resolver

我尝试根据用户代理更改视图的前缀。

如果请求来自 IE,则尝试将其转发到 "legacy" 文件夹,否则将转发到 "modern" 文件夹。

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

它根本不起作用。谁能推荐一下?

不要在 ViewResolver 中胡乱写一个 HandlerInterceptor 来代替。

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

然后注册就像一个普通的拦截器。

@Configuration
public YourWebConfiguration extends WebMvcConfigurerAdapter {

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BrowserPrefixHandlerInterceptor());
    }
}

不要理会 ViewResolver。这将适用于每个 ViewResolver 而不仅仅是您自己的自定义版本。您可能想让拦截器更智能一些(检查是否确实存在 viewName 并且可能对某些 URL 跳过它)。