SpringBoot的web开发

       前言

        使用SpringBoot默认是不支持jsp、html网页解析的,如果需要开发web项目就必须导入thymeleaf模板依赖


thymeleaf模板技术
  • 引入 thymeleaf

    <!--START 引入 thymeleaf 的依赖 START-->
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
     </dependency>

注 注:如果上述引入 thymeleaf 依赖报错,就删除上面依赖引入下面的依赖。

<!-- START=== 引入 thymeleaf 依赖 ===START-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>

必须引入以下JAR包依赖如果缺少的话,可能无法识别jsp、html等页面导致查找不到返回的视图
upload successful
upload successful

  • 使用 thymeleaf 作为视图

    SpringBoot 项目默认的thymeleaf视图解析器通过ThymeleafProperties 属性文件中的源码。

upload successful

  • 配置自定义thymeleaf视图解析器

    • 在application.properties配置文件中添加配置

      spring.thymeleaf.prefix=classpath:html/
      spring.thymeleaf.suffix=.html
      //jsp如下
      spring.thymeleaf.prefix=classpath:jsp/
        spring.thymeleaf.suffix=.jsp
    • 在Controller控制器中添加代码

      @RequestMapping(“/success”)

      public String success(Model model) {
          model.addAttribute("name", " 这是一个网页");
          return "success";
      }

upload successful

  • Thymeleaf使用& 语法

    • 导入 Thymeleaf 的名称空间。

      <html lang="en" xmlns:th="http://www.thymeleaf.org">
    • 使用 thymeleaf 的语法,在页面上面输出在 Controller 中保存到作用域中的值。

      <!DOCTYPE html>
      <html lang="en" xmlns:th="http://www.thymeleaf.org">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
         运行成功${name}
         <br />
         第一种取值方法:<p th:text="${name}"></p>
         第二种取值方法:[[${name}]]
         跳转路径拼接参数:<a th:href="@{/index/emp/}+${emp.id}"/>
          在HTML上获取session参数[[${session.loginUser.name}]]
      </body>
      </html>

      upload successful

      使用thymeleaf模板分页

      upload successful

    • 使用thymeleaf语法在当前页面引入其他标签

      如果很多页面中出现一些重复的标签如导航条、下拉框等等一些重复的标签可以使用thymeleaf语法中的一些引入标签解决重复多余的标签使用。类似于JSP中的jsp:include,<% include=""%>

      1.抽取需要的公共片段。

      upload successful

      2.引入bar.html中的公共片段(thymeleaf中有三种用法:)

      <div th:insert="~{common/bar :: 片段名/ID名}"></div>

      <div th:include="~{common/bar :: 片段名/ID名}"></div>

      <div th:replace="~{common/bar :: 片段名/ID名}"></div>

  • 常用的 th 标签如下
标签 说明
th:insert/th:replace Html 代码片段包含,类似于 jsp:include
th:each 遍历,类似于c:forEach
th:if/th:swtich 条件判断:类似于 c:if
th:case/th:object/th:with 声明变量,类似于 c:set
th:value/th:href/th:src 修改指定的属性默认值,如th:href修改a标签中的href属性。
ht:src 修改 script 中的 src 属性。
th:text/th:utext 修改标签体的内容,th:text 是 会进行转义字符串,如<th:text=”${name}”/>如果取出的值中的<h1>标签,那么在页面上展示的效果是<h1>,utext 才会解析成一级标题
th:fragment 声明 HTML 代码片段。
  • 表达式 Simple expressions( 表达式语法 )
表达式 说明
Variable Expressions: ${…} 获取变量值,
Selection Variable Expressions: *{…} 选择表达式,和${}功能是一样。
Link URL Expressions: @{…} 定义 URL 链接。如<a href="#"th:href="@{/order/details(orderId=${o.id})}">view</a>
Message Expressions: #{…} 获取国际化内容。
Fragment Expressions: ~{…} 片段引用表达式,如<div th:insert="~{commons :: main}">...</div>
数学运算 and,or ! , not
比较运算 >,<,>=,<= ( gt, lt, ge, le ) ==, != , ( eq, ne )
条件运算( 三元运算) (if) ? (then)(if) ? (then) : (else)(value) ?: (defaultvalue)
  • SpringBoot的静态资源访问映射规则

    在 Spring Boot 项目中关于 Spring 的 所有配置都是在 WebMvcAutoConfiguration 类中。我们到 WebMvcAutoConfiguation.java 类中找到 addResourceHandlers 方法即 添加资源处理。

upload successful

上面可以看到一个webjars的格式路径。我们可以在项目中使用 webjars 引入前端框架中的静态资源

关于/webjars/**的所有请求都会去 classpath:/META-INF/resources/webjars/ 找资源。

(SpringBoot 项目是以 jar 包的方式引入静态资源;)

网站:https://www.webjars.org/ 将我们常用的前端框架,如 如 jQuery 、Bootstrap 前端框以 架会以 Maven 依赖的方式供 SpringBoot 项目进行使用。

  • 实现对自己定义的静态资源进行访问
    使用Ctrl+shift+R搜索WebMvcAutoConfiguration.java找到addResourceHandlers方法

//方法中的部分代码

String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)                        .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))                        .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));}

上述代码中,registry.addResourceHandler(new String[]{staticPathPattern})的意思是添加资源映射,staticPathPattern 为映射的路径。然后我们再点击 staticPathPattern 进入查看映射的路径再点击.getStaticPathPattern()方法再点击this.staticPathPattern在 44 行处我们可以看到staticPathPattern 的值为/**。即访问当前项目的任何资源,如果没有 controller 去处理,默认都是去 addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())),addResourceLocations 方法中添加的资源位置处去访问。这时我们点击 getStaticLocations()方法进入查看点击进入 this.staticLocations,查看

upload successful

即当访问当前项目的任何资源,如果没有 controller 去处理,默认都是去类路径下面的META-INF/resources|resources|static|public 去访问资源。

upload successful

启动SpringBoot后直接在地址栏上输入METAINF/resources|resources|static|public下面的文件路径就能够访问的到相应的文件

upload successful

当然我们也可以自己修改静态资源的访问路径。在application.properties配置文件。这种配置会将 ResourceProperties 类中的 staticLocations 属性的值进行修改,原来的约定就不生效了,即原来保存到静态资源文件 resources、static、public 目录中的静态资源就无法访问了。

spring.resources.static-locations=classpath:/res/,classpath:/img/
  • 设置欢迎页面

    我们在刚学 JSP 时,我们是在 web.xml 文件中通过标签中定义多个欢迎页面。那么我们 SpringBoot 项目中是如何定义欢迎页面呢?

    我们找到 WebMvcAutoConfiguration类类中找到welcomePageHandlerMapping方法,可以看到SpringBoot默认的访问页面是index.html。如我们可以到 resources/public 目录下创建 index.html,然后在浏览器中输入 localhost:8080 回车默认会在静态资源目录中找 index 页面。

upload successful

//自定义项目访问名
server.servlet.context-path=/curd

登录页面的国际化( 包含链接和浏览器语言实现国际化)

实现当我们在下面登录页面中点击”中文”链接时,登录页面显示中文。当我们点击”English”时,登录页面显示英文效果。

upload successful

  • 编写国际化配置文件,抽取页面需要显示的国际化消息

    在 resources 目录下创建 i18n 目录,然后在 i18n 目录下创建 login.properties 文件,再创建 login_zh_CN.properties 中文国际化文件(zh 为语言代码,CN 为国家代码),最后再创建login_en_US.properties 英文国际化文件。

    • 双击 login_en_US.proerpties 文件到Resource Bundle,之后添加国际化配置信息。

      upload successful

      国际化配置信息如下所示。

upload successful
upload successful

upload successful

  • 修改 application.properties

    添加如下配置。

    //指定国际化的基础名,这里的 i18n 为国际化配置文件所在的 包名
    //login 为 国际化资源文件的基础名(即去掉了语言国家代码的,如 zh_CN、en_US)
    spring.messages.basename=i18n.login
  • 去页面获取国际化的值

    在 login.html 页面中使用#{}获取国际化的值,如下所示,红色字体为新增的。

upload successful

  • 重启项目并设置浏览器的语言为中文

    设置浏览器语言为中文(简体),切换国际化。在谷歌浏览器右上角—设置—高级—语言,将中文(简
    化)移到顶部。

upload successful

原因:IDEA 中 properties 里面的配置信息最终都要会被转换成 ASCII,解决这个乱码我们可以 properties 文件的字符编码。

解决方案:File—Settings—File Encodings,如下所示。最后再到 login.properties 文件中将中文乱码修改下,重启后,再刷新一下页面。

upload successful

谷歌浏览器右上角设置高级语言,将 英语( 美国)移到顶部。之后再刷新一下登录页面。登录页面的实现效果如下所示。

upload successful

  • 当点击页面底部的”中文”和”English”链接时,实现页面的国际化切换。

    国际化之所以有效果,是因为有一个重要的对象就是 Locale(区域信息对象),SpringMVC 给我们提供了获取所有 Locale 对象的组件——LocaleResolver(作用是获取区域信息对象)。而我们 SpringBoot 中也配置了区域信息解析器。Ctrl + N 搜索 localeResolver 方法,代码如下所示。

upload successful

在上述代码中,如果我们使用WebMvcProperties指定使用FixedLocaleResolver区域解析器那么我们就用 使用FixedLocaleResolver解析器,否则我们就使用AcceptHeaderLocaleResolver解 析 器 , 这 时 我们点击AcceptHeaderLocaleResolver找到resolverLocale用于解析区域信息的方法,下图中的 request.getLocale() 方法说明我们是从请求头中获取区域信息。SpringBoot 默认实现国际化的原理是:根据请求头带来的区域信息获取 Locale 区域对象信息来实现国际化。

upload successful

想要实现当点击页面底部的”中文”和”English”链接时,实现页面的国际化的切换,那么我们可以把 SpringBoot 默认配置的区域信息解析器给换掉(不使用它默认的),换成自己自定义的区域信息解析器。

upload successful

  • 实现的步骤如下

    • 修改 login.html 中的两个超链接的链接地址。

       <a class="btn btn-sm" th:href="@{/toLogin(l='zh_CN')}">中文</a>
      <a class="btn btn-sm" th:href="@{/toLogin(l='en_US')}">English</a>
    • 配置自定义的区域信息解析器,代码如下所示

      创建 component 包,在 component 包中创建 MyLocaleResolver

upload successful

自定义的区域信息解析器实现的效果:URL 参数没带区域信息时,就使用操作系统默认的区域信息。如果 URL 参数带了区域信息,就使用指定的区域信息。

为了能让自定义的区域信息解析器生效,我们需要将这个解析器添加了 SpringBoot容器。创建一个 config 包,在 config 包中创建一个配置类 MyMvcConfig。

upload successful

运行时点击切换中文

upload successful

当点击English时切换英文

upload successful