一文詳解Spring Boot的使用
文章目錄
- `Spring Boot`基礎
- `Spring Boot`整合
- `Spring MVC`整合
- `jdbc`整合
- 普通`mybatis`整合
- `tk mybatis` 整合
- `Thymeleaf`整合
- `Mybatis Plus`整合
- `Servlet`整合
- `Filter`整合
- `Listener`整合
- `Spring Boot`檔案上傳與下載
- `Spring Boot`熱部署
- `SpringBoot`中的異常處理
- `SpringBoot`中的單元測試
- `Freemarker`整合【未完成】
- SpringBoot整合Shiro
- SpringBoot整合SpringSecurity
- SpringBoot整合Ehcache
- SpringBoot整合SpringDataRedis
- SpringBoot整合Scheduled
- SpringBoot整合Quartz
- SpringBoot整合SpringDataJPA
Spring Boot
基礎
springboot
是spring
快速開發腳手架,通過約定大於配置的方式,快速構建和啟動spring
專案 。解決了複雜的配置
和混亂的依賴管理
。
Spring Boot
特點:
- 快速開發
spring
應用的框架 - 內嵌
tomcat和jetty
容器,不需要單獨安裝容器,jar包
直接釋出一個web應用
- 簡化
maven
配置,parent
這種方式,一站式引入需要的各種依賴 - 基於註解的零配置思想
- 和各種流行框架,
spring web mvc,mybatis,spring cloud
無縫整合
Spring Boot
基礎配置
(1)建立專案
(2)新增依賴
SpringBoot提
供了一個名為spring-boot-starter-parent
的構件,裡面已經對各種常用依賴(並非全部)的版本進行了管理,我們的專案需要以這個專案為父工程
,這樣我們就不用操心依賴的版本問題
了,需要什麼依賴,直接引入座標即可!
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
(3)新增web啟動器
為了讓SpringBoot
幫我們完成各種自動配置,我們必須引入SpringBoot
提供的自動配置依賴,我們稱為 啟動器
。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
自動裝配
(4)管理jdk版本
修改為自己使用的版本即可
<properties>
<java.version>11</java.version>
</properties>
(5)啟動類
使用
JBLSpringBootAppGen
外掛引入Appliation
啟動類和application.yml
配置檔案
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
(6)啟動main執行緒
即可
@SpringBootApplication
註解:
當啟動Application
類,就會完成IOC
的初始化操作,這個時候就會載入@SpringBootApplication
註解,這是一個組合註解:
@Target({ElementType.TYPE}) //註解位置
@Retention(RetentionPolicy.RUNTIME)//作用域
@Documented
@Inherited
// 以上四個是Java中提供的元註解
@SpringBootConfiguration // 本質上就是一個Configuration註解
@EnableAutoConfiguration // 自動裝配的註解
@ComponentScan( //掃描註解(掃描啟動類所在包以及子包)
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
改變banner:
什麼是banner?
spring Boot啟動時顯示的字元圖案就是banner。
怎麼改變?
- 到專案下的 resources 目錄下新建一個
banner.txt
- 將自己的banner複製到
banner.txt
中- banner生成網站
https://www.bootschool.net/ascii
Spring Boot
整合
Spring MVC
整合
(1)修改埠號
在
application.properties
中新增配置,後面就可以使用修改後的埠進行訪問了
#修改埠
server.port=8888
(2)訪問靜態資源
ResourceProperties
的類,裡面就定義了靜態資源的預設查詢路徑
:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public
只要靜態資源放在這些目錄中任何一個,
SpringMVC
都會幫我們處理。習慣會把靜態資源放在classpath:/resources/static/
目錄下
比如:
重新啟動Application類
後,直接訪問cat.jpg
即可
webapp
目錄
在resources
同級目錄下建立一個webapp目錄
,該目錄的型別必須是ResourcesRoot
(3)新增攔截器
攔截器類:實現
HandlerInterceptor
介面
public class LoginInterceptor implements HandlerInterceptor {
//使用日誌物件進行處理
private Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug("處理器執行前執行!");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.debug("處理器執行後執行!");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.debug("跳轉回執行!");
}
}
配置
Spring Mvc
:實現WebMvcConfigurer
介面路徑匹配萬用字元 :
?
匹配任何單字元*
匹配0或者任意數量的字元/**
匹配0或者更多的目錄
@Configuration
public class MvcConfig implements WebMvcConfigurer{
/**
* @Description: 通過Bean註解,將定義的攔截器註冊到Spring容器
* @Param: []
* @Return: com.xj0927.interceptor.LoginInterceptor
* @Author: xj0927
* @Date Created in 2020/9/28 15:00
*/
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
/**
* @Description: 重寫介面中的addInterceptor方法,新增自定義攔截器
* @Param: [registry]
* @Return: void
* @Author: xj0927
* @Date Created in 2020/9/28 15:01
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 通過registry來註冊攔截器,通過addPathPatterns來新增攔截路徑
registry.addInterceptor(this.loginInterceptor()).addPathPatterns("/**");
}
}
配置日誌級別:
預設日誌級別為
info以上
在
application.properties
中進行配置
#設定com.xj0927包的級別為debug
logging.level.com.xj0927=debug
結構如下:
執行檢視即可!!!
jdbc
整合
環境配置
(1)引入jdbc啟動器
依賴、MySQL
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
(2)配置連線池
在
application.properties
中配置,不過後面在結構更簡單的yaml
格式的application.yml
中進行配置
引入jdbc啟動器
的時候,SpringBoot
會自動引入一個連線池HikariCP
,相較於之前用的c3p0
,
#配置jdbc引數:
spring.datasource.url=jdbc:mysql://localhost:3306/xixi?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=
#下面部分可省略(spring boot可自推斷)
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10
普通mybatis
整合
配置環境
(1)引入mybatis
啟動器
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
(2)演示使用
前提:在application.properties
配置好資料庫連線環境,後面建議使用yaml
格式,比較簡單。
實體類:
- 欄位和屬性對應時,會
下劃線
轉駝峰命名
public class User implements Serializable {
private Long id;
//自動轉換下換線到駝峰命名user_name -> userName
private String userName;
private String password;
private String name;
private Integer age;
// 性別,1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 建立時間
private Date created;
// 更新時間
private Date updated;
// 備註
private String note;
}
dao
:在一點與tx mayatis
和mybatis plus
不同,不需要繼承Mapper
介面
public interface UserDao{
public List<User> findAll();
}
UserMapper.xml
對映檔案:在
/resources/mappers
資料夾下新增UserMapper.xml
檔案
- 對映介面中的方法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xj0927.dao.UserDao"> <!--修改處1-->
<select id="findAll" resultType="com.xj0927.bean.User">
select * from tb_user
</select>
</mapper>
配置
application.properties
:
- 別名掃描,配置後
resultType
的值就不用寫完整路徑- 對映檔案地址
#mybatis配置:
# mybatis 別名掃描
mybatis.type-aliases-package=com.xj0927.bean
# mapper.xml檔案位置,如果沒有對映檔案,請註釋掉
mybatis.mapper-locations=classpath:/mappers/*.xml
啟動類
Application
:使用
普通mybatis
提供的構件即可:org.mybatis.spring.annotation.MapperScan
@SpringBootApplication
@MapperScan("com.xj0927.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
另外一種載入介面代理物件的方式,在介面上新增@Mapper
註解,但這種方式在介面較多的情況下,每一個都需要新增,比較繁瑣,使用上面的方式,直接掃描介面所在的包。
測試:
- 測試需要引入
測試依賴
- 測試類上新增
@RunWith(SpringRunner.class)
和@SpringBootTest
註解- 呼叫物件上新增
@Autowired
註解- 測試的方法上新增
@Test
註解
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserDaoTest {
@Autowired
private UserDao dao;
@Test
public void findAll() {
List<User> list = dao.findAll();
for (User u :list) {
System.out.println(u);
}
}
}
tk mybatis
整合
也叫通用mybatis
,可以避免重複的CRUD
編寫。
配置環境
(1)引入啟動器依賴
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
實體類:
- 預設表名 = 類名 欄位名 = 屬性名
- 使用
@Table(name = "表名")
進行表名指定- 使用
@Column(name = "欄位名")
進行欄位指定- 使用
@Transient
不進行欄位對映
@Table(name = "tb_user")//表名與類不一致時
public class User1 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//自動轉換下換線到駝峰命名user_name -> userName
//@Column(name = "user_name")
private String userName;
private String password;
private String name;
private Integer age;
// 性別,1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 建立時間
private Date created;
// 更新時間
private Date updated;
// 備註
private String note;
@Transient//不進行欄位對映
private String info;
}
dao
:繼承Mapper
介面,不要忘記指定實體物件
繼承
Mapper
後,就繼承了Mapper
的通用crud
方法
public interface UserMapper extends Mapper<User1> {
public List<User1> findByUser(User1 user1);
}
(2)配置UserMapper.xml
在/resources/mappers/
路徑下新建UserMapper.xml
檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xj0927.dao.UserMapper"> <!--修改地方1-->
<select id="findByUser" resultType="com.xj0927.bean.User1">
SELECT * FROM tb_user
<where>
<if test="name != null">
name like '%${name}%'
</if>
<if test="note != null">
or note like '%${note}%'
</if>
</where>
</select>
</mapper>
啟動類:
此時
@SpringBootApplication
使用tx mybatis
的構件:tk.mybatis.spring.annotation.MapperScan
@SpringBootApplication
@MapperScan("com.xj0927.dao")//使用tx mybatis時注意換註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
(3)測試
新增
@Test
public void insert(){
//新增單條資料{是否會使用預設值}
User1 user1 = new User1();
user1.setName("麻子");
user1.setAge(18);
// dao.insert(user1);
dao.insertSelective(user1);
}
刪除
@Test
public void delete(){
//1.根據主鍵值刪除元素
dao.deleteByPrimaryKey(8);
//2.根據屬性值刪除資料
User1 user1 = new User1();
user1.setId(9l);
dao.delete(user1);
}
修改
@Test
public void update(){
//根據主鍵值更新
User1 user1 = new User1();
user1.setId(9l);
user1.setName("麻子");
user1.setAge(15);
user1.setNote("說明");
dao.updateByPrimaryKey(user1);
// dao.updateByPrimaryKeySelective(user1);
}
檢視
@Test
public void select(){
//1.根據主鍵進行查詢
User1 u = dao.selectByPrimaryKey(1);
System.out.println(u);
//2.查詢所有
List<User1> list = dao.selectAll();
list.forEach(System.out::println);
//3.查詢單個資料
User1 user1 = new User1();
user1.setName("嘻嘻");
User1 user2 = dao.selectOne(user1);
System.out.println(user2);
//4.根據(屬性條件)查詢符合條件的總條數
User1 user3 = new User1();
user3.setName("張三a");
int i = dao.selectCount(user3);
System.out.println(i);
}
Example
方法
使用Example
方法,加一些限制條件,比如使用Example.selectProperties(屬性1,屬性2)
查詢指定欄位;
使用example.createCriteria().andLike("name","%a%")
模糊查詢。
呼叫crud
方法時使用xxxExample(example)
即可。
Example example = new Example(User1.class);
example.selectProperties("id","name");
List<User1> list = dao.selectByExample(example);
for (User1 u :list) {
System.out.println(u);
}
Thymeleaf
整合
Thymeleaf
是一個跟FreeMarker
類似的模板引擎,它可以完全替代JSP
。
環境配置
(1)引入啟動器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
SpringBoot
會自動為Thymeleaf
註冊一個檢視解析器:
Thymeleaf
也會根據字首和字尾來確定模板檔案的位置:
將靜態頁面檔案放入/templates/
下,
當通過controller
層返回users
時,會加上字尾.html
,指向users.html
檔案。
模板快取
Thymeleaf
會在第一次對模板解析之後進行快取,極大的提高了併發處理能力。但是這給我們開發帶來了不便,修改頁面後並不會立刻看到效果,我們開發階段可以關掉快取使用:
修改頁面後按快捷鍵:
Ctrl + Shift + F9
對專案進行rebuild
才可以。
# 開發階段關閉thymeleaf的模板快取
spring.thymeleaf.cache=false
使用語法
Thymeleaf
一款模板引擎,可代替jsp
,實現動靜結合顯示內容。
無網路顯示靜態內容,有網路用後臺得到資料替換靜態內容 。
與
SpringBoot
完美整合。
表示式
前提:
由controller
層儲存資料到model attribute
中,同時跳轉到users
[具體路徑:resources/templates
,由Thymeleaf
指定,同時加上字尾.html
]
(1)變數表示式
也叫Spring EL
表示式,用來獲取model attribute
中的資料
${session.user.name}
注意:必須使用在th
標籤之中,這是因為此時渲染到模型中的資料,是採用的Thymeleaf
名稱空間
<span>${user.id}</span>
<span th:text="${user.id}"></span>
${user.id}
1
(2)選擇(*
)表示式
由th:object
屬性指定object
物件,然後使用*{}
獲取資料
<tr th:each="user : ${users}" th:object="${user}">
同樣*{}
必須放在th
標籤之中
<span>*{id}</span>
<span th:text="*{id}"></span>
*{id}
1
(3)URL表示式
將回話資訊
新增到url
中,
方式一:url
表示式 ,使用@{/地址/(引數)}
<a th:href="@{/delete(id=${user.id},name=*{userName})}">delete</a>
效果:
http://localhost:8888/delete?id=1&name=zhangsan
方式二:文字替換 ,使用|/地址/引數|
<a th:href="|/update/${user.id}|">update</a>
效果:
http://localhost:8888/update/1
方式三:字串拼接 ,使用
"`/地址` + 引數"
<a th:href="'/approve/' + ${user.id}">稽核</a>
效果:
http://localhost:8888/approve/1
常用th
標籤
(1)條件判斷if
和unless
if
表示條件成立才顯示:
<a th:if="*{id > 1}">id大於1才顯示</a>
unless
表示條件不成立才顯示:
<a th:unless="*{name == null}">名字不等於空才顯示</a>
兩者結合,使用(if) ? (then) : (else)
語法顯示
<a th:text="(${user.id} > 1)? '大於':'小於'"></a>
(2)for
迴圈
在定義的迭代物件
後面加上status
[名字自定義]
<tr th:each="user,status: ${list}" th:object="${user}">
status
常用屬性:
index
:當前迭代物件的序號(從0開始)count
:當前迭代的序號(從1開始)size
:被迭代物件的大小current
:當前迭代變數even/odd
:布林值,當前迴圈是否是偶數/奇數(從0開始計算)first
:布林值,當前迴圈是否是第一個last
:布林值,當前迴圈是否是最後一個
<td th:text="${status.index}"></td>
<td th:text="${status.count}"></td>
<td th:text="${status.size}"></td>
<td th:text="${status.current}"></td>
<td th:text="${status.index}"></td>
<td th:text="${status.even}"></td>
(4)內聯文字inline
先使用th:inline="text"
啟用,再使用[[...]]
展示表示式內容:
<td th:inline="text">[[${user.id}]]</td>
未展示表示式內容:
<td th:inline="none">[[${user.id}]]</td>
(5)內建物件
Thymeleaf
提供了一系列Utility物件
(內建於Context中),可以通過#
直接訪問:
常用:
- dates :
java.util.Date**
的功能方法類。 - calendars : 類似*#dates*,面向
java.util.Calendar
- numbers : 格式化數字的功能方法類
- strings : 字串物件的功能類,
contains,startWiths,prepending/appending
等等。 - objects: 對objects的功能類操作。
bools
: 對布林值求值的功能方法。- arrays:對陣列的功能類方法。
- lists: 對
lists
功能類方法 - sets
- maps
dates
用法:
<td th:text="${#dates.format(#dates.createNow(),'yyyy-MM-dd')}">獲取當前日期並進行格式化輸出</td>
Strings
用法:
<span th:text="${#strings.substring(user.name,1,2)}">擷取字串</span>
<span th:text="${#strings.length(user.name)}">獲得長度</span>
<span th:text="${#strings.randomAlphanumeric(2)}">隨機字串</span>
<span th:text="${#strings.equals(user.name, 'hello text....')}">比較兩個字串是否相等</span>
thymeleaf
佈局
在/resources/templates/
目錄下建立footer.html
:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<footer th:fragment="copy(title)">
© 2020<br>
<span th:text="${title}">title footer</span>
</footer>
</body>
</html>
任何地方進行引用都行:
<div th:insert="footer :: copy('哈哈1')"></div>
<div th:replace="footer :: copy('哈哈2')"></div>
<div th:include="footer :: copy('哈哈3')"></div>
在網頁中顯示的原始碼:
<div>
<footer>
2020<br>
<span>哈哈1</span>
</footer>
</div>
<footer>
2020<br>
<span>哈哈2</span>
</footer>
<div>
2020<br>
<span>哈哈3</span>
</div>
總結:
th:insert
:保留自己的主標籤,保留th:fragment
的主標籤。th:replace
:不要自己的主標籤,保留th:fragment
的主標籤。th:include
:保留自己的主標籤,不要th:fragment
的主標籤。(官方3.0後不推薦)
Mybatis Plus
整合
Mybatis-Plus
(簡稱MP
)是一個Mybatis
的增強工具,在 Mybatis
的基礎上只做增強不做改變,避免了我們重複CRUD
語句。
新增配置:
(1)引入依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xj0927</groupId>
<artifactId>mybatis-plus-demo-quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatisplus.version>3.3.2</mybatisplus.version>
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)新增配置檔案application.yml
yaml
格式結構簡單,推薦使用
這裡使用JBLSpringBootAppGen
外掛同時引入Appliation
啟動類和application.yml
配置檔案
右擊專案:選擇JBLSpringBootAppGen
演示使用:
這裡使用h2
基於記憶體的資料庫,此資料庫一般測試用,比較方便。
在jvm
啟動時,自動執行指令碼檔案載入相應的資料。
(1)建庫建表
在resources
資料夾下新建資料夾db
用於存放資料庫表結構檔案
和表資料檔案
schema-h2.sql
:表結構檔案
DROP TABLE IF EXISTS user1;
CREATE TABLE user1(
id BIGINT(20) NOT NULL COMMENT '主鍵ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年齡',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY (id)
);
data-h2.sql
:表資料檔案
DELETE FROM user1;
INSERT INTO user1(id, name, age, email) VALUES
(1,'lisi', 18, 'test1@163.com'),
(2,'zhangsan', 20, 'test22@163.com'),
(3,'wanger', 14, 'test4@163.com'),
(4,'mazi', 28, 'test1@163.com');
(2)配置資料庫
在application.yml
檔案中進行配置
注意:名字和值之間有一個空格
#DataSource Config
spring:
datasource:
driver-class-name: org.h2.Driver
#配置資料庫表結構
schema: classpath:db/schema-h2.sql
#配置資料庫表資料
data: classpath:db/data-h2.sql
#連線資料庫[mem:代表記憶體,test資料庫名字可自定義,賬戶密碼自定義]
url: jdbc:h2:mem:test
username: root
password: 123
#日誌輸出
logging:
level:
com.xj0927: debug
(3)設定類
實體類
@Data //實體類物件
@TableName("user1")//表名與類名不一致時
@Accessors(chain = true)//在set的同時返回物件:便於鏈式書寫
public class User {
// @TableId("id_")//主鍵名字不一致
// @TableId(type = IdType.AUTO)//mysql自增主鍵策略
@TableId(type = IdType.ASSIGN_ID)//雪花演算法:生成唯一long型的值
private Long id;
private String name;
private Integer age;
private String email;
@TableField(exist = false)//表中不存在欄位時
private String info;
// public User setId(Long id) {
// this.id = id;
// return this;
// }
}
dao
:繼承BaseMapper
介面(裡面包含CRUD方法)
public interface UserMapper extends BaseMapper<User> {//指定實體類
}
啟動類:新增掃描註解
@MapperScan("介面所在包名")
@SpringBootApplication
@MapperScan("com.xj0927.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
測試類:在介面中
ctrl + shift +t
進入測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
@Autowired //介面物件
private UserMapper mapper;
@Test
public void testSelect1(){
//呼叫通用方法進行測試
List list = mapper.selectList(null);
list.forEach(System.out::println);
Assert.assertEquals(4,list.size());//使用斷言進行判斷
}
}
內建CRUD
斷言使用:
Assert.assertEquals(期待值,結果值);
Assert.assertTrue(條件判斷);
輸出使用:
-
結果集.forEach(System.out::println)
-
結果集.forEach( 結果物件 -> {
System.out.println(結果物件);
});
(1)新增
讓id
自動生成時,在id
屬性上使用@TableId(type = IdType.ASSIGN_ID)
雪花演算法生成時,值為long
,對應的h2
記憶體資料庫的id欄位型別
為BIGINT
@Test//新增
public void testInsert(){
User user = new User();
user.setName("小紅");
user.setAge(22);
user.setEmail("hah@163.com");
int result = mapper.insert(user);
Assert.assertEquals(1,result);
mapper.selectList(null).forEach(System.out::println);
}
(2)刪除
@Test
public void testDelete(){
//1.根據主鍵刪除
mapper.deleteById(1);
mapper.selectList(null).forEach(System.out::println);
// 2.批量刪除(使用Wrappers工具類)
// 刪除age欄位中包含4的資料
mapper.delete(Wrappers.<User>query().like("age",4));
mapper.delete(Wrappers.<User>query().gt("age",20));
mapper.selectList(null).forEach(System.out::println);
//3.批量刪除(直接建立QueryWrapper物件)
mapper.delete(new QueryWrapper<User>().like("age",4));
mapper.selectList(null).forEach(System.out::println);
//4.批量刪除(使用lambda表示式呼叫實體類方法)
mapper.delete(new QueryWrapper<User>().lambda().like(User::getAge,4));
mapper.selectList(null).forEach(System.out::println);
}
(3)修改
如果想要鏈式設定(set
)實體類的屬性,可以新增註解@Accessors(chain = true)
效果相當於:
public User setId(Long id) {
this.id = id;
return this;
}
@Test
public void testUpdate(){
//1.根據id修改
User user = new User();
user.setId(1l);
user.setName("小紅");
//修改id為1的資料
mapper.updateById(user);
mapper.selectList(null).forEach(System.out::println);
//2.批量修改(通過setter不需要實體物件)
mapper.update(null,Wrappers.<User>update().set("age",29).like("id",1));
mapper.selectList(null).forEach(System.out::println);
//3.批量修改(通過實體物件)
mapper.update(new User().setName("李四").setAge(43),Wrappers.<User>update().like("id",1));
mapper.selectList(null).forEach(System.out::println);
}
(4)檢視
@Test
public void testSelect(){
//1.根據id查詢
System.out.println(mapper.selectById(1));
//2.查詢一條資料
System.out.println(mapper.selectOne(Wrappers.<User>query().eq("age",18)));
//3.投影查詢
//(只查詢指定欄位)
mapper.selectList(Wrappers.<User>query().select("name","age")).forEach(user -> {
System.out.println(user);
});
//查詢指定資料
mapper.selectList(Wrappers.<User>query().eq("age",28)).forEach(user -> {
System.out.println(user);
});
}
分頁
內建分頁:
(1)設定config
類
@Configuration
public class MybatisPlusPageConfig {
/**
* @Description: 分頁外掛
* @Return: com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
* @Author: xj0927
* @Date Created in 2020/9/29 17:50
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
// 開啟count的join優化,只針對left join !!!
return new PaginationInterceptor().setCountSqlParser(new JsqlParserCountOptimize(true));
}
}
(2)測試
使用內建分頁時,進行查詢時
需要使用帶xxxPage
的方法
@Test//baseMapper自帶的分頁
public void testPage(){
//設定分類規則:引數1表示第幾頁,引數2表示這頁顯示數量
Page<User> page = new Page<>(1,6);
//1.顯示按規則分頁後的結果(不加限制條件)
Page<User> pageResult = mapper.selectPage(page, null);
//2.顯示按規則分頁後的結果(加限制條件)
QueryWrapper<User> w = Wrappers.<User>query().like("age", 2);
Page<User> pageResult = mapper.selectPage(page, w);
//總條數
System.out.println(pageResult.getTotal());
//當前總頁數
System.out.println(pageResult.getPages());
//當前頁條數
System.out.println(pageResult.getSize());
}
自定義xml
分頁:
(1)建立UserMapper
介面
該介面需要繼承BaseMapper
介面
public interface UserMapper extends BaseMapper<User> {
/**
* @Description: 對映的介面方法需要使用@Param定義兩個引數:
* 第1個參數列示分頁物件,第2個參數列示分頁條件
* @Param: [page, condition]
* @Return: com.baomidou.mybatisplus.core.metadata.IPage<com.xj0927.bean.User>
* @Author: xj0927
* @Date Created in 2020/9/29 18:44
*/
public IPage<User> selectUserByPage(@Param("p") IPage<User> page, @Param("c") User condition);
}
(2)配置application.yml
#配置mybatis plus
mybatis-plus:
#別名搜尋
type-aliases-package: com.xj0927.bean
#載入對映檔案
mapper-locations: classpath:/mappers/*.xml
(3)配置UserMapper.xml
對映檔案
在resources/mappers
資料夾下,建立UserMapper.xml
,該檔名一定要與介面名相同
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xj0927.dao.UserMapper"> <!--修改地方1-->
<sql id="selectSql">
SELECT * FROM user1
</sql>
<select id="selectUserByPage" resultType="com.xj0927.bean.User">
<include refid="selectSql"></include>
<where>
<if test="c.age !=null">
age = #{c.age}
</if>
<if test="c.email !=null">
and name like '%${c.name}%'
</if>
</where>
</select>
</mapper>
(4)測試
@Test//自定義xml分頁
public void testPage1(){
//設定分頁規則
Page<User> page = new Page<>(1,5);
User user = new User();
user.setAge(18);
user.setName("mazi");
//呼叫自定義方法
IPage<User> pr = mapper.selectUserByPage(page, user);
//總條數
System.out.println(pr.getTotal());
//總頁數
System.out.println(pr.getPages());
//當前頁條數
System.out.println(pr.getSize());
//當前頁數
System.out.println(pr.getCurrent());
//分頁規則後的所有條數
List<User> list = pr.getRecords();
list.forEach(System.out::println);
}
pageHelper
分頁:
(1)引入pageHelper
依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.11</version>
</dependency>
(2)設定config
類
@Configuration
public class MybatisPlusPageConfig {
/**
* @Description: 分頁外掛
* @Return: com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
* @Author: xj0927
* @Date Created in 2020/9/29 17:50
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
// 開啟 count 的 join 優化,只針對 left join !!!
return new PaginationInterceptor().setCountSqlParser(new JsqlParserCountOptimize(true));
}
//pageHelper的分頁外掛
//與上一個分頁外掛不會衝突
@Bean
public PageInterceptor pageInterceptor(){
return new PageInterceptor();
}
}
(3)創捷UserMapper
介面
public interface UserMapper extends BaseMapper<User> {
public List<User> selectUserByPage2(User user);
}
(4)配置UserMapper.xml
對映檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xj0927.dao.UserMapper">
<sql id="selectSql">
SELECT * FROM user1
</sql>
<select id="selectUserByPage2" resultType="com.xj0927.bean.User">
<include refid="selectSql"></include>
<where>
<if test="age !=null">
age = #{age}
</if>
<if test="name !=null">
and name like '%${name}%'
</if>
</where>
</select>
</mapper>
(5)測試
@Test
public void testPage2(){
//限制條件
User user = new User();
user.setAge(28);
user.setName("mazi");
//寫法一:
PageInfo<User> page = PageHelper.startPage(2,5).doSelectPageInfo(() ->{
mapper.selectUserByPage2(user);
});
//寫法二:
//分頁規則:引數1表示第幾頁,引數2表示這頁條數
PageHelper.startPage(2,5);
PageInfo<User> page1 = new PageInfo<User>(mapper.selectUserByPage2(user));
List<User> list = page.getList();
list.forEach(System.out::println);
//總條數
System.out.println(page.getTotal());
//總頁數
System.out.println(page.getPages());
//當頁條數
System.out.println(page.getSize());
//每頁行數
System.out.println(page.getPageSize());
//起始行數
System.out.println(page.getStartRow());
//是否是第一頁
System.out.println(page.isIsFirstPage());
//是否是最後一頁
System.out.println(page.isIsLastPage());
//是否還有下一頁
System.out.println(page.isHasNextPage());
//是否還有上一頁
System.out.println(page.isHasPreviousPage());
//頁碼列表
System.out.println(Arrays.toString(page.getNavigatepageNums()));
}
Servlet
整合
方式一:
(1)自定義Servelt類
@WebServlet(name = "servlet_name",urlPatterns = "/first")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet running");
PrintWriter writer = resp.getWriter();
writer.write("success...");
writer.flush();
writer.close();
}
}
(2)啟動類中新增@ServletComponentScan()
註解
新增後在SpringBoot
啟動的時候會掃描@WebServlet
註解
@SpringBootApplication
@MapperScan("com.xj0927.dao")//這是mabatis的掃描註解,不用管
@ServletComponentScan()//servlet 掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
(3)啟動application類
測試
方式二:
(1)自定義Servelt類
不新增@WebServlet()
註解,放在啟動類
中實現
public class MyServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet running");
PrintWriter writer = resp.getWriter();
writer.write("success1...");
writer.flush();
writer.close();
}
}
(2)在啟動類application
中註冊ServletRegistrationBean
物件
@SpringBootApplication
@MapperScan("com.xj0927.dao")//mybatis註解
@ServletComponentScan()//servlet 掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
//註冊Servlet物件
@Bean
public ServletRegistrationBean getRegistrationBean(){
// 將要新增的Servlet封裝為一個ServletRegistrationBean物件
ServletRegistrationBean reg = new ServletRegistrationBean(new MyServlet1());
// 設定對映資訊
reg.setName("servlet_name");
reg.addUrlMappings("/second");
return reg;
}
}
(3)啟動application類
測試
Filter
整合
方式一:
(1)自定義Filter類
,在過濾器中新增@WebFilter
註解
@WebFilter(urlPatterns = "/second")//需要過濾的請求
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("----init----");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("________First過濾器執行之前_________");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("________First過濾器執行之後_________");
}
@Override
public void destroy() {
System.out.println("----destroy----");
}
}
(2)啟動類中加@ServletComponentScan()
掃描註解
與整合Servlet
時新增的註解相同
@SpringBootApplication
@MapperScan("com.xj0927.dao")//mybatis掃描註解
@ServletComponentScan()//servlet 掃描註解 //Filter掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
(3)啟動application類
測試
測試前提:一定要有Servlet
處理請求
方式二:
(1)自定義Filter類
不新增@WebFilter
註解
public class MyFilter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("----init2----");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("________First過濾器執行之前2_________");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("________First過濾器執行之後2_________");
}
@Override
public void destroy() {
System.out.println("----destroy2----");
}
}
(2)在啟動類application
中註冊物件
@SpringBootApplication
@MapperScan("com.xj0927.dao")//tx mybatis掃描註解
@ServletComponentScan()//servlet 掃描註解 //Filter掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
//註冊Servlet物件
@Bean
public ServletRegistrationBean getRegistrationBean(){
// 將要新增的Servlet封裝為一個ServletRegistrationBean物件
ServletRegistrationBean reg = new ServletRegistrationBean(new MyServlet1());
// 設定對映資訊
reg.setName("servlet_name");
reg.addUrlMappings("/second");
return reg;
}
}
(3)啟動application類
測試
Listener
整合
方式一:
(1)自定義Listener
類,新增註解@WebListener
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("Listener1 : 初始化了....");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("Listener1 : 銷燬了....");
}
}
(2)在啟動類application
中註冊FilterRegistrationBean
物件
@SpringBootApplication
@MapperScan("com.xj0927.dao")//使用tx mybatis時注意換註解
@ServletComponentScan()//servlet 掃描註解 //Filter掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
//註冊Servlet物件
@Bean
public ServletRegistrationBean getRegistrationBean(){
// 將要新增的Servlet封裝為一個ServletRegistrationBean物件
ServletRegistrationBean reg = new ServletRegistrationBean(new MyServlet1());
// 設定對映資訊
reg.setName("servlet_name");
reg.addUrlMappings("/second");
return reg;
}
//註冊Filter物件
@Bean
public FilterRegistrationBean getFRegistrationBean(){
FilterRegistrationBean frb = new FilterRegistrationBean(new MyFilter1());
frb.addUrlPatterns("/second");
return frb;
}
}
方式二:
(1)自定義Listener
類
不新增註解@WebListener
public class MyListener2 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("Listener2 : 初始化了....");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("Listener1 : 銷燬了....");
}
}
(2)在啟動類application
中註冊ServletListenerRegistrationBean
物件
@SpringBootApplication
@MapperScan("com.xj0927.dao")//使用tx mybatis時注意換註解
@ServletComponentScan()//servlet 掃描註解 //Filter掃描註解 //Listener掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
//註冊Servlet物件
@Bean
public ServletRegistrationBean getRegistrationBean(){
// 將要新增的Servlet封裝為一個ServletRegistrationBean物件
ServletRegistrationBean reg = new ServletRegistrationBean(new MyServlet1());
// 設定對映資訊
reg.setName("servlet_name");
reg.addUrlMappings("/second");
return reg;
}
//註冊Filter物件
@Bean
public FilterRegistrationBean getFRegistrationBean(){
FilterRegistrationBean frb = new FilterRegistrationBean(new MyFilter1());
frb.addUrlPatterns("/second");
return frb;
}
//註冊Listener物件
@Bean
public ServletListenerRegistrationBean getLRegistrationBean(){
ServletListenerRegistrationBean slr = new ServletListenerRegistrationBean(new MyListener2());
return slr;
}
}
Spring Boot
檔案上傳與下載
檔案上傳:
(1)建立上傳的表單
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>檔案上傳</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data"> <!--注意這裡-->
<label>photoName:</label><input type="text" name="photoName"><br/>
<label>photo:</label><input type="file" name="upload"><br/><!--注意這裡-->
<input type="submit" value="提交">
</form>
</body>
</html>
(2)服務端contrtoller
處理請求
@RestController("/") //相當於@Controller + @RequestBody
public class MyUploadController {
@RequestMapping("/upload")
public String upload(String photoName, MultipartFile upload, HttpServletRequest request) throws IOException {
System.out.println("photoName:" + photoName + ",檔名稱:" + upload.getOriginalFilename());
String realPath = request.getRealPath("/uploadFile");
String filename = upload.getOriginalFilename();
upload.transferTo(new File(realPath,filename));
return "success";
}
}
(3)application.properties
中配置上傳引數
#檔案上傳設定引數
spring.servlet.multipart.enabled=true
#單個檔案上傳大小
spring.servlet.multipart.max-file-size=200MB
#一次上傳檔案總的大小
spring.servlet.multipart.max-request-size=200MB
(4)測試
在webapp
下新建資料夾uploadFile
,並隨便建立一個檔案a.txt
(是什麼不重要,有就行),在前端頁面選擇檔案提交上傳,成功後,可以在uploadFile
下看見該檔案
檔案下載:
(1)建立上傳的表單
這一步的目的主要是告訴伺服器,你要下載的檔名稱
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>檔案下載</title>
</head>
<body>
<form action="/downLoad" method="post" enctype="multipart/form-data">
<label>name:</label><input type="text" name="name">
<input type="submit" value="下載">
</form>
</body>
</html>
(2)伺服器controller
處理請求
@RestController("/") //相當於@Controller + @RequestBody
public class MyUploadDownController {
@RequestMapping("/downLoad")
public String down(String name, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String realPath = request.getRealPath("/uploadFile");
//1.要下載的檔案地址
realPath = realPath + "/" + name;
File file = new File(realPath);
//2.設定響應的頭和客戶端儲存的檔名
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
//attachment 表示以附件的形式響應給客戶端
response.setHeader("Content-Disposition","attachment;fileName=" + file.getName());
//複製檔案
FileInputStream in = null;
ServletOutputStream out = null;
try {
in = new FileInputStream(file);
out = response.getOutputStream();
// 迴圈讀取
byte[] b = new byte[1024];
int length = 0;
while((length = in.read(b)) > 0){
out.write(b,0,length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//關閉流
try {
if(in != null){
in.close();
}
if(out != null){
out.flush();
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return "success";
}
}
(3)測試
輸入檔名,即可到伺服器指定資料夾下進行查詢,然後下載
Spring Boot
熱部署
(1)什麼是SpringBoot熱部署
?
SpringBoot
熱部署就是在專案正在執行的時候修改程式碼, 卻不需要重新啟動專案。
有了SpringBoot
熱部署後大大提高了開發效率,因為頻繁的重啟專案,勢必會浪費很多時間, 有了熱部署後,不用擔心修改程式碼重啟專案了。
(2)SpringBoot熱部署
的流程
.pom檔案
中匯入spring-boot-devtools
依賴:
<!--SpringBoot熱部署配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
pom.xml
中新增外掛:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
設定
application.properties
:
#配置專案熱部署
spring.devtools.restart.enabled=true
在
idea
中設定自動編譯:ctrl+alt+s
開啟設定(Other Settings
的設定是對整個工作空間專案都啟作用,而Settings
的設定是對整個專案啟作用),搜尋Compliler
,勾選Build project automatically
按住
ctrl + shift + alt + /
,出現如下圖所示介面,點選Registry
:
點選進入後,勾選
compiler.automake.allow.when.app.running
後關閉即可
通過以上步驟,就完成了SpringBoot
專案的熱部署功能!!!
(3)對熱部署測試是否成功:
@RestController
public class HotAutoController {
@RequestMapping("/index")
public String index() {
return "helloworld!";
}
}
啟動專案,通過瀏覽器輸入地址:http://localhost:8888/index
【埠號選擇你使用的】
結果如下:
新加請求,在不重新啟動專案的情況下測試熱部署是否配置成功:
@RestController
public class HotAutoController {
@RequestMapping("/index")
public String index() {
return "helloworld!";
}
@RequestMapping("/say")
public String say(){
return "I love Java!";
}
}
測試新加請求是否成功,瀏覽器輸入http://localhost:8080/say
後結果如下:
SpringBoot
中的異常處理
1. 自定義錯誤頁面:
SpringBoot
預設的處理異常的機制:SpringBoot
預設的已經提供了一套處理異常的機制。
一旦程式中出現了異常 SpringBoot
會向/error
的url
傳送請求。在 springBoot
中提供了一個叫 BasicExceptionController
來處理/error 請求
,然後跳轉到預設顯示異常的頁面來展示異常資訊:
只需要在resources/templates
中新增一個error.html
頁面即可:
隨便寫一個錯誤請求,進行測試:
2.@ExceptionHandler
處理:
- 針對特定的異常處理
- 異常處理程式碼和業務程式碼耦合性比較強
Controller
類:
@RestController
public class ExceptionHandlerController {
//請求1:模擬NullPointerException異常
@RequestMapping("/show1")
public String show1(){
String msg = null;
msg.length(); //NullPointerException
return "success";
}
/**
* @Description: 如果當前類中出現了NullPointerException異常就會跳轉到本方法對應的view中
*/
@ExceptionHandler(value = {NullPointerException.class})
public ModelAndView nullPointerException(Exception e){
ModelAndView view = new ModelAndView();
//處理的異常請求
view.addObject("error",e.toString());
//處理異常的頁面
view.setViewName("error1");
return view;
}
//請求2:模擬ArithmeticException異常
@RequestMapping("/show2")
public String show2(){
int i = 0;
int b = 100;
System.out.println(b/i); // ArithmeticException
return "success";
}
/**
* 如果當前類中出現了ArithmeticException異常就會跳轉到本方法對應的view中
*/
@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView arithmeticException(Exception e){
ModelAndView view = new ModelAndView();
view.addObject("error",e.toString());
view.setViewName("error2");
return view;
}
}
對應的錯誤處理頁面:
分別請求/show1
和/show2
時,出現異常,跳轉到對應頁面。
3.@ControllerAdvice
處理 :
@ControllerAdvice
,它是一個Controller增強器
,可對controller
中被@RequestMapping註解的方法
加一些邏輯處理。最常用的就是異常處理。
需要配合@ExceptionHandler
使用。當將異常拋到controller時,可以對異常進行統一處理,規定返回的json格式
或是跳轉到一個錯誤頁面
自定義異常MyException
:
@Data
public class MyException extends RuntimeException{
private long code;//錯誤程式碼
private String msg;//錯誤資訊
public MyException(long code, String msg) {
this.msg = msg;
this.code = code;
}
public MyException(String message) {
super(message);
}
}
發生自定義異常後的邏輯處理:
使用
@ControllerAdvice
實現業務程式碼和系統異常處理程式碼解耦
@ControllerAdvice //全域性異常捕捉處理
public class AdviceException {
@ExceptionHandler(value = {MyException.class})
public ModelAndView MyExceptionHandler(MyException e){
ModelAndView view = new ModelAndView();
view.addObject("code",e.getCode());
view.addObject("msg",e.getMsg());
//發生異常後跳轉的頁面
view.setViewName("error1");
return view;
}
}
錯誤頁面:
Controller
層:(模擬請求訪問時,出現自定義異常)
@RestController
public class ExceptionController {
@RequestMapping("/test1")
public String testException() throws Exception{
throw new MyException(403,"頁面錯誤");
}
}
測試:訪問http://localhost:8888/test1
4.SimpleMappingExceptionResolver
處理:
通過系統提供的異常對映處理實現
SimpleMappingExceptionResolver
處理的方法中進行地址對映即可
在處理類application
中進行對應異常的地址對映:
@SpringBootApplication
@MapperScan("com.xj0927.dao")//mybatis 掃描註解
@ServletComponentScan()//servlet 掃描註解 //Filter掃描註解 //Listener掃描註解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
/**
* 異常資訊和對應的 處理地址的 對映
* @return
*/
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
SimpleMappingExceptionResolver mapping = new SimpleMappingExceptionResolver();
//不同異常跳轉不同頁面
Properties p = new Properties();
p.setProperty("java.lang.NullPointerException","error3");
p.setProperty("java.lang.ArithmeticException","error4");
mapping.setExceptionMappings(p);
return mapping;
}
}
錯誤頁面:
5.自定義HandlerExceptionResolver
全域性異常:
只要發生自定義類裡面的異常就進行相應的跳轉處理。新增
@Component
與實現HandlerExceptionResolver
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("全域性的自定義異常處理觸發了....");
ModelAndView model = new ModelAndView();
if(e instanceof NullPointerException){
//跳轉頁面
model.setViewName("error5");
model.addObject("error","空指標異常");
}else if(e instanceof ArithmeticException){
//跳轉頁面
model.setViewName("error6");
model.addObject("error","算數異常");
}
return model;
}
}
SpringBoot
中的單元測試
(1)新增spring-boot-starter-test
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
(2)在所需測試的類中 ctrl + shift + t
進入測試類
(3)測試類中新增註解(綠色部分)
Freemarker
整合【未完成】
FreeMarker
是一個基於 Java
的模板引擎,最初專注於使用 MVC
軟體架構進行動態網頁生成。使用Freemarker
的主要優點是表示層和業務層
的完全分離。程式設計師可以處理應用程式程式碼,而設計人員可以處理 html 頁面
設計。最後使用freemarker
可以將這些結合起來,給出最終的輸出頁面。
環境配置
(1)新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
【待補充。。。】
SpringBoot整合Shiro
SpringBoot整合SpringSecurity
SpringBoot整合Ehcache
SpringBoot整合SpringDataRedis
SpringBoot整合Scheduled
SpringBoot整合Quartz
SpringBoot整合SpringDataJPA
相關文章
- Spring Boot(四):Thymeleaf 使用詳解Spring Boot
- Spring Boot 中使用 Dubbo 詳解Spring Boot
- Spring Boot Security 詳解Spring Boot
- Java之Spring Boot詳解JavaSpring Boot
- Spring Boot(八):RabbitMQ 詳解Spring BootMQ
- Spring Boot Test 的詳細使用教程Spring Boot
- Spring Boot Admin 2.0 詳解Spring Boot
- Spring Boot中的配置管理詳解Spring Boot
- SpringBoot詳解(二)-Spring Boot的核心Spring Boot
- 詳解Spring Boot的RedisAutoConfiguration配置Spring BootRedis
- spring-boot入門程式詳解Springboot
- spring boot2整合ES詳解Spring Boot
- Spring Boot 整合 FreeMarker 詳解案例Spring Boot
- Spring Boot(五):Spring Boot Jpa 的使用Spring Boot
- Spring Boot(十一):Spring Boot 中 MongoDB 的使用Spring BootMongoDB
- Spring Boot(三):Spring Boot 中 Redis 的使用Spring BootRedis
- 一文詳解spring迴圈依賴Spring
- Spring Boot的前世今生以及它和Spring Cloud的關係詳解。Spring BootCloud
- SpringBoot詳解(三)-Spring Boot的web開發Spring BootWeb
- Spring Boot 基於 SCRAM 認證整合 Kafka 的詳解Spring BootKafka
- spring boot使用註解的方式整合mybaitsSpring BootAI
- 專題一之Spring Boot入門詳解Spring Boot
- 值得使用的Spring BootSpring Boot
- Spring Boot(十八):使用 Spring Boot 整合 FastDFSSpring BootAST
- 【Spring Boot架構】整合Mybatis-Plus的例項詳解Spring Boot架構MyBatis
- 實戰Spring Boot 2.0系列(三) – 使用@Async進行非同步呼叫詳解Spring Boot非同步
- 實戰Spring Boot 2.0系列(三) - 使用@Async進行非同步呼叫詳解Spring Boot非同步
- Spring Boot Hello World 基於 IDEA 案例詳解Spring BootIdea
- Swagger 與 Spring Boot REST API 整合詳解SwaggerSpring BootRESTAPI
- Spring Boot中自動配置Autoconfigure詳解Spring Boot
- Spring Boot + Maven 多模組專案開發詳解Spring BootMaven
- Spring Boot 2.0(四):使用 Docker 部署 Spring BootSpring BootDocker
- Spring Boot(十六):使用 Jenkins 部署 Spring BootSpring BootJenkins
- 如何使用Spring Boot的ProfilesSpring Boot
- Spring boot註解Spring Boot
- Spring JdbcTemplate之使用詳解SpringJDBC
- Spring Boot 使用1Spring Boot
- Spring Boot(十七):使用 Spring Boot 上傳檔案Spring Boot