springboot2.0中Spring MVC的JSR具體體現Hibernate Validator,Spring Boot自定義過濾器Filter
宣告,基於springboot 上一篇博文 ,地址:
https://blog.csdn.net/weixin_42323802/article/details/83964225
在spring中,輸入驗證提供2種方式,一種基於spring框架,一種基於Hibernate Validator;
Hibernate Validator是JSR規範請求(Java Specification Request)的具體體現,其中包含了大部分輸入驗證所需要的註解,也可以自定義添加註解;
子模組專案結構:
首先在 WebController 新增一個儲存的方法 saveUser,引數為 User。
/**
* @valid 註解表明 該物件開啟了結果校驗
* BindingResult 是把校驗結果儲存到該物件中,若校驗通過儲存,不通過把錯誤資訊打印出來
* 校驗,需要在user中,對不同的filed 新增不同的校驗規則;
* @param user
* @param result
* @return
*/
@RequestMapping("/saveUser")
public void saveUser(@Valid User user, BindingResult result) {
System.out.println(user);
// 對校驗結果進行判斷,獲取校驗資訊
if (result.hasErrors()){
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError error : allErrors) {
System.out.println(error.getCode()+""+error.getDefaultMessage());
}
}
}
接下來在 User 中給需要校驗的引數新增對應的註解,對不同的屬性,按照規則新增不同的校驗內容。
/**
* @auther SyntacticSugar
* @data 2018/11/11 0011下午 10:03
*/
public class User {
@NotEmpty(message = "姓名不能夠為空")
private String name;
@Max(value = 100,message = "年齡不能夠大於100歲")
private int age;
@Length(min = 6,message = "密碼長度不能夠小於6位")
private String pass;
// getter setter
.......
}
新增 test 方法、執行
/**
* 對user 的屬性 進行valid 測試
*/
@Test
public void saveUsers() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/saveUser").param("name","").
param("age","666").param("pass","123"));
}
結果顯示均已經觸發了校驗規則,返回了錯誤資訊;Hibernate Validator 常見的註解如下:
註解 | 應用目標 | 執行時檢查 | Hibernate 元資料影響 |
---|---|---|---|
@Length(min=, max=) | 屬性(String) | 檢查字串長度是否符合範圍 | 列長度會被設到最大值 |
@Max(value=) | 屬性(以 numeric 或者 string 型別來表示一個數字) | 檢查值是否小於或等於最大值 | 對列增加一個檢查約束 |
@Min(value=) | 屬性(以 numeric 或者 string 型別來表示一個數字) | 檢查值是否大於或等於最小值 | 對列增加一個檢查約束 |
@NotNull | 屬性 | 檢查值是否非空(not null) | 列不為空 |
@Past | 屬性(date 或 calendar) | 檢查日期是否是過去時 | 對列增加一個檢查約束 |
@Future | 屬性(date 或 calendar) | 檢查日期是否是將來時 | 無 |
@Pattern(regex=“regexp”, flag=) | 屬性(string) | 檢查屬性是否與給定匹配標誌的正則表示式相匹配(見 java.util.regex.Pattern ) | 無 |
@Range(min=, max=) | 屬性(以 numeric 或者 string 型別來表示一個數字) | 檢查值是否在最小和最大值之間(包括臨界值) | 對列增加一個檢查約束 |
@Size(min=, max=) | 屬性(array,collection,map) | 檢查元素大小是否在最小和最大值之間(包括臨界值) | 無 |
@AssertFalse | 屬性 | 檢查方法的演算結果是否為 false(對以程式碼方式而不是註解表示的約束很有用) | 無 |
@AssertTrue | 屬性 | 檢查方法的演算結果是否為 true(對以程式碼方式而不是註解表示的約束很有用) | 無 |
@Valid | 屬性(object) | 對關聯物件遞迴進行驗證。如果物件是集合或陣列,就遞迴地驗證其元素;如果物件是 Map,則遞迴驗證其值元素 | 無 |
屬性(String) | 檢查字串是否符合有效的 email 地址規範 | 無 |
Spring Boot自定義 Filter;
Spring Boot中自定義過濾器 Filter 有兩種實現方式,@WebFilter 和FilterRegistrationBean ;但是第一種不支援順序優先順序;
自定義 Filter 兩個步驟:
-> 實現 Filter 介面,實現其中的 doFilter() 方法;
-> 新增 @Configuration 註解,將自定義 Filter 加入過濾鏈。
->新建 MyFilter 類,重寫 doFilter() 方法:
自定義 MyFilter ,和 MyFilter2 ;
package com.neo.springbootweb.filter;
/**
* @auther SyntacticSugar
* @data 2018/11/12 0012上午 10:15
*/
// filter 導包javax.servlet.Filter;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// url級別的filter
HttpServletRequest request= (HttpServletRequest) servletRequest;
System.out.println("這是自定義的filter,url"+request.getRequestURI());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {}
}
MyFilter2為MyFilter copy 一份並更改列印內容;然後將自定義 Filter 加入過濾鏈:
/**
* @auther SyntacticSugar
* @data 2018/11/12 0012上午 10:26
*/
@Configuration
public class WebConfiguration {
/**
* :http://localhost:8080/getUsers 進行訪問
* @RequestMapping(value = "/getUsers",method = RequestMethod.POST)
* 需要把 method = RequestMethod.POST 去掉,不然不支援get請求
* @return
*/
@Bean
public FilterRegistrationBean testFilterRegistrationBean() {
FilterRegistrationBean frb = new FilterRegistrationBean();
// 把自定義的filter 傳進去
frb.setFilter(new MyFilter());
//
frb.addUrlPatterns("/*");
frb.setName("MyFilter");
frb.setOrder(6);
return frb;
}
/**
* 把 Myfilter2 新增到過濾器中,設定 order 為1
* order 越低,優先順序越高;
* @return
*/
@Bean
public FilterRegistrationBean test2FilterRegistrationBean() {
FilterRegistrationBean frb = new FilterRegistrationBean();
// 把自定義的filter 傳進去
frb.setFilter(new MyFilter2());
//
frb.addUrlPatterns("/*");
frb.setName("MyFilter2");
frb.setOrder(1);
return frb;
}
}
將 MyFilter 的 Order 屬性設定為 6,將 MyFilter2 的 Order 屬性設定為 1,重新啟動專案,在瀏覽器中輸入地址:http://localhost:8080/getUsers,就會看到控制檯列印如下資訊:
MyFilter2 具有較高的優先順序;
在 Web 開發的過程中,經常需要自定義一些配置檔案,如何使用呢?
->在 application.properties 中配置:
neo.title=打豆豆
neo.description=品味生活
->在 other.properties 中配置:
other.title=keep smile
other.blog=www.youknow.com
->注:同時存在 application.yml 和 application.properties,並且裡面配置相同,application.properties 的配置會覆蓋 application.yml。
建立單元測試:
package com.neo.springbootweb;
/**
* @auther SyntacticSugar
* @data 2018/11/12 0012上午 11:08
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertiesTest {
/**
* 對自定義的 properties 進行測試
*/
@Value("${neo.title}")
private String title;
@Test
public void test() {
Assert.assertEquals(title, "打豆豆1");
}
}
/**
* @Value("${neo.title}") 預設讀取application.properties檔案中neo.title 賦值給title
* Assert.assertEquals用來判斷 title 和“ 打豆豆 ”是否一致;
*/
執行結果如下,不一致 test不通過,執行測試用例執行正常,說明屬性值載入成功。
讀取多個配置:
定義一個 NeoProperties 物件,來接收所有以 neo 開頭的配置內容。
/**
* @auther SyntacticSugar
* @data 2018/11/12 0012上午 11:55
*/
@ConfigurationProperties(prefix = "neo")
@Component
public class NeoProperties {
private String title;
private String description;
// setter getter
}
@ConfigurationProperties(prefix = “neo”)
neo 開頭的 自動賦值到物件的屬性中,neo.description 賦值到>description中
@Component 交給ioC
單元測試,把NeoProperties 物件注入即可;
/**
* 新增 @PropertySource 指定配置檔案的位置
*/
@ConfigurationProperties(prefix = "other")
@Component
@PropertySource("classpath:other.properties")
public class OtherProperties {
private String title;
private String blog;
// getter setter
}
自定義一個配置檔案
有時候需要自定義配置檔案,以便和系統使用的 application.properties 檔案區分開,避免混淆。Spring Boot 對這種情況也有很好的支援。
在 resources 目錄下建立一個 other.properties 檔案,內容如下:
@Autowired
private NeoProperties neoProperties;
@Test
public void testMore() {
System.out.println("title:" + neoProperties.getTitle());
System.out.println("description:" + neoProperties.getDescription());
}
/**
* 其他的配置類
*/
@Autowired
private OtherProperties otherProperties;
@Test
public void testOther() {
System.out.println("title:" + otherProperties.getTitle());
System.out.println("description:" + otherProperties.getBlog());
}
分別執行單元測試如下:
title:打豆豆
description:品味生活
說明成功;
列印結果:
title:keep smile
description:www.youknow.com
->自定義的other.properties 也成功了;
如果測試中出現中文亂碼,可按照以下方法進行設定:
依次單擊 File | Settings | Editor | File Encodings 命令,將 Properties Files (*.properties) 下的 Default encoding for properties files 設定為 UTF-8,勾選 Transparent native-to-ascii conversion 複選框。
參考資料來自:
純潔的微笑 大神的分享 https://me.csdn.net/ityouknow