SpringBoot3框架,Web开发(下)

模板引擎

  • 由于 SpringBoot 使用了嵌入式 Servlet 容器。所以 JSP 默认是不能使用的。
  • 如果需要服务端页面渲染,优先考虑使用 模板引擎。

Thymeleaf

Thymeleaf 是一个现代的服务器端 Java 模板引擎,适用于 Web 和独立 环境

格式:

<!DOCTYPE html>
<html xmlns:th="[<http://www.thymeleaf.org>](<http://www.thymeleaf.org/>)">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all" th:href="@{/css/gtvg.css}" />
</head>
<body>
<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
</body
</html>

Thymeleaf整合

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

自动配置原理

  1. 开启了 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration 自动配置
  2. 属性绑定在 ThymeleafProperties 中,对应配置文件 spring.thymeleaf 内容
  3. 所有的模板页面默认在 classpath:/templates文件夹下
  4. 默认效果
    1. 所有的模板页面在 classpath:/templates/下面找
    2. 找后缀名为.html的页面

Thymeleaf基础语法

核心用法

th:xxx:动态渲染指定的 html 标签属性值、或者th指令(遍历、判断等)

  • th:text:标签体内文本值渲染
    • th:utext:不会转义,显示为html原本的样子。即会识别html语法
  • th:属性:标签指定属性渲染
  • th:attr:标签任意属性渲染,可以指定多个属性,语法为:例如,要指定src和style属性,th:attr=”src=${imgUrl},style=${style}”
  • th:if th:each...:其他th指令
    • th:if:可以传入布尔类型的值,true表示该标签生效,false表示该标签不生效

    • th:switch:例:

      <div th:switch="${user.role}"><p th:case="'admin'">User is an administrator</p><p th:case="#{roles.manager}">User is a manager</p><p th:case="*">User is some other thing</p>
      </div>
      
    • th:each :遍历操作,语法:th:each=”元素名 : ${集合}”或者th:each=”元素名,迭代状态 : ${集合}”,迭代状态有以下取值:

      • index:当前遍历元素的索引,从0开始
      • count:当前遍历元素的索引,从1开始
      • size:需要遍历元素的总数量
      • current:当前正在遍历的元素对象
      • even/odd:是否偶数/奇数行
      • first:是否第一个元素
      • last:是否最后一个元素
      <tr th:each="prod : ${prods}"><td th:text="${prod.name}">Onions</td><td th:text="${prod.price}">2.41</td><td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
      </tr><tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'"><td th:text="${prod.name}">Onions</td><td th:text="${prod.price}">2.41</td><td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
      </tr>
      

      使用状态信息直接在表中加一列 stats.迭代状态 (也是使用${stats.迭代状态})就可以在表中显示出每一行(集合中的每个元素)的状态信息

表达式

  • ${}:变量取值,使用model共享给页面的值都直接用${}
  • @{}:专门用来获取url路径,其中的路径在访问时会自动加上项目根路径
  • #{}:国际化消息
  • ~{}:片段引用
  • *{}:变量选择:需要配合th:object绑定对象

工具类

  • param:请求参数对象
  • session:session对象
  • application:application对象
  • #execInfo:模板执行信息
  • #messages:国际化消息
  • #uris:uri/url工具
  • #conversions:类型转换工具
  • #dates:日期工具,是java.util.Date对象的工具类
  • #calendars:类似#dates,只不过是java.util.Calendar对象的工具类
  • #temporals: JDK8+ java.time API 工具类
  • #numbers:数字操作工具
  • #strings:字符串操作
  • #objects:对象操作
  • #bools:bool操作
  • #arrays:array工具
  • #lists:list工具
  • #sets:set工具
  • #maps:map工具
  • #aggregates:集合聚合工具(sum、avg)
  • #ids:id生成工具

这些工具类中有一系列函数可以调用,见官网文档

一些其他操作

文本操作:

  • 字符串拼接: +
  • 文本替换:| The name is ${name} |

布尔操作:

  • 二进制运算: and,or
  • 取反:!,not

比较运算:

  • 比较:>,<,<=,>=(gt,lt,ge,le)
  • 等值运算:==,!=(eq,ne)

条件运算:

  • if-then: (if)?(then)
  • if-then-else: (if)?(then):(else)
  • default: (value)?:(defaultValue)

行内写法:

使用[[...]] or [(...)] 在行内使用其要引入的数据

<p>Hello, [[${session.user.name}]]!</p>

属性优先级

OrderFeatureAttributes
1片段包含th:insert th:replace
2遍历th:each
3判断th:if th:unless th:switch th:case
4定义本地变量th:object th:with
5通用方式属性修改th:attr th:attrprepend th:attrappend
6指定属性修改th:value th:href th:src ...
7文本值th:text th:utext
8片段指定th:fragment
9片段移除th:remove

变量选择

使用th:object属性指定一个对象,再使用*{}获取其对象的属性,例:

<div th:object="${session.user}"><p>Name: <span th:text="*{firstName}">Sebastian</span>.</p><p>Surname: <span th:text="*{lastName}">Pepper</span>.</p><p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>

Thymeleaf模板布局

  • 定义模板: th:fragment
  • 引用模板:~{templatename(模板名)::selector(片段名)}
  • 插入模板:th:insertth:replace
<footer th:fragment="copy"> &copy; 2011 The Good Thymes Virtual Grocery</footer><body><div th:insert="~{footer :: copy}"></div><div th:replace="~{footer :: copy}"></div>
</body>
<body>结果:<body><div><footer> &copy; 2011 The Good Thymes Virtual Grocery</footer></div><footer> &copy; 2011 The Good Thymes Virtual Grocery</footer></body>
</body>

devtools

      <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency>

修改页面后;ctrl+F9刷新效果;

java代码的修改,如果devtools热启动了,可能会引起一些bug,难以排查

国际化

实现步骤

  1. Spring Boot 在类路径根下查找messages资源绑定文件。文件名为:messages.properties
  2. 多语言可以定义多个消息文件,命名为messages_区域代码.properties。如:
    1. messages.properties:默认
    2. messages_zh_CN.properties:中文环境
    3. messages_en_US.properties:英语环境
  3. 程序中可以自动注入 MessageSource组件,获取国际化的配置项值
  4. 页面中可以使用表达式 #{}获取国际化的配置项值
    @Autowired  //国际化取消息用的组件MessageSource messageSource;@GetMapping("/haha")public String haha(HttpServletRequest request){Locale locale = request.getLocale();//利用代码的方式获取国际化配置文件中指定的配置项的值String login = messageSource.getMessage("login", null, locale);return login;}

错误处理

错误处理的自动配置都在ErrorMvcAutoConfiguration中,两大核心机制:

    1. SpringBoot 会自适应处理错误响应页面JSON数据
    1. SpringMVC的错误处理机制依然保留,MVC处理不了,才会交给boot进行处理
  1. 发生错误以后,到了SpringBoot,转发给/error路径,SpringBoot在底层写好一个 BasicErrorController的组件,专门处理这个请求
  2. 再通过与客户端的内容协商,选择返回json数据还是选择返回具体页面
    1. 如果是返回json则将信息转化为json形式返回
    2. 如果是返回页面,会找解析错误的自定义视图地址,如果找不到,默认的错误也就是error页
  3. 如果模板引擎路径templates下有 error.html页面,就直接渲染
  4. 容器中有一个错误视图解析器
    1. 如果发生了500、404、503、403 这些错误
      1. 如果有模板引擎,默认在 classpath:/templates/error/**精确码.html**
      2. 如果没有模板引擎,在静态资源文件夹下找 精确码.html
    2. 如果匹配不到精确码.html这些精确的错误页,就去找5xx.html4xx.html模糊匹配
      1. 如果有模板引擎,默认在 classpath:/templates/error/5xx.html
      2. 如果没有模板引擎,在静态资源文件夹下找 5xx.html

容器中有一个默认的名为 error 的 view; 提供了默认白页功能

建议错误处理:

  • 前后分离
    • 后台发生的所有错误,@ControllerAdvice + @ExceptionHandler进行统一异常处理。
  • 服务端页面渲染
    • 不可预知的一些,HTTP码表示的服务器或客户端错误
      • classpath:/templates/error/下面,放常用精确的错误码页面。500.html404.html
      • classpath:/templates/error/下面,放通用模糊匹配的错误码页面。 5xx.html4xx.html
    • 发生业务错误
      • 核心业务,每一种错误,都应该代码控制,跳转到自己定制的错误页
      • 通用业务classpath:/templates/error.html页面,显示错误信息

错误信息页面可以使用一些model数据用行内写法[[ ]]和变量取值${}(对这些错误的信息的model数据变量取值)加在页面上

可用的model数据:

  • timestamp:错误的时间信息
  • status:状态码
  • error:错误类型
  • trace:错误堆信息
  • message:错误信息
  • path:错误对应的路径

嵌入式容器

Servlet容器:管理、运行Servlet组件(Servlet、Filter、Listener)的环境,一般指服务器

自动配置原理

  • SpringBoot 默认嵌入Tomcat作为Servlet容器。
  • 自动配置类ServletWebServerFactoryAutoConfigurationEmbeddedWebServerFactoryCustomizerAutoConfiguration
  • 自动配置类开始分析功能。xxxxAutoConfiguration
  1. ServletWebServerFactoryAutoConfiguration 自动配置了嵌入式容器场景
  2. 绑定了ServerProperties配置类,所有和服务器有关的配置 server
  3. ServletWebServerFactoryAutoConfiguration 导入了 嵌入式的三大服务器 TomcatJettyUndertow
    1. 导入 TomcatJettyUndertow 都有条件注解。系统中有这个类才行(也就是导了包)
    2. 都给容器中 ServletWebServerFactory放了一个 web服务器工厂(造web服务器的)
    3. web服务器工厂 都有一个功能,getWebServer获取web服务器
    4. TomcatServletWebServerFactory 创建了 tomcat。
  4. ServletWebServerApplicationContextioc容器,启动的时候会调用创建web服务器
  5. Spring**容器刷新(启动)**的时候,会预留一个时机,用来刷新子容器。onRefresh() ,刷新子容器时会调用 onRefresh()

总结:

  • Web场景的Spring容器启动,在onRefresh的时候,会调用创建web服务器的方法。
  • Web服务器的创建是通过WebServerFactory搞定的。容器中又会根据导了什么包条件注解,启动相关的 服务器配置,默认EmbeddedTomcat会给容器中放一个 TomcatServletWebServerFactory,导致项目启动,自动创建出Tomcat
  • 修改server下的相关配置就可以修改服务器参数

全面接管SpringMVC(全手动)

全面接管SpringMVC即使用全手动模式配置SpringMVC,实现WebMvcConfiger接口,再在配置类上加上@EnableWebMvc注解,再手动配置SpringMvc

WebMvcAutoConfiguration

WebMvcAutoConfiguration是web场景的自动配置类,会自动导入一些配置:

  • 支持RESTful的filter:HiddenHttpMethodFilter
  • 支持非POST请求,请求体携带数据:FormContentFilter
  • 导入EnableWebMvcConfiguration:导入了HandlerAdapter,HandlerMapping,一些解析器等组件
  • WebMvcAutoConfigurationAdapter配置生效,会导入一些视图解析器,内容协商解析器,过滤器,静态资源链等相关的mvc底层组件

@EnableWebMvc

  1. @EnableWebMvc给容器中导入 DelegatingWebMvcConfiguration组件,他是 WebMvcConfigurationSupport
  2. WebMvcAutoConfiguration有一个核心的条件注解, @ConditionalOnMissingBean(WebMvcConfigurationSupport.class),容器中没有WebMvcConfigurationSupportWebMvcAutoConfiguration才生效.
  3. @EnableWebMvc 导入 WebMvcConfigurationSupport 导致 WebMvcAutoConfiguration 失效。导致禁用了默认行为

但是建议使用手自一体方式

Web新特性

ProblemDetails

  1. ProblemDetailsExceptionHandler是一个@ControllerAdivce,集中处理系统的异常
  2. ProblemDetailsExceptionHandler只能处理springmvc的一些指定异常
  3. ProblemDetails默认是关闭的

开启ProblemDetails返回, 使用新的MediaType

Content-Type: application/problem+json+ 额外扩展返回,例:

{"type": "about:blank","title": "Method Not Allowed","status": 405,"detail": "Method 'POST' is not supported.","instance": "/list"
}

函数式Web

步骤:

  1. 给容器中放一个Bean:RouterFunction<ServerResponse>
    1. 核心四大对象:
      1. RouterFunction:定义路由信息(请求内容,接收请求的handler)
      2. RequestPredicate:定义请求(请求方式,请求参数)
      3. ServerRequest:封装请求完整信息
      4. ServerResponse:封装响应完整信息
  2. 先定义路由信息,再定义请求,最后封装完整请求和响应的信息,例:
@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);@Beanpublic RouterFunction<ServerResponse> routerFunction(MyUserHandler userHandler) {return route().GET("/{user}", ACCEPT_JSON, userHandler::getUser).GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers).DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser).build();}}
@Component
public class MyUserHandler {public ServerResponse getUser(ServerRequest request) {...//具体业务return ServerResponse.ok().build();}public ServerResponse getUserCustomers(ServerRequest request) {...//要获取请求的信息可以使用request对象的一系列方法return ServerResponse.ok().body(...);//在body中的对象,会以json形式返回}public ServerResponse deleteUser(ServerRequest request) {...return ServerResponse.ok().build();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/751701.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

训练YOLOv8m时AMP显示v8n

在训练Yolov8模型时&#xff0c;使用AMP&#xff08;Automatic Mixed Precision&#xff09;可以加速训练过程并减少显存的使用。AMP是一种混合精度训练技术&#xff0c;它通过将模型参数的计算转换为低精度&#xff08;如半精度&#xff09;来提高训练速度&#xff0c;同时保持…

文献阅读及笔记

每个阶段&#xff0c;该看什么文献 当我们刚开始接触课题时&#xff0c;对这个研究方向一无所知&#xff0c;可以选择硕博学位论文、领域大牛的文献综述当我们已经对课题有了解&#xff0c;处于深化认识的阶段&#xff0c;可以选择行业最新的论文&#xff0c;领域大牛的文献综…

一种动态联动的实现方法

安防领域中的联动规则 有安防领域相关的开发经历的人知道&#xff0c;IPCamera可以配置使能“侦测”功能&#xff0c;并且指定仅针对图像传感器的某个区载进行侦测。除了基本的“移动侦测"外&#xff0c;侦测的功能点还有细化的类别&#xff0c;如人员侦测、车辆侦测、烟…

《手把手教你》系列技巧篇(三十七)-java+ selenium自动化测试-日历时间控件-上篇(详解教程)

1.简介 我们在实际工作中&#xff0c;有可能遇到有些web产品&#xff0c;网页上有一些时间选择&#xff0c;然后支持按照不同时间段范围去筛选数据。网页上日历控件一般&#xff0c;是一个文本输入框&#xff0c;鼠标点击&#xff0c;就会弹出日历界面&#xff0c;可以选择具体…

upload文件上传漏洞复现

什么是文件上传漏洞&#xff1a; 文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷&#xff0c;而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马&#xff0c;病毒&#xff0c;恶意脚本或者WebShell等。“…

c语言的指针函数和函数指针的区别

指针函数是一个返回指针的函数。它的声明类似于普通函数&#xff0c;但是返回类型是指针类型而不是普通的数据类型。指针函数可以用来返回数组、结构体、对象等复杂的数据类型。 指针函数的定义和使用方式与普通函数类似&#xff0c;可以通过调用函数名来执行函数&#xff0c;…

Qt入门之概述

1.1 介绍 Qt&#xff1a;它是一套基于C的跨平台开发框架&#xff0c;包括GUI、字符串、多线程处理、文件IO、网络IO、3D渲染等时间&#xff1a;它诞生于1991年&#xff0c;由Haavard Nord和Eirik Chambe-Eng共同缔造发展&#xff1a;历经Qt Company、Nokia、Digia多个公司开发…

Seata 2.x 系列【9】事务会话存储模式

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 存储模…

在linux上发起get和post请,怎么写

获取用户 curl --location --request GET http://127.0.0.1:8888/API/UserService/GetUserInfo?&token123456789&userId66666666 下面接口参数两部分&#xff0c;url传参和body 新增用户 curl --location --request POST http://127.0.0.1:8888/API/UserService/AddUs…

ubuntu安装docker的详细教程

检查卸载老版本docker ubuntu下自带了docker的库&#xff0c;不需要添加新的源。 但是ubuntu自带的docker版本太低&#xff0c;需要先卸载旧的再安装新的。 注&#xff1a;docker的旧版本不一定被称为docker&#xff0c;docker.io 或 docker-engine也有可能&#xff0c;所以卸…

springboot RocketMQ 客户端 日志配置 rocketmq_client.log过大

项目集成rocketMQ后&#xff0c;日志持续增大&#xff0c;导致磁盘空间逐渐减少&#xff0c;参考官方文档 来正确配置。 打印客户端日志 RocketMQ 的 TCP Java SDK 基于 SLF4J 接口编程。 JavaSDK1.7.8.Final 版本及以上 RocketMQ 的 Java SDK 1.7.8.Final 已内置了日志实现&…

有关整数和浮点数在内存中存储

1. 整数在内存中的存储 整数的2进制表⽰⽅法有三种&#xff0c;即原码、反码和补码 三种表⽰⽅法均有符号位和数值位两部分&#xff0c;符号位都是⽤0表⽰“正”&#xff0c;⽤1表⽰“负”&#xff0c;⽽数值位最 ⾼位的⼀位是被当做符号位&#xff0c;剩余的都是数值位。 正…

常用芯片学习——BME280芯片

BME280 温湿度气压传感器 芯片介绍 BME280是基于成熟传感原理的组合数字湿度、压力和温度传感器。该传感器块采用极为紧凑的金属盖LGA封装&#xff0c;占地面积仅为2.5x2.5mm2&#xff0c;高度为0.93mm。该传感器提供I2C以及SPI接口。它的小尺寸和低功耗允许在电池驱动的设备…

TCP-IP 知识汇总

开放式系统互联模型------国际化标准组织ISO提出----协议组&#xff08;协议模型&#xff09; 应用层&#xff1a;接收用户数据&#xff0c;人机交互的接口 表示层&#xff1a;将编码转换为二进制&#xff08;加密、解密&#xff09;---统一格式 会话层&#xff1a;针对传输…

二叉树<II>:二叉树的四种遍历方式代码实现Python3

今天我们来介绍的是二叉树的「前序」、「中序」、「后序」、「层序」四种遍历方式如何用代码实现。 还不知道这四种遍历方式原理的可以看另一篇文章&#xff1a;二叉树&#xff1c;I&#xff1e;&#xff1a;概念及二叉树的前序遍历、中序遍历、后序遍历原理 1. 相关题目 这…

springboot279基于javaweb的影院订票系统的设计与实现

影院订票系统 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本影院订票系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大…

MySQL语法分类 DML

DML 增删改表中数据 添加数据 //注意: //1.列名和值一一对应 //2.如果不定义列名需要给所有列赋值 //3.除了数字其他类型的值需要引号 insert into 表名(列名1&#xff0c;列名2,...列名n ) values(值1,值2,...值n );//这句需要给所有列赋值 insert into 表名(值1,值2,...值n…

2024.4.17周报

目录 摘要 Abstract 文献阅读&#xff1a;耦合时间和非时间序列模型模拟城市洪涝区洪水深度 现有问题 提出方法 创新点 XGBoost和LSTM耦合模型 XGBoost算法 ​编辑 LSTM&#xff08;长短期记忆网络&#xff09; 耦合模型 研究实验 数据集 评估指标 研究目的 洪水…

Orbit 使用指南 03 | 与刚体交互 | Isaac Sim | Omniverse

如是我闻&#xff1a; “在之前的指南中&#xff0c;我们讨论了独立脚本&#xff08; standalone script&#xff09;的基本工作原理以及如何在模拟器中生成不同的对象&#xff08;prims&#xff09;。在指南03中&#xff0c;我们将展示如何创建并与刚体进行交互。为此&#xf…

48、C++/堆区动态内存管理 类中特殊成员函数学习20240313

一、设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 代码&#xff1a; #include <iostream>us…