SpringBoot系列之集成jsp模板引擎

1、模板引擎简介

引用百度百科的模板引擎解释:

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

在JavaEE领域有几中比较常用的模板引擎,分别是Jsp、Velocity、Freemarker、Thymeleaf,不过对于前端页面渲染效率来说,jsp其实还是最快的,Velocity次之。Thymeleaf虽然渲染效率不是很快,但是语法方面是比较轻巧的,Thymeleaf语法比Velocity轻巧,但是渲染效率不如Velocity

2、环境准备

ok,Springboot是一款javaee框架,使用非常简捷,创建工程也是默认打成jar包的,启动jar包就可以直接运行嵌入式的Servlet容器,比如Tomcat等等,不过Springboot要集成模板引擎的话,是默认不支持jsp的,但是并不表示不能使用,首先Springboot项目默认是jar方式运行的,而我们之前的jsp项目大部分都是war包方式,jar方式打包的项目默认就没有webapp等等这些文件,所以我们要创建jsp项目,就可以创建工程时候改成war包形式

ok,进行jsp实验,环境准备:

  • 版本:

    • Maven3.9+
    • SpringBoot2.2.1
  • IDE:
    • IntelliJ IDEA

创建Springboot Initializer项目,打包方式选择war方式

创建好的项目,默认是没有webapp文件的,所以我们可以手动加上,或者在idea这样做:



新增web.xml,记得改下默认路径



创建好之后,我们可以看看自动生成的项目有什么特征:

  • 首先是多了一个ServletInitializer类,这个类是干什么的?后面再详讲

  • Pom文件,翻了一下,发现spring-boot-starter-tomcat的作用范围被改成provided的,这个是什么意思?需要补充一下maven的基础知识,maven中三种classpath 编译,测试,运行
    • 1.compile:默认范围,编译测试运行都有效
    • 2.provided:在编译和测试时有效
    • 3.runtime:在测试和运行时有效
    • 4.test:只在测试时有效
    • 5.system:在编译和测试时有效,与本机系统关联,可移植性差

      修改scope为provided,也就是在运行时不起效,也就是打成war包时候,就不引入对应的Tomcat jar包,不使用嵌入式的Tomcat容器,使用外部的Tomcat容器

3、外部Servlet容器

Springboot项目创建之后,其实就可以直接创建jsp应用了,然后从其自动生成的配置可以看出我们在创建war包时,是可以使用外部的Tomcat容器的,所以,我们引入一下外部Tomcat



部署时候,直接使用暴露的war即可,Application context可以写上也可以不管



直接创建一个jsp页面



进行页面跳转,写个Controller类:

@Controller
public class HelloController { @RequestMapping(value = {"/success"})
public String toSuccess(){
return "success";
}
}

注意:还要向以前那样定义一下mvc的一下配置:

spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp

ok,我之前博客SpringBoot源码学习系列之嵌入式Servlet容器已经比较详细地介绍了Springboot嵌入式Servlet容器的知识,所以本博客有必要对比一下嵌入式的Servlet容器和本博客介绍的外部Servlet容器的区别

  • 外部Servlet容器:maven打包是war形式,先启动Servlet容器,在创建ioc容器
  • 嵌入式Servlet容器:maven打包是jar形式,启动时候先创建ioc容器,再启动嵌入式的Servlet容器,比如Tomcat、undertow等等

4、源码原理简介

尚硅谷视频介绍过Servlet的规范,翻下文档,找到如图章节,这个章节介绍了创建war包项目时候会自动创建ServletInitializer类,主要介绍共享库和运行时插件,里面介绍了ServletContainerInitializer,也就是Servlet容器的一个初始化类的使用,启动时候会通过配置在META-INF/services的文件找对应类,通过@HandlesTypes注解在启动时候将需要的类引进来



全局搜索,在Spring-web项目找到对应配置

@HandlesTypes(WebApplicationInitializer.class)//SpringServletContainerInitializer 容器类启动时候会一起创建WebApplicationInitializer类
public class SpringServletContainerInitializer implements ServletContainerInitializer { @Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<>(); if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
//检验WebApplicationInitializer不是一个接口、抽象类就进行实例
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer)
ReflectionUtils.accessibleConstructor(waiClass).newInstance());
}
catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
} if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
} servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
//遍历获取到的WebApplicationInitializer 类,调用其对应的onStartup方法
for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
} }

WebApplicationInitializer 其实就是一个接口类,所以打开其实现类,可以看到SpringBootServletInitializer类



SpringBootServletInitializer类implements WebApplicationInitializer接口,所以在Servlet容器启动时候也会被创建,同时执行onStartup方法,如图,找关键点:



createRootApplicationContext方法是创建根据的容器,看看源码:

protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
//创建SpringApplication的构建器
SpringApplicationBuilder builder = createSpringApplicationBuilder();
builder.main(getClass());//设置main方法
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
//构建器初始化
builder.initializers(new ParentContextApplicationContextInitializer(parent));
}
builder.initializers(new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);
//关键点,调用configure方法
builder = configure(builder);
builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext));
SpringApplication application = builder.build();
if (application.getAllSources().isEmpty()
&& MergedAnnotations.from(getClass(), SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class)) {
application.addPrimarySources(Collections.singleton(getClass()));
}
Assert.state(!application.getAllSources().isEmpty(),
"No SpringApplication sources have been defined. Either override the "
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered
if (this.registerErrorPageFilter) {
application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
}
//启动Application类
return run(application);
}

从这个源码找到关键点configure方法,继续跟一下这个方法,基类的方法很简单,只是返回构造器



所以,在idea里ctrl+alt+B打开其实现方法,如图看到关键点,这个不就是自动创建的ServletInitializer类?而且重写了configure方法,而且将Springboot的Application类传给构造器类,所以跟到这里就明白了,为什么Servlet容器启动时候就会触发Springboot的ioc容器创建

代码例子下载:github下载链接

SpringBoot系列之集成jsp模板引擎的更多相关文章

  1. springboot系列四、配置模板引擎、配置热部署

    一.配置模板引擎 在之前所见到的信息显示发现都是以 Rest 风格进行显示,但是很明显在实际的开发之中,所有数据的显示最终都应该交由页面完成,但是这个页面并不是*.jsp 页面,而是普通的*.html ...

  2. springboot同时使用thymeleaf和jsp模板

    语言:javaEE 框架:springboot+thymeleaf.jsp模板引擎 背景:学习springboot过程中想同时使用thymeleaf和jsp访问(官方不建议) 步骤: 1)  在pom ...

  3. SpringBoot系列之集成Druid配置数据源监控

    SpringBoot系列之集成Druid配置数据源监控 继上一篇博客SpringBoot系列之JDBC数据访问之后,本博客再介绍数据库连接池框架Druid的使用 实验环境准备: Maven Intel ...

  4. SpringBoot系列之集成Mybatis教程

    SpringBoot系列之集成Mybatis教程 环境准备:IDEA + maven 本博客通过例子的方式,介绍Springboot集成Mybatis的两种方法,一种是通过注解实现,一种是通过xml的 ...

  5. SpringBoot系列之集成logback实现日志打印(篇二)

    SpringBoot系列之集成logback实现日志打印(篇二) 基于上篇博客SpringBoot系列之集成logback实现日志打印(篇一)之后,再写一篇博客进行补充 logback是一款开源的日志 ...

  6. SpringBoot系列之集成Dubbo的方式

    SpringBoot系列之集成Dubbo的方式 本博客介绍Springboot框架集成Dubbo实现微服务的3种常用方式,对于Dubbo知识不是很熟悉的,请先学习我上一篇博客:SpringBoot系列 ...

  7. 九、SpringBoot集成Thymeleaf模板引擎

    Thymeleaf咋读!??? 呵呵,是不是一脸懵逼...哥用我的大学四级英文知识告诉你吧:[θaimlif]. 啥玩意?不会音标?...那你就这样叫它吧:“赛母李府”,大部分中国人是听不出破绽的.. ...

  8. SpringBoot集成Thymeleaf模板引擎

    简单介绍 目前在JavaEE领域有几中比较常用的模板引擎,分别是Jsp.Velocity.Freemarker.Thymeleaf,对Freemark语法不是特别熟悉,不过对于前端页面渲染效率来说,j ...

  9. SpringBoot系列之集成Thymeleaf用法手册

    目录 1.模板引擎 2.Thymeleaf简介 2.1).Thymeleaf定义 2.2).适用模板 3.重要知识点 3.1).th:text和th:utext 3.2).标准表达式 3.3).Thy ...

随机推荐

  1. es ik 分词 5.x后,设置默认分词

    1.使用模板方式,设置默认分词 注: 设置模板,需要重新导入数据,才生效 通过模板设置全局默认分词器 curl -XDELETE http://localhost:9200/_template/rtf ...

  2. 爬虫学习--Day3(小猿圈爬虫开发_1)

    爬虫基础简介 前戏: 1.你是否在夜深人静的时候,想看一些让你更睡不着的图片 2.你是否在考试或者面试前夕,想看一些具有针对性的题目和面试题 3.你是否想在杂乱的网络世界中获取你想要的数据 什么是爬虫 ...

  3. JAVA项目打包成可运行的exe程序

    前言:本篇文章为原创,转载请注明地址,谢谢. 我们一些时候,可能需要需要把我们完成的java打包,打成jar文件或者exe文件.这时候就请鄙人的这篇文章. 言尽于此,Let‘s go! 一.导出jar ...

  4. 二叉搜索树BST(C语言实现可用)

    1:概述 搜索树是一种可以进行插入,搜索,删除等操作的数据结构,可以用作字典或优先级队列.二叉搜索树是最简单的搜索树.其左子树的键值<=根节点的键值,右子树的键值>=根节点的键值. 如果共 ...

  5. cocos creator 3D | 蚂蚁庄园运动会星星球

    上一篇文章写了一个简易版的蚂蚁庄园登山赛,有小伙伴留言说想要看星星球的,那么就写起来吧! 效果预览 配置环境 cocos creator 3d 1.0.0 小球点击 3d里节点无法用 cc.Node. ...

  6. [Error]Archive for required library: 'C:/Users/fk/.m2/repository/com/sun/xml/bind/jaxb-core/2.2.7/jaxb-core-2.2.7.jar'

    Eclipse报错: Description Resource Path Location Type Archive for required library: 'C:/Users/fk/.m2/re ...

  7. nyoj 72-Financial Management (求和 ÷ 12.0)

    72-Financial Management 内存限制:64MB 时间限制:3000ms 特判: No 通过数:7 提交数:12 难度:1 题目描述: Larry graduated this ye ...

  8. JVM浅谈

    **前言** 由于先前也遇到过一些性能问题,OOM算是其中的一大类了.因此也对jvm产生了一些兴趣.自己对jvm略做了些研究.后续继续补充. **从oom引申出去** 既然说到oom,首先需要知道oo ...

  9. 结合Spring Security进行web应用会话安全管理

    在本文中,将为大家说明如何结合Spring Security 和Spring Session管理web应用的会话. 一.Spring Security创建使用session的方法 Spring Sec ...

  10. 领扣(LeetCode)各位相加 个人题解

    给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2. 由于 2 是一位数,所 ...