4.SpringBoot与Web结合前期准备

4.SpringBoot与Web结合前期准备

​ 首先需要了解SpringBoot整合Web的准备前提需要什么?

因为SpringBoot约定大于配置所以我们需要知道一下资源放置位置

  • 导入静态资源(html,css,js等静态资源该如何导入)
  • 定制首页
  • 用thymeleaf或者freemarker代替jsp(SpringBoot不支持jsp)
  • 学会装配扩展SpringMVC(视图解析器,处理器映射器,json,ajax,文件上传与下载等等都是我们需要装配SpringMVC的理由)
  • 国际化i18n
  • 拦截器(都是通过Bean注入到Spring容器的)
  • CRUD(我觉得可以用代码生成器easycode,mybatisplus generator)

4.1 静态导入探究

​ 首先我们配置了web的场景启动器,所以SpringBoot会自动帮我们装配WebMvcAutoConfiguration

  • 跟进WebMvcAutoConfiguration可以找到WebMvcAutoConfigurationAdapter这样一个Web适配类
  • 发现里面声明了一个静态私有的ResourceProperties配置类
private final ResourceProperties resourceProperties;
  • 跟进去可以看到SpringBoot静态资源的存放位置(就下面源代码部分)
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
	//第一个classpath:/META-INF/resources/是webjars下的下面会将,其他的直接建在classpath下就行
   private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
         "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

   private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
}
  • 因此我们可以在指定的路径下创建相应的文件夹存放静态资源(classpath表示类路径也即是resources)

在这里插入图片描述

优先级:resources>static>public

​ 同样WebMvcAutoConfigurationAdapter下也有addResourceHandlers(添加资源处理器的类)

  • 在这个类中也说明了一种添加静态资源的方式
  • 直接上源码
  • 她说在"classpath:/META-INF/resources/webjars/"下可以增加静态资源
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
   	/**
   	  * 如果你自己定义了静态资源的路径,那么默认的就失效
   	  * 源码默认是	private String staticPathPattern = "/**";
   	  * 现在我们可以自定义
   	  * spring.mvc.static-path-pattern=	"/xuan"
   	  */
    if (!this.resourceProperties.isAddMappings()) {
      logger.debug("Default resource handling disabled");
      return;
   }
    
   Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
   CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
   if (!registry.hasMappingForPattern("/webjars/**")) {
      customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/")
            .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
   }
   String staticPathPattern = this.mvcProperties.getStaticPathPattern();
   if (!registry.hasMappingForPattern(staticPathPattern)) {
      customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
             //这源码就是找我们上面说的resourceProperties下的静态资源
            .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
            .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
   }
}

​ 我们看一下webjars是什么?

  • WebJars是打包到JAR(Java存档)文件中的客户端Web库(例如jQuery和Bootstrap)

安装官网

​ 第一步:引入pom.xml

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.5.1</version>
</dependency>

​ 第二步:我们可以看到导入依赖对应的目录结构与classpath:/META-INF/resources/webjars/是对应的

在这里插入图片描述

​ 第三步:启动服务,访问下 localhost:8081/webjars/jquery/3.5.1/jquery.js 可以访问到jquery.js的静态资源

在这里插入图片描述

4.2 定制首页

​ 首先我们配置了web的场景启动器,所以SpringBoot会自动帮我们装配WebMvcAutoConfiguration

  • 跟进WebMvcAutoConfiguration可以找到EnableWebMvcConfiguration这个类
  • 在这个类下面有个welcomePageHandlerMapping(@Bean表示添加到Spring组件)就是可以让我们定制首页的
  • 其次还有一个getWelcomePage方法默认是index页面作为首页
  • index.html这个页面放在this.resourceProperties也就是我们上面指定的静态资源目录
  • 首页一般是放在templates目录下

​ 下面我们看一下源码

//欢迎页的处理映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
      FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
   WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
         new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
         this.mvcProperties.getStaticPathPattern());
   welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
   welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
   return welcomePageHandlerMapping;
}

private Optional<Resource> getWelcomePage() {
   String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
   return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}

private Resource getIndexHtml(String location) {
    return this.resourceLoader.getResource(location + "index.html");
}

​ 测试一下,编写一个index.html放在public目录下 直接访问localhost:8080 就可以显示首页信息

4.3 Thymeleaf模板引擎

​ 什么是Thymeleaf?

  • https://www.thymeleaf.org/ 官网

  • Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎,能轻易的与Spring MVC等Web框架进行集成作为Web应用。

  • 与其它模板引擎(比如FreeMaker)相比,Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用(更加方便前后端分离,比如方便类似VUE前端设计页面),抛弃JSP吧。

  • Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板 -HTML可以在浏览器中正确显示,也可以作为静态原型工作,从而可以在开发团队中加强协作。

  • Thymeleaf拥有适用于Spring Framework的模块,与您喜欢的工具的大量集成以及插入您自己的功能的能力,对于现代HTML5 JVM Web开发而言,Thymeleaf是理想的选择-尽管它还有很多工作要做。

使用Thymeleaf

​ 第一步:导入Thymeleaf依赖

<!--Java 8 Time API兼容性-->
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<!--Spring 5整合-->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>

​ 然后由于SpringBoot的自动装配,我们一定能找到ThymeleafAutoConfiguration自动装配类

​ 接着必然有ThymeleafProperties,我们跟进去看一下源码

  • 也就是说我们所有需要被SpringBoot识别的html页面需要放到templates目录下(当然也可以自己指定)
  • 当然我们也可以在application.yml指定spring.thymeleaf的属性值
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

   private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

   public static final String DEFAULT_PREFIX = "classpath:/templates/";

   public static final String DEFAULT_SUFFIX = ".html";
}

​ 第二步:编写controller并用model将值存进去

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model){
        model.addAttribute("msg","thymeleaf是最好的模板引擎");
        return "hello";
    }
}

​ 第三步:在templates文件夹下新建一个 hello.html

  • 注意这里想要取值,关键之一是 引入thymeleaf支持====
  • 其次用==th:text="${msg}"==取出model里面的值 th是thymeleaf的固定前缀 text是取出文本数据 ${} 就是el表达式的取值
<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<p th:text="${msg}"></p>

</body>
</html>

4.4 Thymeleaf语法

可以在在线文档查看用法:https://fanlychie.github.io/

​ thymeleaf语法

  • Thymeleaf 提供了非常丰富的标准表达式语法,总共有 8 大类:
  • 简单表达式、字面值、文本操作、算术运算、布尔运算、比较和相等、条件运算、无操作符
语法名称描述作用
${…}Variable Expressions变量表达式取出上下文变量的值
*{…}Selection Variable Expressions选择变量表达式取出选择的对象的属性值
#{…}Message Expressions消息表达式使文字消息国际化,I18N
@{…}Link URL Expressions链接表达式用于表示各种超链接地址
~{…}Fragment Expressions片段表达式引用一段公共的代码片段

​ 1.使用文本 th:text 与 th:utext

属性th:utextth:text的区别在于:

  • th:text默认会对含有 HTML 标签的内容进行字符转义

  • th:utext(Unescaped Text)则不会对含有 HTML 标签的内容进行字符转义;(也就是说utext会解析标签中内容

  • 测试

  • controller中部分代码

model.addAttribute("msg","<h1>thymeleaf是最好的模板引擎</h1>");
  • hello.html部分代码
<div th:text="${msg}"></div>
<hr/>
<div th:utext="${msg}"></div>
  • 页面展示

在这里插入图片描述

​ 2.遍历 th:each

  • 遍历(迭代)的语法th:each="自定义的元素变量名称 : ${集合变量名称}"
  • 下面就是遍历取出所有所在城市名字
<div>
    <spn>你所在城市:</spn>
    <select name="mycity">
        <option th:each="city : ${cities}" th:text="${city.name}"></option>
    </select>
</div>
  • 还有另一种取法(不建议这样取)
 <option th:each="city : ${cities}" >[[${city.name}]]</option>

​ 3.条件判断 th:if th:unless th:swith

  • 当表达式的评估结果为真时则显示内容,否则不显示:
<a th:href="@{/user/order(uid=${user.id})}" th:if="${user != null}">我的订单</a>
  • th:unlessth:if判断恰好相反,当表达式的评估结果为假时则显示内容,否则不显示:
<a th:href="@{/user/order(uid=${user.id})}" th:unless="${user == null}">我的订单</a>
  • 多路选择语句,它需要搭配th:case来使用:
<div th:switch="${user.role}">
    <p th:case="admin">管理员</p>
    <p th:case="user">普通用户</p>
</div>

4.5 装配扩展SpringMVC

官网地址

​ 自动配置在Spring的默认值之上添加了以下功能:

  • 包含ContentNegotiatingViewResolverBeanNameViewResolver
  • 支持提供静态资源,包括对WebJars的支持。
  • 自动注册ConverterGenericConverterFormatter豆类。
  • 支持HttpMessageConverters
  • 自动注册MessageCodesResolver
  • 静态index.html支持。
  • 定制Favicon支持。
  • 自动使用ConfigurableWebBindingInitializerbean。

如果要保留这些Spring Boot MVC定制并进行更多的MVC定制拦截器,格式化程序,视图控制器和其他功能),则可以添加自己@Configuration的type类,WebMvcConfigurer但不添加 @EnableWebMvc

​ 解释一下为什么自己配置的类不能加@EnableWebMvc注解

  • 首先加上这个注解后跟进源码会发现导入了DelegatingWebMvcConfiguration这个类
  • DelegatingWebMvcConfiguration继承WebMvcConfigurationSupport这个类
  • 此时我们再看springBoot中web的核心配置类WebMvcAutoConfiguration(见下面)
  • 是不是发现了**@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)只有在XXXSupport不存在SpringIOC容器才接管,也就意味着你加了@EnableWebMvc**后spring容器就无法接管了。
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
      ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}

​ 可以自定义视图解析器之类的 写在config包下,类需要实现WebMvcConfigurer接口

  • 重写WebMvcConfigurer的addViewControllers方法实现视图跳转
package com.xuan.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

/**
 * xuan
 * 2020/7/23
 * 1870136088@qq.com
 **/
@Configuration
public class MyWebConfig implements WebMvcConfigurer {

    /**
     * 视图跳转(因为视图跳转是由controller决定的)
     * @param registry
     */

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/yangjieshen").setViewName("hello");
        
        registry.addRedirectViewController("/xuan","/hello");
    } 


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值