前言

Spring Boot 天生的适合 web 应用开发,它可以快速的嵌入 Tomcat, Jetty 或 Netty 用于包含一个 HTTP 服务器。且开发十分简单,只需要引入 web 开发所需的包,然后编写业务代码即可。

自动配置原理?

在进行 web 开发之前让我再来回顾一下自动配置,可以参考系列文章第三篇。Spring Boot 为 Spring MVC 提供了自动配置,添加了如下的功能:

  • 视图解析的支持。
  • 静态资源映射,WebJars 的支持。
  • 转换器 Converter 的支持。
  • 自定义 Favicon 的支持。
  • 等等

在引入每个包时候我们需要思考是如何实现自动配置的,以及我们能自己来配置哪些东西,这样开发起来才会得心应手。

关于 Spring Boot Web 开发的更详细介绍可以参考官方文档。

1. JSON 格式转换

Spring Boot 默认使用 Jackson 进行 JSON 化处理,如果想要切换成 FastJson 可以首先从官方文档里查询信息。从这里知道对于 ResponseBody 的渲染主要是通过 HttpMessageConverters, 而首先引入FastJson Pom依赖并排除 Spring Boot 自带的 Jackson。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-json</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>

编写转换器处理 json 的日期格式同时处理中文乱码问题。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer { /**
* 自定义JSON转换器
*
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//日期格式化
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
//处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); converter.setSupportedMediaTypes(fastMediaTypes);
converter.setFastJsonConfig(fastJsonConfig); converters.add(converter);
} }

2. 静态资源映射

By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.

2.1 默认映射

官方文档告诉我们 Spring Boot 对于静态资源的映射目录是 /static , /public , /resources 以及 /META-INF/resource。除此之外其实还映射了 /webjars/**classpath:/META-INF/resources/webjars

很明显此处是自动配置实现的,通过查看源码分析这段配置。



而对于网站图标,Spring Boot 也已经配置了默认位置,可以在看到。

// path: org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", // 图表
faviconRequestHandler()));
return mapping;
} @Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(resolveFaviconLocations());
return requestHandler;
} private List<Resource> resolveFaviconLocations() {
String[] staticLocations = getResourceLocations(
this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
Arrays.stream(staticLocations).map(this.resourceLoader::getResource)
.forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}

根据 Spring Boot 默认的静态资源映射规则,可以直接把需要的静态资源放在响应的文件夹下然后直接引用即可。

而放在 Public 文件夹下的 HTML 页面也可以直接访问。

2.2 webjars

webjars 的思想是把静态资源打包到 Jar 包中,然后使用 JVM 构建工具进行管理,如 maven , Gradle 等。

使用 webjars 第一步需要进入依赖,如要使用 bootstrap。

 <!-- Web Jars 静态资源文件 -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.1.3</version>
</dependency>

引入之后查看 bootstrap 资源。

由于 Springboot 映射了 /webjars/**classpath:/META-INF/resources/webjars. 因此可以直接在文件中引用 webjars 的静态资源。

<!-- Bootstrap core CSS -->
<link href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
<script src="/webjars/bootstrap/4.1.3/js/bootstrap.min.js"></script>

3. 模版引擎

Spring MVC 支持各种模版技术,如 Thymeleaf , FreeMarker , JSP 等。而Thyemeleaf 原型即页面的特性或许更符合 Spring Boot 快速开发的思想而被官方推荐。

Thymeleaf 是适用于 Web 开发的服务端 Java 模版引擎,Thymeleaf 为开发工作流程带来优雅自然的模版,由于其非侵入的特性,可以让页面不管是在静态原型下还是用作模版引擎时都有良好的页面展现。

<table>
<thead>
<tr>
<th th:text="#{msgs.headers.name}">Name</th>
<th th:text="#{msgs.headers.price}">Price</th>
</tr>
</thead>
<tbody>
<tr th:each="prod: ${allProducts}">
<td th:text="${prod.name}">Oranges</td>
<td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
</tr>
</tbody>
</table>

3.1 引入 Thymeleaf

 		<!-- thymeleaf 模版-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

3.2 使用 Thymeleaf

根据 Spring Boot 自动配置原理,先看一下 Thymeleaf 的配置类,从中可以看出 Thymeleaf 的相关配置。我们可以知道 默认存放目录是 templates 文件夹,文件后缀为 .html 且开启了缓存。

@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";
/**
* Whether to enable template caching.
*/
private boolean cache = true;

为了在开发中编写模版文件时不用重启,可以在配置中关闭缓存。

# 关闭模版缓存
spring.thymeleaf.cache=false
# 如果需要进行其他的配置,可以参考配置类:ThymeleafProperties
# org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties

编写 Controller 响应信息。

  /**
* 获取ID为1的用户信息
*
* @return
*/
@GetMapping(value = "/user/1")
public String getUserById(Model model) {
User user1 = new User("Darcy", "password", 24, new Date(), Arrays.asList("Java", "GoLang"));
User user2 = new User("Chris", "password", 22, new Date(), Arrays.asList("Java", "Web"));
ArrayList<User> userList = new ArrayList<>();
userList.add(user1);
userList.add(user2);
model.addAttribute("userList", userList);
model.addAttribute("user", user1);
return "user";
}

因为 Thymelaf 默认模版位置在 templates 文件夹下,因此在这个文件夹下编写页面信息。

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf 的基本使用</title>
<!-- 引入JS文件 -->
<!--<script th:src="@{/static/js/alert.js}"></script>-->
</head>
<body> <div>
<p><b>Hello Thymeleaf Index</b></p>
用户名称:<input th:id="${user.username}" th:name="${user.username}" th:value="${user.username}">
<br/>
用户技能:<input th:value="${user.skills}">
<br/>
用户年龄:<input th:value="${user.age}">
<br/>
用户生日:<input th:value="${#dates.format(user.birthday,'yyyy-MM-dd hh:mm:ss ')}">
</div> <div th:object="${user}">
<p><b>Hello Thymeleaf Index</b></p> 用户名称:<input th:id="*{username}" th:name="*{username}" th:value="*{username}">
<br/>
用户技能:<input th:value="*{skills}">
<br/>
用户年龄:<input th:value="*{age}">
<br/>
用户生日:<input th:value="*{#dates.format(birthday,'yyyy-MM-dd hh:mm:ss')}">
</div> <div>
<p><b>Text 与 utext</b></p>
<!-- th:text 显示HTML源码,作为字符串 -->
<span th:text="${user.username}">abc</span>
<br>
<span th:utext="${user.username}">abc</span>
</div> <div>
<p><b>URL 的引用</b></p>
<a th:href="@{https://www.baidu.com}">网站网址</a>
</div> <div>
<p><b>表单的使用</b></p>
<form th:action="@{/th/postform}" th:object="${user}" method="post">
用户名称:<input type="text" th:field="*{username}">
<br/>
用户技能:<input type="text" th:field="*{skills}">
<br/>
用户年龄:<input type="text" th:field="*{age}">
<input type="submit">
</form>
</div> <div>
<p><b>判断的使用</b></p>
<div th:if="${user.age} == 18">18岁了</div>
<div th:if="${user.age} gt 18">大于18岁</div>
<div th:if="${user.age} lt 18">小于18岁</div>
<div th:if="${user.age} ge 18">大于等于</div>
<div th:if="${user.age} le 18">小于等于</div>
</div> <div>
<p><b>选择框</b></p>
<select>
<option>请选择一本书</option>
<option th:selected="${user.username eq 'admin'}">管理员</option>
<option th:selected="${user.username eq 'Darcy'}">Darcy</option>
<option th:selected="${user.username eq 'Chris'}">Chris</option>
</select>
</div> <div>
<p><b>遍历功能</b></p>
<table>
<tr>
<th>用户名称</th>
<th>年龄</th>
<th>技能</th>
</tr>
<tr th:each="u:${userList}">
<td th:text="${u.username}"></td>
<td th:text="${u.age}"></td>
<td th:text="${u.skills}"></td>
</tr>
</table>
</div> <div>
<p><b>Switch功能</b></p>
<div th:switch="${user.username}">
<p th:case="'admin'">欢迎管理员</p>
</div>
</div>
</body>
</html>

访问页面可以看到数据正常显示。

文章代码已经上传到 GitHub Spring Boot Web开发 - 静态资源

文章代码已经上传到 GitHub Spring Boot Web开发 - 模版引擎

<完>

本文原发于个人博客:https://www.codingme.net 转载请注明出处

Springboot 系列(五)Spring Boot web 开发之静态资源和模版引擎的更多相关文章

  1. Springboot 系列(六)Spring Boot web 开发之拦截器和三大组件

    1. 拦截器 Springboot 中的 Interceptor 拦截器也就是 mvc 中的拦截器,只是省去了 xml 配置部分.并没有本质的不同,都是通过实现 HandlerInterceptor ...

  2. Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析

    前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...

  3. spring boot系列(二)spring boot web开发

    json 接口开发 在以前的spring 开发的时候需要我们提供json接口的时候需要做如下配置: 1 添加jackjson等jar包 2 配置spring controller扫描 3 对接的方法添 ...

  4. SpringBoot系列:Spring Boot使用模板引擎FreeMarker

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

  5. SpringBoot系列:Spring Boot使用模板引擎Thymeleaf

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

  6. SpringBoot系列:Spring Boot使用模板引擎JSP

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

  7. Spring Boot Web 开发注解篇

    本文提纲 1. spring-boot-starter-web 依赖概述 1.1 spring-boot-starter-web 职责 1.2 spring-boot-starter-web 依赖关系 ...

  8. 四、Spring Boot Web开发

    四.Web开发 1.简介 使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可 ...

  9. SpringBoot系列:Spring Boot集成Spring Cache,使用RedisCache

    前面的章节,讲解了Spring Boot集成Spring Cache,Spring Cache已经完成了多种Cache的实现,包括EhCache.RedisCache.ConcurrentMapCac ...

随机推荐

  1. jquery 判断一个元素是否在数组中 $.inarry()使用

    需要判断一个元素是否在一个数组里: js indexOf()方法  如果存在 则返回该元素的下标值 如果不存在则返回-1 学习源头: http://www.w3school.com.cn/jsref/ ...

  2. 聊聊Socket、TCP/IP、HTTP、FTP及网络编程

    1 这些都是什么 既然是网络传输,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输.这里就要使用到TCP/IP协议. 1.1 TCP ...

  3. 玩转PHP中的正则表达式

    玩转PHP中的正则表达式 检验用户输入.解析用户输入和文件内容,以及重新格式化字符串 级别: 中级 正则表达式提供了一种处理文本的强大方法.使用正则表达式,您可以对用户输入进行复杂的检验.解析用户输入 ...

  4. 如何看MySql执行计划explain(或desc)

    简介 MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化.EXPLAIN 命令用法十分简单, 在 S ...

  5. MyEclipse 10导入JDK1.7或1.8

    1.在MyEclipse,选择“windows”>"preferences"选择,打开“perference”窗口(如下图) 2.展开“perference”窗口左侧“jav ...

  6. Python档案袋(生成器、迭代器、队列 )

    生成器: 简单的生成器实现: #生成器,将for循环的变量传递到前面的式子进行处理 #生成的并不是一个列表,而是一个存在算数规则的对象 #不能通过下标直接取值,必须一个一个从头到尾取 va=(i*2 ...

  7. 中小研发团队架构实践之生产环境诊断工具WinDbg

    生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具,Dump文件类似于飞机的黑匣子,记录着生产环境程序 ...

  8. 基于CNN的人群密度图估计方法简述

    人群计数的方法分为传统的视频和图像人群计数算法以及基于深度学习的人群计数算法,深度学习方法由于能够方便高效地提取高层特征而获得优越的性能是传统方法无法比拟的.本文简单了秒速了近几年,基于单张图像利用C ...

  9. SQL优化 MySQL版 - B树索引详讲

    SQL优化 MySQL版  - -B树索引详讲 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 为什么要进行SQL优化呢?很显然,当我们去写sql语句时: 1会发现性能低 2.执行时间太 ...

  10. 安卓开发笔记(十):升级ListView为RecylerView的使用

    概述 RecyclerView是什么 从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活.Recycle ...