docs: 移动文档
This commit is contained in:
parent
5fb5f7c524
commit
da5a5d1314
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
@ -1,433 +0,0 @@
|
||||||
# `SpringMVC`笔记
|
|
||||||
|
|
||||||
- 公共AI网站:https://chatgptplus.cn/
|
|
||||||
- vue3官网:https://cn.vuejs.org/
|
|
||||||
- SpringBoot官网:https://docs.spring.io/spring-boot/index.html
|
|
||||||
|
|
||||||
## 访问控制
|
|
||||||
|
|
||||||
请求地址时返回对应的网页文件
|
|
||||||
|
|
||||||
- `@RestController`用于返回对象格式的内容,在后面会使用`ModelAndView`可以返回网页文件
|
|
||||||
- `@Controller`用于返回网页文件
|
|
||||||
|
|
||||||
### 环境要求
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- thymeleaf -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- devtools -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<!-- lombok -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.36</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 错误页面设置
|
|
||||||
|
|
||||||
在这个路径下可以配置错误码要访问的页面,也就是可以自定义页面内容
|
|
||||||
|
|
||||||
![image-20250122171536808](./images/SpringMVC笔记/image-20250122171536808.png)
|
|
||||||
|
|
||||||
### 使用`@Controller`
|
|
||||||
|
|
||||||
返回需要访问的HTML内容页面,最后返回的字符串就是页面,这个页面位于`templates`目录下
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RequestMapping("/use")
|
|
||||||
@Controller
|
|
||||||
public class UseController {
|
|
||||||
|
|
||||||
// 带参数访问
|
|
||||||
@RequestMapping(value = "hello", method = RequestMethod.GET, params = {"name"})
|
|
||||||
public String hello() {
|
|
||||||
return "hello";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("jumpPage")
|
|
||||||
public String jumpPage() {
|
|
||||||
return "jumpPage";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("index")
|
|
||||||
public String quick() {
|
|
||||||
return "user";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转的页面
|
|
||||||
@GetMapping("toJump")
|
|
||||||
public String toJump() {
|
|
||||||
return "redirect:jumpPage";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
如果在使用`@Controller`需要返回JSON内容,需要在控制器方法上加上`@ResponseBody`
|
|
||||||
|
|
||||||
```java
|
|
||||||
@GetMapping("getJson")
|
|
||||||
@ResponseBody
|
|
||||||
public List<String> getJson() {
|
|
||||||
ArrayList<String> list = new ArrayList<>();
|
|
||||||
list.add("a");
|
|
||||||
list.add("b");
|
|
||||||
list.add("c");
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 将视图和模型拆开
|
|
||||||
|
|
||||||
```java
|
|
||||||
// 将视图和模型拆开
|
|
||||||
@GetMapping("page/test3")
|
|
||||||
public String test3(Model model) {
|
|
||||||
model.addAttribute("test3", "测试3");
|
|
||||||
return "page/test3";
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 使用`@RestController`
|
|
||||||
|
|
||||||
#### 使用方式1
|
|
||||||
|
|
||||||
如果使用`@RestController`那么返回的就是JSON对象,但是这时候要想返回网页文件,需要使用`ModelAndView`
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RequestMapping("userRest")
|
|
||||||
@RestController
|
|
||||||
public class UseRestController {
|
|
||||||
|
|
||||||
@GetMapping("page/test")
|
|
||||||
public ModelAndView test() {
|
|
||||||
ModelAndView modelAndView = new ModelAndView();
|
|
||||||
modelAndView.setViewName("page/test");
|
|
||||||
modelAndView.addObject("message", "这是消息内容");
|
|
||||||
return modelAndView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
我们引入了`thymeleaf`所以有以下内容`<h4 th:text="'消息:'+ ${message}"></h4>`
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>使用RestController返回页面信息</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h3>使用RestController返回页面信息</h3>
|
|
||||||
<h4 th:text="'消息:'+ ${message}"></h4>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
```
|
|
||||||
|
|
||||||
> 其中`modelAndView.addObject("message", "这是消息内容");`是可选的
|
|
||||||
|
|
||||||
#### 使用方式2
|
|
||||||
|
|
||||||
在控制器方法上使用`ModelAndView`
|
|
||||||
|
|
||||||
```java
|
|
||||||
@GetMapping("page/test2")
|
|
||||||
public ModelAndView test2(ModelAndView modelAndView) {
|
|
||||||
modelAndView.addObject("hello", "你好");
|
|
||||||
modelAndView.setViewName("page/test2");
|
|
||||||
return modelAndView;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thymeleaf快速入门
|
|
||||||
|
|
||||||
Thymeleaf 是一种现代化的 Java 模板引擎,广泛用于生成 HTML、XML、JavaScript 等内容。它有许多内置的指令和功能,用于渲染动态内容、条件渲染、循环、处理表达式等。以下是 Thymeleaf 中常见的指令和属性的详细介绍:
|
|
||||||
|
|
||||||
### 1. **`th:text`**
|
|
||||||
|
|
||||||
用于替换元素的文本内容。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<span th:text="${message}"></span>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `${message}` 的值会替换 `span` 元素的文本。
|
|
||||||
|
|
||||||
> 如果需要格式化日期,需要注意,使用`temporals`进行操作
|
|
||||||
>
|
|
||||||
> ```html
|
|
||||||
> <td class="text-success" th:text="${#temporals.format(bill.transactionDate,'yyyy-MM-dd HH:mm:ss')}"></td>
|
|
||||||
> ```
|
|
||||||
|
|
||||||
### 2. **`th:utext`**
|
|
||||||
|
|
||||||
用于替换元素的文本内容,并允许处理 HTML 标签(不会转义 HTML)。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<span th:utext="${htmlContent}"></span>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `${htmlContent}` 的内容直接插入,并解析其中的 HTML。
|
|
||||||
|
|
||||||
### 3. **`th:value`**
|
|
||||||
|
|
||||||
设置表单元素的 `value` 属性,通常用于输入框或选择框。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<input type="text" th:value="${user.name}" />
|
|
||||||
```
|
|
||||||
|
|
||||||
- 将 `${user.name}` 的值赋给该输入框的 `value` 属性。
|
|
||||||
|
|
||||||
### 4. **`th:each`**
|
|
||||||
|
|
||||||
用于循环遍历集合或数组。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<ul>
|
|
||||||
<li th:each="person : ${people}">
|
|
||||||
<span th:text="${person.name}"></span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 遍历 `people` 集合,输出每个 `person.name`。
|
|
||||||
|
|
||||||
### 5. **`th:if`**
|
|
||||||
|
|
||||||
用于条件渲染,只有满足条件时才渲染元素。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:if="${user.isAdmin}">
|
|
||||||
<p>Welcome, admin!</p>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 如果 `user.isAdmin` 为 `true`,渲染该 `div`。
|
|
||||||
|
|
||||||
### 6. **`th:unless`**
|
|
||||||
|
|
||||||
与 `th:if` 相反,只有条件为 `false` 时才渲染元素。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:unless="${user.isAdmin}">
|
|
||||||
<p>You are not an admin!</p>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 如果 `user.isAdmin` 为 `false`,渲染该 `div`。
|
|
||||||
|
|
||||||
### 7. **`th:attr`**
|
|
||||||
|
|
||||||
用于设置元素的多个属性。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<img th:attr="src=${imageUrl}" th:attr="alt=${imageDescription}" />
|
|
||||||
```
|
|
||||||
|
|
||||||
- 设置 `img` 元素的 `src` 和 `alt` 属性。
|
|
||||||
|
|
||||||
### 8. **`th:src` / `th:href`**
|
|
||||||
|
|
||||||
用于动态设置 `src` 或 `href` 属性。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<img th:src="@{${imageUrl}}" alt="Image">
|
|
||||||
<a th:href="@{${linkUrl}}">Click Here</a>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `th:src` 用于设置图片的 `src` 属性,`th:href` 用于设置链接的 `href` 属性。
|
|
||||||
|
|
||||||
### 9. **`th:class`**
|
|
||||||
|
|
||||||
动态设置 `class` 属性,支持条件表达式。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:class="${isActive} ? 'active' : 'inactive'">...</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 如果 `isActive` 为 `true`,设置 `class="active"`,否则为 `inactive`。
|
|
||||||
|
|
||||||
### 10. **`th:classappend` / `th:classprepend`**
|
|
||||||
|
|
||||||
分别在现有的 `class` 属性上追加或前置新类。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:classappend="'newClass'">...</div>
|
|
||||||
<div th:classprepend="'prefixClass'">...</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `th:classappend` 会将新的类追加到现有类的后面。
|
|
||||||
- `th:classprepend` 会将新的类添加到现有类的前面。
|
|
||||||
|
|
||||||
### 11. **`th:id`**
|
|
||||||
|
|
||||||
设置元素的 `id` 属性。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<input type="text" th:id="${elementId}" />
|
|
||||||
```
|
|
||||||
|
|
||||||
- 设置 `input` 元素的 `id` 为 `${elementId}` 的值。
|
|
||||||
|
|
||||||
### 12. **`th:action`**
|
|
||||||
|
|
||||||
设置表单的 `action` 属性。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<form th:action="@{/submitForm}" method="post">
|
|
||||||
<!-- form fields -->
|
|
||||||
</form>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 设置表单的 `action` 为 `/submitForm`。
|
|
||||||
|
|
||||||
### 13. **`th:style`**
|
|
||||||
|
|
||||||
设置元素的 `style` 属性。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:style="'color: ' + ${color}"></div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 动态设置 `style` 属性,`${color}` 的值会成为 `color` 样式的值。
|
|
||||||
|
|
||||||
### 14. **`th:fragment`**
|
|
||||||
|
|
||||||
定义一个可重用的片段,通常在模板中调用。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:fragment="userFragment">
|
|
||||||
<p>Welcome, <span th:text="${user.name}"></span></p>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 定义一个 `userFragment` 片段,可以在其他模板中引用。
|
|
||||||
|
|
||||||
### 15. **`th:replace`**
|
|
||||||
|
|
||||||
替换当前元素,并将一个片段或其他模板插入其中。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:replace="~{userFragment}"></div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `th:replace` 会将 `userFragment` 片段的内容插入到当前 `div` 中。
|
|
||||||
|
|
||||||
### 16. **`th:include`**
|
|
||||||
|
|
||||||
将另一个模板的内容插入当前模板中,但不会替换当前元素。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:include="~{userFragment}"></div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 插入 `userFragment` 的内容,但保留当前 `div` 元素。
|
|
||||||
|
|
||||||
### 17. **`th:with`**
|
|
||||||
|
|
||||||
局部变量声明,用于在模板中定义临时变量。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:with="total=${cart.totalPrice}">
|
|
||||||
<p th:text="'Total price: ' + ${total}"></p>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `th:with` 用于在当前元素的上下文中定义变量,类似于局部变量。
|
|
||||||
|
|
||||||
### 18. **`th:block`**
|
|
||||||
|
|
||||||
在模板中定义一个不会渲染任何 HTML 标签的块元素。用于组合多个元素。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<th:block th:each="person : ${people}">
|
|
||||||
<p th:text="${person.name}"></p>
|
|
||||||
</th:block>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `th:block` 不会渲染任何标签,但可以用来包装多个元素进行条件判断或循环。
|
|
||||||
|
|
||||||
### 19. **`th:switch` / `th:case`**
|
|
||||||
|
|
||||||
类似于 Java 中的 `switch` 语句,用于条件选择。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div th:switch="${status}">
|
|
||||||
<span th:case="'active'">Active</span>
|
|
||||||
<span th:case="'inactive'">Inactive</span>
|
|
||||||
<span th:case="*">Unknown</span>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
- 根据 `${status}` 的值,渲染对应的 `span` 元素。
|
|
||||||
|
|
||||||
### 20. **`th:object`**
|
|
||||||
|
|
||||||
用来为表单元素绑定一个对象。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<form th:action="@{/submit}" th:object="${user}">
|
|
||||||
<input type="text" th:field="*{name}" />
|
|
||||||
<input type="text" th:field="*{email}" />
|
|
||||||
<button type="submit">Submit</button>
|
|
||||||
</form>
|
|
||||||
```
|
|
||||||
|
|
||||||
- `th:object` 绑定整个表单到 `user` 对象。
|
|
||||||
- `th:field` 用于绑定每个表单字段到对象的属性。
|
|
||||||
|
|
||||||
### 21. **`th:href` / `th:src`**
|
|
||||||
|
|
||||||
用于动态设置 URL 值。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<a th:href="@{/users/{id}(id=${user.id})}">Profile</a>
|
|
||||||
<img th:src="@{/images/{imageName}(imageName=${image.name})}" />
|
|
||||||
```
|
|
||||||
|
|
||||||
- 动态生成 URL,支持路径变量的替换。
|
|
||||||
|
|
||||||
### 22. **`th:placeholder`**
|
|
||||||
|
|
||||||
设置表单输入框的 `placeholder` 属性。
|
|
||||||
|
|
||||||
```html
|
|
||||||
<input type="text" th:placeholder="${placeholderText}" />
|
|
||||||
```
|
|
||||||
|
|
||||||
- 设置 `input` 的 `placeholder` 为 `${placeholderText}` 的值。
|
|
||||||
|
|
||||||
------
|
|
||||||
|
|
||||||
### 总结
|
|
||||||
|
|
||||||
Thymeleaf 提供了许多强大的指令来处理模板中的动态内容、条件渲染、迭代和属性绑定。常见的指令包括:
|
|
||||||
|
|
||||||
- `th:text`、`th:utext`:用于设置文本内容。
|
|
||||||
- `th:each`:用于循环遍历。
|
|
||||||
- `th:if`、`th:unless`:用于条件判断。
|
|
||||||
- `th:attr`、`th:id`、`th:class`:用于设置 HTML 属性。
|
|
||||||
- `th:replace`、`th:include`:用于片段包含。
|
|
||||||
- `th:switch`、`th:case`:用于类似 `switch` 的条件语句。
|
|
|
@ -9,6 +9,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
@ -39,4 +40,16 @@ public class ThymeleafController {
|
||||||
|
|
||||||
return "thymeleaf/bill";
|
return "thymeleaf/bill";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 不能包含age,header必须匹配header
|
||||||
|
@GetMapping(value = "href-test", params = {"!age"}, headers = {"host=localhost:8080"})
|
||||||
|
public String hrefTest() {
|
||||||
|
return "thymeleaf/href-test";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ?表示可以任意字符
|
||||||
|
@RequestMapping("a?e")
|
||||||
|
public String test() {
|
||||||
|
return "test/test";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" rel="stylesheet">
|
||||||
|
<script crossorigin="anonymous" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>标签跳转测试</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p><a class="link-primary link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover"
|
||||||
|
th:href="@{/thymeleaf/href-test(name='aaa',password='123')}">
|
||||||
|
链接自动转成?格式
|
||||||
|
</a></p>
|
||||||
|
<p><a class="link-secondary link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover"
|
||||||
|
th:href="@{/thymeleaf/href-test(name='aaa',password='123',age=16)}">
|
||||||
|
请求跳转链接包含age,包含age错误码:400
|
||||||
|
</a></p>
|
||||||
|
<p><a class="link-success link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" th:href="@{/thymeleaf/age}">
|
||||||
|
匹配ant路径
|
||||||
|
</a></p>
|
||||||
|
<p><a class="link-danger link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="#">Danger link</a></p>
|
||||||
|
<p><a class="link-warning link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="#">Warning link</a></p>
|
||||||
|
<p><a class="link-info link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="#">Info link</a></p>
|
||||||
|
<p><a class="link--offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="#">Light link</a></p>
|
||||||
|
<p><a class="link-dark link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="#">Dark link</a></p>
|
||||||
|
<p><a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-75-hover" href="#">Emphasis link</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue