SpringBoot03:SpringBoot Web 开发

1 前言

在实际开发中,SpringBoot 通过自动装配帮我们解决许多问题,那么我们能不能自定义修改其中的一些内容呢?

SpringBoot 自动装配的代码位置:

  • ***Autoconfiguration:向容器中自动配置组件;
  • ***Properties:自动配置类,装配配置文件中自定义的内容。

SpringBoot 自动装配的过程:

  1. SpringBoot 启动会加载大量的自动配置类;
  2. 我们看我们需要的功能有没有在 SpringBoot 默认写好的自动配置类当中;
  3. 我们再来看这个自动配置类中到底配置了哪些组件;
  4. 给容器中自动配置类添加组件的时候,会从 ***Properties 类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
  5. 对于 SpringBoot 本身,如果其发现存在用户手动配置的数据,那么就会使用用户配置的数据,如果没有,则使用 SpringBoot 默认的。

 


2 静态资源导入

2.1 静态资源映射规则

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        // 已禁用默认资源处理
        logger.debug("Default resource handling disabled");
        return;
    }
    // 缓存控制
    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
    // webjars 配置
    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)
                                             .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                                             .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
}

2.2 使用 webjars 方法

webjars 本质就是以 jar 包的方式引入我们的静态资源。

比如当我们想要使用 jQuery 时,我们只需在 https://www.webjars.org 查找引入 jQuery 对应版本的pom依赖即可。

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

这样,我们便可以在对应的路径访问静态资源:http://localhost:8080/webjars/jquery/3.4.1/jquery.js

2.3 使用默认静态资源目录

"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"

我们可以在resources根目录下新建对应的文件夹,都可以存放我们的静态文件;

2.4 自定义静态资源文件夹

我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在 application.properties 中配置;

spring.resources.static-locations=classpath:/coding/

一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了。

 


3 Thymeleaf 模板引擎

3.1 模板引擎

如下图所示,模板引擎通过将我们给定的数据以及指定的模板进行填充,最终生成一个我们想要的内容。JSP 便是一种模板引擎。

由于 SpringBoot 默认不支持 JSP,且静态页面的开发过于繁琐,因此这里我们可以使用 Thymeleaf 模板引擎。

请添加图片描述

3.2 导入 Thymeleaf 依赖

要想使用 Thymeleaf,只需导入对应的依赖即可。对应的 pom 文件以及说明文档可以从以下三个网站中找到:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

3.3 Thymeleaf 使用

3.3.1 Thymeleaf 的规则

根据 SpringBoot 的自动配置原理可知,我们可以通过查找 Thymeleaf 的自动配置类 ThymeleafProperties 来了解其使用规则。

在 IDEA 中可以使用 ctrl + shift + alt + N 通过类名查找类。

@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML";
    private Charset encoding;
}

可以看到,我们只要把我们的 html 页面放在类路径下的 templates 下,thymeleaf 就可以帮我们自动渲染了。使用 thymeleaf 什么都不需要配置,只需要将他放在指定的文件夹下即可。

3.3.2 测试

1 编写一个测试页面 test.html 放在 templates 目录下;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>这是一个测试页面</h1>
</body>
</html>

2 编写一个 TestController;

@Controller
public class TestController {
    @RequestMapping("/t1")
    public String test1(){
        // 便会自动转到 classpath:/templates/test.html 这个目录下
        return "test";
    }
}

3 浏览器输入对应网站,输入如下内容;

请添加图片描述

3.4 Thymeleaf 语法

语法参考 Thymeleaf 的官方文档,传送门。弄几个测试。

3.4.1 后端传送内容到前端显示

1 编写一个 TestController;

@Controller
public class TestController {
    @RequestMapping("/t1")
    public String test1(Map<String,Object> map){
        //存入数据
        map.put("msg","<h1>Hello, Thymeleaf</h1>");
        // 便会自动转到 classpath:/templates/test.html 这个目录下
        return "test";
    }
}

2 编写一个测试页面 test.html 放在 templates 目录下;

<!DOCTYPE html>
<!--  若要使用 Thymeleaf,需要在 html 文件中导入命名空间的约束,方便提示 -->
<!-- 只有被接管了,才可以使用他的表达式 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- th:text就是将div中的内容设置为它指定的值 -->
<div th:text="${msg}"></div>
<!--不转义-->
<div th:utext="${msg}"></div>
</body>
</html>

3.4.2 前端遍历数据

1 编写一个 TestController;

@Controller
public class TestController {
    @RequestMapping("/t1")
    public String test1(Map<String,Object> map){
        //存入数据
        map.put("users", Arrays.asList("sharm","jack"));
        // 便会自动转到 classpath:/templates/test.html 这个目录下
        return "test";
    }
}

2 编写一个测试页面 test.html 放在 templates 目录下;

<!DOCTYPE html>
<!--  若要使用 Thymeleaf,需要在 html 文件中导入命名空间的约束,方便提示 -->
<!-- 只有被接管了,才可以使用他的表达式 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--th:each每次遍历都会生成当前这个标签:建议用行内写法 -->
<h4 th:each="user :${users}" th:text="${user}"></h4>
</body>
</html>

 


4 装配扩展 SpringMVC

Spring 的官方文档如是说:If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

Spring 的说明文档怎么找,我以找到 Spring MVC 的自动配置这部分为例:Spring 官网 - Projects - Spring Boot - LEARN - Reference Doc. - Web - Servlet Web Applications - Spring MVC Auto-configuration。

4.1 扩展视图解析器

从源码中可以看到,我们只需要自己写一个视图解析器,并且把它注册到 bean 里面,SpringBoot 就会自动帮我们装配上。

写上视图解析器为:

// If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors
// ,formatters, view controllers, and other features), you can add your own @Configuration class of type
// WebMvcConfigurer.
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Bean
    // MyViewResolver 是实现了视图解析器接口的类,因此我们可以将它看成视图解析器
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }
}

// 自定义了一个视图解析器
class MyViewResolver implements ViewResolver{
    @Override
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        return null;
    }
}

测试视图解析器是否起作用:

1 给 DispatcherServlet 中的 doDispatch方法 加个断点进行调试一下,因为所有的请求都会走到这个方法中;

请添加图片描述

2 启动我们的项目,随便访问一个页面,看一下 Debug 信息;

请添加图片描述

3 找到视图解析器,可以看到我们自定义的视图解析器就在这里,且发挥了作用。

请添加图片描述

4.2 扩展格式化配置

在 WebMvcAutoConfiguration 中找到格式化转换器:

@Bean
@Override
public FormattingConversionService mvcConversionService() {
    // 拿到配置文件中的格式化规则
    WebConversionService conversionService = 
        new WebConversionService(this.mvcProperties.getDateFormat());
    addFormatters(conversionService);
    return conversionService;
}

进入到.getDateFormat方法中,可以看到:

public String getDateFormat() {
    return this.dateFormat;
}

/**
* Date format to use. For instance, `dd/MM/yyyy`. 默认的
 */
private String dateFormat;

所以我们可以在我们的 Properties 文件中设置新的配置日期格式化的规则为:

spring.mvc.data-format=……

请添加图片描述

4.3 扩展视图跳转

这样的话,当我们书写一个新的链接,新的链接会跳转到指定的链接里。

// If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors
// ,formatters, view controllers, and other features), you can add your own @Configuration class of type
// WebMvcConfigurer.
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/sharm").setViewName("test");
    }
}

其中 test.html 的内容为:

<body>
<!--th:each每次遍历都会生成当前这个标签:官网-->
<!--<h4 th:each="user :${users}" th:text="${user}"></h4>-->
<h1>This is new page!</h1>
</body>

浏览器输出为:

请添加图片描述

4.4 全面接管 SpringMVC

官方文档:

If you want to take complete control of Spring MVC you can add your own @Configuration annotated with @EnableWebMvc.

@Configuration
// 当在配置类中加上 @EnableWebMvc 这个注解,可以看到之前 SpringBoot 给我们配置的静态资映射全都无效了。在开发中,不推荐使用全面接管 SpringMVC
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/sharm").setViewName("test");
    }
}

访问首页出现的结果。

请添加图片描述

原因:

1 该注解导入了一个类

@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

2 它继承了一个父类 WebMvcConfigurationSupport

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
  // ......
}

3 Webmvc 自动配置类为:

@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 {
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值