目錄
Spring Boot表單數據校驗
Spring Boot中使用了Hibernate-validate校驗框架來完成數據校驗的。(但是不需要我們導入這個jar包,Spring Boot中的web啓動器中已經包含了此包)
檢驗規則
常用的校驗規則如下
- @NotBlank:判斷字符串是否爲null或者是空串(去掉兩邊空格)
- @NotEmpty:判斷字符串是否爲null或者是空串(不會去掉兩邊空格,也即是如果你輸入的是一段空串,校驗會通過)
- @Length:判斷字符的長度(最大或最小)[校驗數字會拋異常的哦]
- @Min:判斷數值最小值
- @Max:判斷數值最大值
- @Email:判斷郵箱是否合法
@GetMapping("save")
public Object addUser(@Valid UserVO user, BindingResult bindingResult) throws Exception {
if (bindingResult.hasErrors()) {
List<ObjectError> allErrors = bindingResult.getAllErrors();
StringBuilder builder = new StringBuilder();
for (ObjectError allError : allErrors) {
builder.append(allError.getDefaultMessage());
}
throw new Exception(builder.toString());
}
// 這裏已經說明校驗通過了
String addUser = userService.addUser(user);
return addUser;
}
異常處理與單元測試
- Spring Boot中異常處理方式
- Spring Boot整合Junit單元測試
Spring Boot中異常處理方式
Spring Boot中對於異常處理提供了五種處理方式
其實這五種,只需要瞭解即可,真要使用的話都是選擇最後一種,而且有的公司部門前後分離,爲了簡化開發,可能會和前臺商量一種規範,甚至都不採用如下這幾種。
- 自定義錯誤頁面。SpringBoot 默認的處理異常的機制。
SpringBoot 默認的已經提供了一套處理異常的機制。 一旦程序中出現了異常 SpringBoot 會像/error 的 url 發送請求。在 springBoot 中提供了一個 叫 BasicExceptionController 來處理/error 請求,然後跳轉到默認顯示異常的頁面來展示異常 信息。如果我們需要將所有的異常同一跳轉到自定義的錯誤頁面 ,需要在src/main/resources/templates目錄下創建error.html 頁面。注意:名稱必須叫error。 - @ExceptionHandler註解處理異常
用法和@Request Mapping註解類似,但是此類註解的方法在哪個Controller中,只對該類中出現的異常有效。 - @ControllerAdvice+@ExceptionHandler 註解處理異常
此種方式彌補了第二種的缺陷,但是可能會有很多的異常處理方法。 - 配置 SimpleMappingExceptionResolver 處理異常
此種方式彌補了第三種的缺陷,可以在全局異常類中添加一個方法完成異常的同一處理。但是不能拿到異常信息。 - 自定義 HandlerExceptionResolver 類處理異常
該方式需要再全局異常處理類中實現HandlerExceptionResolver 接口,彌補了方式四獲取不到異常信息的缺陷。
Spring Boot整合Junit單元測試
- 添加Spring Boot整合Junit單元測試的包
<!-- 添加 junit 環境的 jar 包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
- 在測試類中添加相應註解
@RunWith:啓動器。
SpringJUnit4ClassRunner.class:讓junit 與 spring 環境進行整合。
@SpringBootTest(classes={App.class}) 。
1,當前類爲springBoot 的測試類 @SpringBootTest(classes={App.class}) 。
2,加載SpringBoot 啓動類。啓動 springBoot。
junit 與 spring 整合@Contextconfiguartion(“classpath:applicationContext.xml”)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class UserServiceTest {
@Autowired
private UserServiceImpl userServiceImpl;
@Test
public void testAddUser() {
this.userServiceImpl.addUser();
}
}
Spring Boot熱部署
熱部署:熱部署即在項目啓動後代碼發生改變但是不重新啓動容器。
Spring Boot的熱部署分爲兩種
- SpringLoader插件
- DevTools工具(準確的說是重新部署)
使用Spring Loader進行項目的熱部署
- 以maven插件的方式
- 在項目中直接使用jar包的方式
Spring Loader熱部署方式一:以maven插件的方式
- 在pom配置文件中添加下配置
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
- 使用maven的命令來啓動項目
spring-boot:run
Spring Loader缺陷:
- 只能對Java代碼做熱部署處理,但是對頁面無能爲力。
- Spring Loader以maven插件方式熱部署是在系統後臺以進程的形式來運行。在Idea或者eclipse中我們停掉的只是項目,所以再次手動運行時會報端口占用錯誤。需要我們手動打開任務管理器殺死該進程(Java.exe)。
Spring Loader熱部署方式二:在項目中直接使用jar包的方式
- 將Spring Loader的jar包放在項目根路徑的lib目錄下
- 運行時候,常規運行,但是需要添加一些參數
-javaagent:.\lib\springloaded-1.2.5.RELEASE.jar-noverify
注意:這一種方式不會出現端口搶佔的情況
DevTools工具
首先說一下Spring Loader與DevTools的區別:
Spring Loader:Spring Loader在部署項目時使用的是熱部署的方式。
DevTools:DevTools在部署項目時使用的是重新部署的方式。
- 修改項目的pom文件,添加DevTools的依賴
<!-- DevTools 的座標 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!-- 不傳遞依賴 -->
<optional>true</optional>
</dependency>
- 常規運行即可
IDEA下不生效的解決方案,勾上下邊的這個選項(File-Settings-Compiler-Build Project automatically)
然後按住以下快捷鍵(ctrl + shift + alt + /)修改Registry。勾上 Compiler autoMake allow when app running
Spring Boot緩存技術
- Spring Boot整合Ehcache
- Spring Boot整合Spring Data Redis
Spring Boot整合Ehcache
- 修改pom文件,添加對緩存支持和Ehcache的jar包
<dependencies>
<!-- springBoot 的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springBoot 的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 測試工具的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- Spring Boot 緩存支持啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Ehcache 座標 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
- 創建Ehcache的配置文件(ehcache.xml,resource目錄下)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!--defaultCache:echcache 的默認緩存策略 -->
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- 自定義緩存策略 -->
<cache name="myStrategy"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>
- 在Spring Boot的核心配置文件裏添加Ehcache配置文件路徑
spring.cache.ehcache.cofnig=ehcache.xml
- 在Spring Boot的啓動類上開啓緩存支持
@EnableCaching
- 在需要添加緩存支持的方法上加上緩存相關的註解
@Cacheable
@CacheEvict
Spring Boot整合Spring Data Redis
Spring Data Redis是Spring Data下的一個模塊。作用就是簡化對redis的操作。
- 修改pom文件,導入Spring-Data-Redis啓動器
<dependencies>
<!-- springBoot 的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data Redis 的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
- 在Spring Boot的核心配置文件配置Redis相關的參數
spring.redis.pool.max-idle=10
spring.redis.pool.min-idle=5
spring.redis.pool.max-total=20
spring.redis.hostName=192.168.70.128
spring.redis.port=6379
- 編寫Spring Data Redis的配置類
詳細整合可以參考一下兩篇博客:
SpringBoot2.x整合Redis || SpringBoot2.x整合Redis-使用Spring緩存註解操作Redis
Spring Boot定時任務
- Scheduled定時任務器
- 整合Quartz定時任務框架
Scheduled定時任務器
Scheduled定時任務器:是Spring3.0以後自帶的一個定時任務器。
- 修改pom文件,添加Scheduled的jar包
<dependencies>
<!-- springBoot 的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加 Scheduled 座標 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
</dependencies>
- 創建一個專門保存定時任務方法的類,並讓Spring去管理,在該類的定時任務方法上加上@Scheduled註解,該註解有一個cron屬性(cron表達式,定時任務觸發時的時間的一個字符串表達形式)。
- 開啓Spring對定時任務的支持,默認是不開啓的,在啓動類上加入如下註解。
@EnableScheduling
Cron表達式
Cron 表達式是一個字符串,分爲 6 或 7 個域,每一個域代表一個含義 Cron 有如下兩種語法格式:
(1) Seconds Minutes Hours Day Month Week Year
(2)Seconds Minutes Hours Day Month Week
一、結構
corn從左到右(用空格隔開):秒 分 小時 月份中的日期 月份 星期中的日期 年份
二、各字段的含義
位置 | 時間域名 | 允許值 | 允許的特殊字符 |
---|---|---|---|
1 | 秒 | 0-59 | , - * / |
2 | 分鐘 | 0-59 | , - * / |
3 | 小時 | 0-23 | , - * / |
4 | 日 | 1-31 | , - * / L W C |
5 | 月 | 1-12 | , - * / |
6 | 星期 | 1-7 | , - * ? / L C # |
7 | 年(可選) | 1970-2099 | , - * / |
Cron 表達式的時間字段除允許設置數值外,還可使用一些特殊的字符,提供列表、範圍、通配符等功 能,細說如下:
●星號(*):可用在所有字段中,表示對應時間域的每一個時刻,例如,在分鐘字段時,表示“每分鐘”;
●問號(?):該字符只在日期和星期字段中使用,它通常指定爲“無意義的值”,相當於佔位符;
●減號(-):表達一個範圍,如在小時字段中使用“10-12”,則表示從 10 到 12 點,即 10,11,12;
●逗號(,):表達一個列表值,如在星期字段中使用“MON,WED,FRI”,則表示星期一,星期三和星期
五;
●斜槓(/):x/y 表達一個等步長序列,x 爲起始值,y 爲增量步長值。如在分鐘字段中使用 0/15,則 表示爲 0,15,30和 45 秒,而 5/15 在分鐘字段中表示5,20,35,50,你也可以使用/y,它等同於 0/y;
●L:該字符只在日期和星期字段中使用,代表“Last”的意思,但它在兩個字段中意思不同。L 在日期 字段中,表示這個月份的最後一天,如一月的 31 號,非閏年二月的 28 號;如果 L 用在星期中,則表示星 期六,等同於 7。但是,如果 L 出現在星期字段裏,而且在前面有一個數值 X,則表示“這個月的最後 X 天”, 例如,6L 表示該月的最後星期五;
●W:該字符只能出現在日期字段裏,是對前導日期的修飾,表示離該日期最近的工作日。例如 15W 表示離該月 15 號最近的工作日,如果該月 15 號是星期六,則匹配 14 號星期五;如果 15 日是星期日, 則匹配 16 號星期一;如果 15 號是星期二,那結果就是 15 號星期二。但必須注意關聯的匹配日期不能夠 跨月,如你指定 1W,如果 1 號是星期六,結果匹配的是 3 號星期一,而非上個月最後的那天。W 字符串 只能指定單一日期,而不能指定日期範圍;
●LW組合:在日期字段可以組合使用 LW,它的意思是當月的最後一個工作日;
●井號(#):該字符只能在星期字段中使用,表示當月某個工作日。如 6#3 表示當月的第三個星期五(6 表示星期五,#3 表示當前的第三個),而 4#5 表示當月的第五個星期三,假設當月沒有第五個星期三, 忽略不觸發;
● C:該字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是計劃所關聯的日期, 如果日期沒有被關聯,則相當於日曆中所有日期。例如 5C 在日期字段中就相當於日曆 5 日以後的第一天。 1C 在星期字段中相當於星期日後的第一天。 Cron 表達式對特殊字符的大小寫不敏感,對代表星期的縮寫英文大小寫也不敏感
案例:
@Scheduled(cron = "0 0 1 1 1 ?")//每年一月的一號的 1:00:00 執行一次
@Scheduled(cron = "0 0 1 1 1,6 ?") //一月和六月的一號的 1:00:00 執行一次
@Scheduled(cron = "0 0 1 1 1,4,7,10 ?") //每個季度的第一個月的一號的 1:00:00 執行一次
@Scheduled(cron = "0 0 1 1 * ?")//每月一號 1:00:00 執行一次
@Scheduled(cron="0 0 1 * * *") //每天凌晨 1 點執行一次
Spring Boot整合Quartz
Quartz 的使用思路
- job- 任務 - 你要做什麼事?
- Trigger- 觸發器 - 你什麼時候去做?
- Scheduler- 任務調度 - 你什麼時候需要去做什麼事?
整合步驟
- 修改pom文件,添加Scheduled座標
<dependencies>
<!-- springBoot 的啓動器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Quartz 座標 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加 Scheduled 座標 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Sprng tx 座標 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
- 編寫自定義AdaptableJobFactory類,手動將實例化的任務對象添加到springIOC容器中並且對象注入
AutowireCapableBeanFactory:可以通過此對象將任務對象添加到IOC容器中並完成注入。 - 編寫 Quartz 的啓動類,類似於編寫整合mybatis的配置類
- 修改啓動類,在啓動類上介入如下註解,表示啓動定時任務
@EnableScheduling
最後,放上一個小案例:SpringBoot-center【github】