温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎

发布时间:2021-09-29 15:58:39 来源:亿速云 阅读:180 作者:柒染 栏目:云计算

这篇文章将为大家详细讲解有关SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

SpringBoot同时支持多个视图解析器jsp+html+其他模版引擎!

有一个不算老的项目,经历过几波人迭代,源码维护的一塌糊涂。视图这一块,用的有 jsp,html,freemarker 等。视图不统一,导致启用 html 后,就不能访问 jsp 和 freemarker。这些具备互斥的因素,导致项目跑了 3 个,通过 Nginx 来适配。

今天,我给大家分享一种办法,让 SpringBoot 项目,同时支持多种模版引擎。

先说一下,这里没有新技术,新发明。只是根据 WebMvc 视图解析器的原理进行略微的改造。

我们都知道,在 SpringMVC 中有 3 个主要的类:DispatherServlet(前端控制器)、ViewResolver(视图解析器)、View(视图类)。

下面是一个简单的视图解析的流程。

SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎  

由图可知,如果我们要支持多个视图,就需要配置多个视图解析器。比如:ThymeleafViewResolver、InternalResourceViewResolver(系统默认实现)、ContentNegotiatingViewResolver、BeanNameViewResolver等。

DispatcherServlet 在选择视图解析器的时候,以优先级为处理原则,此优先级是根据该 ViewResolver 实现 Ordered 接口或者使用 @Order 注解赋值,数字最小优先级越高为原则。

然后对应视图解析器会返回一个具体的 View 类。最终通过3、4步骤渲染成 HTML 或者是 XML 等视图内容。

下图就是具体的排序方法,viewResolvers 是一个 List 集合。

SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎  

排完序后,匹配 View 对象的方法,遍历 viewResolvers,匹配到第一个 View 对象,则返回。

SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎  

因此,当配置多个视图,需要同时支持多个视图时,就会发生一些 404(当我们配置多个视图解析器时,出现只支持一种视图解析器器,其他类型产生 404)。

以 ThymeleafViewResolver 为例,在 ThymeleafAutoConfiguration 中,可以看到它的 Order 为 Ordered.LOWEST_PRECEDENCE - 5。

SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎  

而 SpringBoot 自动注入的 InternalResourceViewResolver 的优先级为最低级。

注意:这里指的是自动注入,就是在我们不经过任何改造的情况下,是属于最低级的。

SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎  
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/WEB-INF/");
    viewResolver.setSuffix(".jsp");
    viewResolver.setOrder(0);
    viewResolver.setContentType("text/html;charset=UTF-8");
    return viewResolver;
}
 

由于,匹配到一个 View 对象,就立即返回。导致你不管配置了多少个视图解析器,返回的 View 可能都不是正确的,这就导致了 404 的出现。

那么有没有可能动态的调整排序,或者动态的指定视图解析器就成了关键。好在,SpringMVC 给我们留下了口子。我们只需要间的重写一个 InternalResourceView 即可。

public class HandleResourceViewExists extends InternalResourceView {
    @Override
    public boolean checkResource(Locale locale) {
        File file = new File(this.getServletContext().getRealPath("/") + getUrl());
        //判断页面是否存在
        return file.exists(); 
    }
}
 

通过上面的代码,我们先检查一下对应的模版文件是否存在。然后通过下面的代码,动态的调整视图解析器。

@Bean
public InternalResourceViewResolver htmlViewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/");
    //设置检查器
    viewResolver.setViewClass(HandleResourceViewExists.class); 
    viewResolver.setSuffix(".html");
    viewResolver.setOrder(0);
    viewResolver.setContentType("text/html;charset=UTF-8");
    return viewResolver;
}

@Bean
public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    //设置检查器
    viewResolver.setViewClass(HandleResourceViewExists.class);
    viewResolver.setPrefix("/WEB-INF/");
    viewResolver.setSuffix(".jsp");
    viewResolver.setOrder(0);
    viewResolver.setContentType("text/html;charset=UTF-8");
    return viewResolver;
}
 

这里给大家提供了一个思路,如果通过调试代码,发现问题,解决问题。

关于SpringBoot能否同时支持多个视图解析器jsp+html+其他模版引擎就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI