1. 程式人生 > >springboot2.0中Spring MVC的JSR具體體現Hibernate Validator,Spring Boot自定義過濾器Filter

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"));
    }

hgjds

結果顯示均已經觸發了校驗規則,返回了錯誤資訊;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,則遞迴驗證其值元素
@Email 屬性(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 具有較高的優先順序;

j


在 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