March 2, 2023

SpringBoot

前言

时隔n年终于来到了SSM框架的最后一步SpringBoot,终于要逃离配置地狱了吗,想想都是心动的不得了,也感觉这段时间自己确实好像很求学,不知道自己是咋了。。

什么是微服务架构

微服务架构(通常简称为微服务)是指开发应用所用的一种架构形式。 通过微服务,可将大型应用分解成多个独立的组件,其中每个组件都有各自的责任领域。 在处理一个用户请求时,基于微服务的应用可能会调用许多内部微服务来共同生成其响应。 容器是微服务架构的绝佳示例,因为它们可让您专注于开发服务,而无需担心依赖项。
最初的架构图如下:

最后随着需求变多,用户量变大,数据库公用可能出现冲突矛盾,因此微服务架构诞生:

创建第一个SpringBoot程序

首先你可以再SpringBoot的官网进行创建,当然IDEA也帮你准备了创建方式(本质还是从官网创建),流程如下:
选择Spring Initializr
image.png
设置好一些参数后进入下一步,选择SpringBoot DevTools、Spring Web
image.png

目录结构

这些是为我们开发提前做好一些工作,之后你就创建了你第一个SpringBoot程序了,项目结构图如下:
image.png
其中Application文件就是我们SpringBoot的主程序了,之后启动web服务器就是允许这个文件。SpringBoot本质上还是一个Tomcat程序,它内置了tomcat服务器,并且经过了改动,因此启动比Tomcat迅速许多。
结构树状图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
E:\CTFLEARNING\JAVA\SPRINGBOOT
├─.idea
│ └─libraries
├─.mvn
│ └─wrapper
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─boogipop
│ │ │ └─springboot
│ │ └─resources
│ │ ├─static
│ │ └─templates
│ └─test
│ └─java
│ └─com
│ └─boogipop
│ └─springboot
└─target
├─classes
│ └─com
│ └─boogipop
│ └─springboot
└─generated-sources
└─annotations

创建一个简单的Controller

我们回顾一下SpringMVC,在其中我们需要配置3个xml文件,Spring-Servlet.xml、Mybatis-config.xml、ApplicationContext.xml,其实还有很多有关Bean的xml文件,面对这一现象我们可以称之为配置地狱了,而SpringBoot啥配置文件都不需要,唯一需要的就是一个application.properties,这个后面会讲
所以总结起来SpringBoot真的是一个十分优秀的框架,谁能拒绝呢?
那么我们正式开始创建SpringBoot程序,我们再Application.java文件的同级目录,创建我们的Controller文件夹,然后在里面写一个Controller:
image.png
配置结束后直接启动程序即可:
image.png

配置端口

很多人也看到了,我的SpringBoot程序开放端口为7878,正常Tomcat和SpringBoot也都是8080端口,这些属性都可以在application.properties中配置:
image.png
这些配置在之后也会慢慢的接触,先暂时挖个坑拉

SpringBoot自动装配原理

具体请参考上述博客园文章,内容挺复杂的,看看就好

Yaml语法讲解

YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)。
其实yaml的语法看菜鸟教程就懂了,还有就是在学Docker-compose编写yml文件时肯定也懂了,但还是温习一下

语法特点

数据类型

Yaml一共支持3种类型的元素:

每个数据类型的使用案例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#对象的用法
Person:
name: boogipop
age: 18
#子对象
Dog:
name: Kino
age: 7

#数组用法,下面例子表示Human:["YourName","YourAge","Nothing"]
Human:
- YourName
- YourAge
- Nothing
#或者
Human2: [a,b,c]
#字成员用法 A:[1,2,[1,2,3]]
A:
- 1
- 2
-
- 1
- 2
- 3
#还有复杂一点的用法,companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
companies:
-
id: 1
name: company1
price: 200w
-
id: 2
name: company2
price: 300w
#复合结构
languages:
- ruby
- perl
- python
websites:
Yaml: yaml.org
ruby: ruby.org
python: python.org

#纯量包括:字符串,布尔值,整数,浮点数,Null,时间,日期
boolean:
- TRUE #或者true,这里的true就是纯量
- FALSE
float:
- 3.14 #3.14也是纯量,纯量的意思就是一些常量
- 1.1415
int:
- 1
- 2
null:
nodename: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- hello
- "hello" #加不加引号都无所谓
data:
- 2022-12-12 #日期必须以yyyy-MM-dd的格式
datatime:
- 2022-12-12T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区

给属性赋值的几种方法

方式一:传统Value赋值

使用Spring的@Value注解进行赋值,并且配合@Component注解注册bean,之后直接取出即可
image.png

方式二:Yaml配置文件绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.boogipop.springboot.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "user")
public class User {
public User() {
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
", age=" + age +
'}';
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

private String username;
private String address;
private int age;


}

通过yaml配置文件即可完成属性赋值,就以上述实体类来进行赋值:

1
2
3
4
User:
username: Boogipop
address: HaiKou-MeiLan
age: 19

之后在实体类上通过注解绑定配置文件:
image.png
prefix="user"表示将我们的配置文件中User下面的属性赋值给实体类,配置文件的名字由硬性要求,那就是application.yml
image.png
目录结构如下:
image.png
接下来可以测试一下:
image.png

方式三:Properties配置文件绑定

这种方法和yml差不多,都是通过配置文件进行指定

1
2
3
user. nmae=Boogipop
address=Haikou
age=19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.boogipop.springboot.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:user.properties")

public class User {
@Value("${username}")
private String username;
@Value("${address}")
private String address;
@Value("${age}")
private int age;
public User() {
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
", age=" + age +
'}';
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;、
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

JSR303校验

详情请参考

多环境配置和配置文件位置

SpringBoot中有四个地方可以存放我们的配置文件

并且可以通过指定spring.profiles.active来选择环境,多环境配置文件的名称以application-xxx.yml(properties)来命名,其中xxx表示不同环境,指定环境只需要让spring.profiles.active=xxx即可

静态资源导入

这里就直接上一下结论了,假如有兴趣分析源码的可以看:

SpringBoot首页设置

你可以直接把index.html放在templates目录或者static文件夹下,static没有就回去templates找,更多方法请看:https://www.hangge.com/blog/cache/detail_2528.html

Thymeleaf模板引擎

一个是依赖:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

另外一个就是语法问题了:
Sir this way↓

Configuration配置

我们可以在一个类上加上@configuration注解,来代表一个配置类,配置类可以配置拦截器,等等:
并且我们需要实现WebMvcConfigurer接口
image.png
从上图中可以看到可重写方法,里面有很多,比如addviewcontroller就可以手动加一个controller

员工管理系统 | 搭建

我也不知道狂神犯什么病,他居然不用mybatis,就直接写个map模拟数据,逆天,那有啥办法,先跟着来一遍然后后面换掉
POJO:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.boogipop.springboot.pojo;

import java.util.Date;

public class Employee {
private Integer id;
private String name;
private String email;
private Integer gender;
private Department department;

public Employee(Integer id, String name, String email, Integer gender, Department department, Date birth) {
this.id = id;
this.name = name;
this.email = email;
this.gender = gender;
this.department = department;
this.birth = birth;
}

public Employee() {
}

@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", gender=" + gender +
", department=" + department +
", birth=" + birth +
'}';
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public Integer getGender() {
return gender;
}

public void setGender(Integer gender) {
this.gender = gender;
}

public Department getDepartment() {
return department;
}

public void setDepartment(Department department) {
this.department = department;
}

public Date getBirth() {
return birth;
}

public void setBirth(Date birth) {
this.birth = birth;
}

private Date birth;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.boogipop.springboot.pojo;

public class Department {
private Integer id;
private String departmentName;

public Department() {
}

public Department(Integer id, String departmentName) {
this.id = id;
this.departmentName = departmentName;
}

@Override
public String toString() {
return "Department{" +
"id=" + id +
", departmentName='" + departmentName + '\'' +
'}';
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getDepartmentName() {
return departmentName;
}

public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
}

Mapper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.boogipop.springboot.mapper;

import com.boogipop.springboot.pojo.Department;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class DepartmentMapper {
private static int initid=5;
private static Map<String,Department> departments=null;
static {
departments=new HashMap<>();
departments.put("1",new Department(1,"斧乃木"));
departments.put("2",new Department(2,"八九寺真宵"));
departments.put("3",new Department(3,"阿良良木历"));
departments.put("4",new Department(4,"不吉波普不笑"));
}
//增,改
public void adddepartment(Department department){
//主键自增
if(department.getId()==null){
department.setId(initid++);
}
departments.put(String.valueOf(department.getId()),department);
}
//获得所有部门
public Collection<Department> getalldepartment(){
return departments.values();
}
//删
public void deletedepartment(String id){
departments.remove(id);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.boogipop.springboot.mapper;

import com.boogipop.springboot.pojo.Department;
import com.boogipop.springboot.pojo.Employee;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class EmployeeMapper {
private static Map<String, Employee> employees=null;
private static Integer initid=5;
static {
employees=new HashMap<>();
employees.put("1",new Employee(1,"Boh1","[email protected]",1,new Department(1,"斧乃木"),new Date()));
employees.put("2",new Employee(2,"Boh2","[email protected]",1,new Department(1,"斧乃木"),new Date()));
employees.put("3",new Employee(3,"Boh3","[email protected]",1,new Department(1,"斧乃木"),new Date()));
employees.put("4",new Employee(4,"Boh4","[email protected]",1,new Department(1,"斧乃木"),new Date()));
}
//增 改
public void addemployee(Employee employee){
//主键自增
if(employee.getId()==null){
employee.setId(initid++);
}
employees.put(String.valueOf(employee.getId()),employee);
}
//查询所有
public Collection<Employee> getallemployees(){
return employees.values();
}
//删除
public void delete(String id){
employees.remove(id);
}
}

搭建好了这两个之后就是准备静态资源了,目录结构如下:
image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<title>Dashboard Template for Bootstrap</title>

<!-- Bootstrap core CSS -->
<link th:href="@{../static/css/bootstrap.min.css}" rel="stylesheet">

<!-- Custom styles for this template -->
<link th:href="@{../static/css/dashboard.css}" rel="stylesheet">
</head>

<body>
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">Company name</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="#">Sign out</a>
</li>
</ul>
</nav>

<div class="container-fluid">
<div class="row">
<nav class="col-md-2 d-none d-md-block bg-light sidebar">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">
<span data-feather="home"></span>
Dashboard <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file"></span>
Orders
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="shopping-cart"></span>
Products
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="users"></span>
Customers
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="bar-chart-2"></span>
Reports
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="layers"></span>
Integrations
</a>
</li>
</ul>

<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Saved reports</span>
<a class="d-flex align-items-center text-muted" href="#">
<span data-feather="plus-circle"></span>
</a>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Current month
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Last quarter
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Social engagement
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Year-end sale
</a>
</li>
</ul>
</div>
</nav>

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
<h1 class="h2">Dashboard</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group mr-2">
<button class="btn btn-sm btn-outline-secondary">Share</button>
<button class="btn btn-sm btn-outline-secondary">Export</button>
</div>
<button class="btn btn-sm btn-outline-secondary dropdown-toggle">
<span data-feather="calendar"></span>
This week
</button>
</div>
</div>

<canvas class="my-4" id="myChart" width="900" height="380"></canvas>

<h2>Section title</h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>#</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1,001</td>
<td>Lorem</td>
<td>ipsum</td>
<td>dolor</td>
<td>sit</td>
</tr>
<tr>
<td>1,002</td>
<td>amet</td>
<td>consectetur</td>
<td>adipiscing</td>
<td>elit</td>
</tr>
<tr>
<td>1,003</td>
<td>Integer</td>
<td>nec</td>
<td>odio</td>
<td>Praesent</td>
</tr>
<tr>
<td>1,003</td>
<td>libero</td>
<td>Sed</td>
<td>cursus</td>
<td>ante</td>
</tr>
<tr>
<td>1,004</td>
<td>dapibus</td>
<td>diam</td>
<td>Sed</td>
<td>nisi</td>
</tr>
<tr>
<td>1,005</td>
<td>Nulla</td>
<td>quis</td>
<td>sem</td>
<td>at</td>
</tr>
<tr>
<td>1,006</td>
<td>nibh</td>
<td>elementum</td>
<td>imperdiet</td>
<td>Duis</td>
</tr>
<tr>
<td>1,007</td>
<td>sagittis</td>
<td>ipsum</td>
<td>Praesent</td>
<td>mauris</td>
</tr>
<tr>
<td>1,008</td>
<td>Fusce</td>
<td>nec</td>
<td>tellus</td>
<td>sed</td>
</tr>
<tr>
<td>1,009</td>
<td>augue</td>
<td>semper</td>
<td>porta</td>
<td>Mauris</td>
</tr>
<tr>
<td>1,010</td>
<td>massa</td>
<td>Vestibulum</td>
<td>lacinia</td>
<td>arcu</td>
</tr>
<tr>
<td>1,011</td>
<td>eget</td>
<td>nulla</td>
<td>Class</td>
<td>aptent</td>
</tr>
<tr>
<td>1,012</td>
<td>taciti</td>
<td>sociosqu</td>
<td>ad</td>
<td>litora</td>
</tr>
<tr>
<td>1,013</td>
<td>torquent</td>
<td>per</td>
<td>conubia</td>
<td>nostra</td>
</tr>
<tr>
<td>1,014</td>
<td>per</td>
<td>inceptos</td>
<td>himenaeos</td>
<td>Curabitur</td>
</tr>
<tr>
<td>1,015</td>
<td>sodales</td>
<td>ligula</td>
<td>in</td>
<td>libero</td>
</tr>
</tbody>
</table>
</div>
</main>
</div>
</div>

<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script th:src="@{../static/js/jquery-slim.min.js}"><\/script>')</script>
<script th:src="@{../static/js/popper.min.js}"></script>
<script th:src="@{../static/js/bootstrap.min.js}"></script>

<!-- Icons -->
<script src="https://unpkg.com/feather-icons/dist/feather.min.js"></script>
<script>
feather.replace()
</script>

<!-- Graphs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
datasets: [{
data: [15339, 21345, 18483, 24003, 23489, 24092, 12034],
lineTension: 0,
backgroundColor: 'transparent',
borderColor: '#007bff',
borderWidth: 4,
pointBackgroundColor: '#007bff'
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
display: false,
}
}
});
</script>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">

<title>Signin Template for Bootstrap</title>

<!-- Bootstrap core CSS -->
<link th:href="@{../static/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link th:href="@{../static/css/signin.css}" rel="stylesheet">
</head>

<body class="text-center">
<form class="form-signin">
<img class="mb-4" src="https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-logo.svg" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">&copy; 2017-2018</p>
</form>
</body>
</html>

上述的@{}为thymeleaf的模板语法,和jsp中的page.context.getcontextpath是一个意思,指向项目根目录

然后自定义一下首页:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.boogipop.springboot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class DIYconfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}

上面说到的只需要继承WebMvcConfigurer然后加上注解即可自定义配置

员工管理系统 | 国际化

国际化也就是中文翻译,支持不同语言的网站

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#开发