Springboot 系列(五)Spring Boot web 开发之静态资源和模版引擎

简介: Springboot 系列(五)Spring Boot web 开发之静态资源和模版引擎

前言


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


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

微信图片_20220413133318.jpg    Mvc静态资源映射

微信图片_20220413133321.jpg

                                                     静态资源映射


而对于网站图标,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 默认的静态资源映射规则,可以直接把需要的静态资源放在响应的文件夹下然后直接引用即可。

微信图片_20220413133451.jpg

                                                   静态资源映射


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

微信图片_20220413133508.jpg

                                                  静态资源映射


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 资源。

微信图片_20220413133546.png

                                        WebJars 引入 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 快速开发的思想而被官方推荐。

微信图片_20220413133628.png

                                               模版引擎原理


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>


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


微信图片_20220413133715.png

                                                          访问测试

相关文章
|
6月前
|
安全 Java Apache
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 身份和权限认证
本文介绍了 Apache Shiro 的身份认证与权限认证机制。在身份认证部分,分析了 Shiro 的认证流程,包括应用程序调用 `Subject.login(token)` 方法、SecurityManager 接管认证以及通过 Realm 进行具体的安全验证。权限认证部分阐述了权限(permission)、角色(role)和用户(user)三者的关系,其中用户可拥有多个角色,角色则对应不同的权限组合,例如普通用户仅能查看或添加信息,而管理员可执行所有操作。
286 0
|
6月前
|
安全 Java 数据安全/隐私保护
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 三大核心组件
本课程介绍如何在Spring Boot中集成Shiro框架,主要讲解Shiro的认证与授权功能。Shiro是一个简单易用的Java安全框架,用于认证、授权、加密和会话管理等。其核心组件包括Subject(认证主体)、SecurityManager(安全管理员)和Realm(域)。Subject负责身份认证,包含Principals(身份)和Credentials(凭证);SecurityManager是架构核心,协调内部组件运作;Realm则是连接Shiro与应用数据的桥梁,用于访问用户账户及权限信息。通过学习,您将掌握Shiro的基本原理及其在项目中的应用。
225 0
|
4月前
|
Web App开发 前端开发 JavaScript
鸿蒙5开发宝藏案例分享---Web适配一多开发实践
这是一份实用的鸿蒙Web多设备适配开发指南,针对开发者在不同屏幕尺寸下的布局难题提供了解决方案。文章通过三大法宝(相对单位、媒体查询和窗口监听)详细介绍如何实现智能适配,并提供了多个实战案例,如宫格布局、对话框变形和自适应轮播图等。此外,还分享了调试技巧及工具推荐,帮助开发者快速上手并优化性能。最后鼓励读者实践探索,并提示更多官方资源等待发现。
|
5月前
|
前端开发 Java Maven
Spring 和 Spring Boot 之间的比较
本文对比了标准Spring框架与Spring Boot的区别,重点分析两者在模块使用(如MVC、Security)上的差异。Spring提供全面的Java开发基础设施支持,包含依赖注入和多种开箱即用的模块;而Spring Boot作为Spring的扩展,通过自动配置、嵌入式服务器等功能简化开发流程。文章还探讨了两者的Maven依赖、Mvc配置、模板引擎配置、启动方式及打包部署等方面的异同,展示了Spring Boot如何通过减少样板代码和配置提升开发效率。总结指出,Spring Boot是Spring的增强版,使应用开发、测试与部署更加便捷高效。
609 11
|
6月前
|
消息中间件 存储 Java
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ安装
本教程介绍ActiveMQ的安装与基本使用。首先从官网下载apache-activemq-5.15.3版本,解压后即可完成安装,非常便捷。启动时进入解压目录下的bin文件夹,根据系统选择win32或win64,运行activemq.bat启动服务。通过浏览器访问`http://127.0.0.1:8161/admin/`可进入管理界面,默认用户名密码为admin/admin。ActiveMQ支持两种消息模式:点对点(Queue)和发布/订阅(Topic)。前者确保每条消息仅被一个消费者消费,后者允许多个消费者同时接收相同消息。
166 0
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ安装
|
6月前
|
消息中间件 Java 微服务
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——发布/订阅消息的生产和消费
本文详细讲解了Spring Boot中ActiveMQ的发布/订阅消息机制,包括消息生产和消费的具体实现方式。生产端通过`sendMessage`方法发送订阅消息,消费端则需配置`application.yml`或自定义工厂以支持topic消息监听。为解决点对点与发布/订阅消息兼容问题,可通过设置`containerFactory`实现两者共存。最后,文章还提供了测试方法及总结,帮助读者掌握ActiveMQ在异步消息处理中的应用。
232 0
|
6月前
|
消息中间件 网络协议 Java
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ集成
本文介绍了在 Spring Boot 中集成 ActiveMQ 的详细步骤。首先通过引入 `spring-boot-starter-activemq` 依赖并配置 `application.yml` 文件实现基本设置。接着,创建 Queue 和 Topic 消息类型,分别使用 `ActiveMQQueue` 和 `ActiveMQTopic` 类完成配置。随后,利用 `JmsMessagingTemplate` 实现消息发送功能,并通过 Controller 和监听器实现点对点消息的生产和消费。最后,通过浏览器访问测试接口验证消息传递的成功性。
330 0
|
6月前
|
消息中间件 Java API
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ—— JMS 和 ActiveMQ 介绍
本文介绍如何在Spring Boot中集成ActiveMQ,首先阐述了JMS(Java消息服务)的概念及其作为与具体平台无关的API在异步通信中的作用。接着说明了JMS的主要对象模型,如连接工厂、会话、生产者和消费者等,并指出JMS支持点对点和发布/订阅两种消息类型。随后重点讲解了ActiveMQ,作为Apache开源的消息总线,它完全支持JMS规范,适用于异步消息处理。最后,文章探讨了在Spring Boot中使用队列(Queue)和主题(Topic)这两种消息通信形式的方法。
152 0
|
设计模式 Web App开发 存储
移动 Web 开发的10个优秀 JavaScript 框架
选择正确的 JavaScript 框架,对于开发移动 Web 应用程序是至关重要的,也是移动应用程序开发的一项重要任务。开发人员可以使用框架实现的功能高效地达到他们的开发目标。这些预实现的组件采用优秀的设计模式和最佳实践,促进应用程序以标准化的方式开发。最重要的是,它让开人员在开发过程中得心应手。
706 0
移动 Web 开发的10个优秀 JavaScript 框架
|
Web App开发 移动开发 JavaScript
【今日推荐】移动 Web 开发的10个最佳 JavaScript 框架
  选择正确的 JavaScript 框架,对于开发移动 Web 应用程序是至关重要的,也是移动应用程序开发的一项重要任务。开发人员可以使用框架实现的功能高效地达到他们的开发目标。这些预实现的组件采用优秀的设计模式和最佳实践,促进应用程序以标准化的方式开发。
2029 0