欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JSR303校驗(yàn)前端傳遞的數(shù)據(jù)方式

 更新時(shí)間:2024年01月12日 10:33:59   作者:龍域、白澤  
這篇文章主要介紹了JSR303校驗(yàn)前端傳遞的數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

介紹

JSR-303規(guī)范(Bean Validation規(guī)范)提供了對 Java EE 和 Java SE 中的 Java Bean 進(jìn)行驗(yàn)證的方式。

該規(guī)范主要使用注解的方式來實(shí)現(xiàn)對 Java Bean 的驗(yàn)證功能。

作用

前端傳遞數(shù)據(jù)到后端時(shí),可以使用其對Bean對象的屬性進(jìn)行合法性校驗(yàn)。

快速開始

導(dǎo)入依賴

<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Java Bean

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    @TableId
    private Long id;
 
    @NotBlank(message = "用戶名不能為空")
    @TableField("user_name")
    private String userName;
 
    @Size(max = 20,min = 6,message = "密碼的長度必須在6-20位")
    @TableField("pass_word")
    private String passWord;
 
    @TableField("group_id")
    private Long groupId;
 
    @Max(value = 100, message = "城市編號不等大于100")
    @TableField("city_id")
    private Long cityId;
 
    @Email(message = "郵件不合法")
    @TableField("email")
    private String email;
}

統(tǒng)一返回結(jié)果

統(tǒng)一響應(yīng)結(jié)果枚舉類

@Getter
@AllArgsConstructor
@ToString
public enum ResponseEnum {
 
    SUCCESS(0, "成功"),
    ERROR(-1, "服務(wù)器內(nèi)部錯誤"),
 
    private final Integer code;
 
    private final String message;
}

統(tǒng)一結(jié)果返回類

@Data
public class R {
 
    private Integer code;
 
    private String message;
 
    /**
     * 返回的數(shù)據(jù)
     */
    private Map<String, Object> data = new HashMap<>();
 
    private R() {
    }
 
    public static R ok() {
        return setResult(ResponseEnum.SUCCESS);
    }
 
    public static R error() {
        return setResult(ResponseEnum.ERROR);
    }
 
    /**
     * 設(shè)置特定結(jié)果
     */
    public static R setResult(ResponseEnum responseEnum) {
        R r = new R();
        r.setCode(responseEnum.getCode());
        r.setMessage(responseEnum.getMessage());
        return r;
    }
 
    /**
     * 設(shè)置響應(yīng)消息
     */
    public R message(String message) {
        this.setMessage(message);
        return this;
    }
 
    public R code(Integer code) {
        this.setCode(code);
        return this;
    }
 
    public R data(String key, Object value) {
        this.data.put(key, value);
        return this;
    }
 
    public R data(Map<String, Object> map) {
        this.setData(map);
        return this;
    }
}

方法一

Bean對象的下一個位置的參數(shù)寫B(tài)indingResult對象,當(dāng)JSR303校驗(yàn)失敗后可以由BindResult對象捕獲異常

controller層

@Valid注解后面的對象是要校驗(yàn)的Bean對象

Bean對象的下一個位置的參數(shù)寫B(tài)indingResult對象

@RestController
@RequestMapping("/user")
public class UserController {
 
    @Resource
    private UserServiceImpl userService;
 
    @PostMapping
    public R addUser(@Valid @RequestBody User user, BindingResult bindingResult) {
        Map<String, Object> map = new HashMap<>();
        // 判斷是否有錯誤
        if (bindingResult.hasErrors()) {
            // 如果有錯誤,遍歷錯誤信息,添加到Map中
            bindingResult.getFieldErrors().forEach((item) -> {
                // 獲取錯誤提示
                String message = item.getDefaultMessage();
                // 獲取錯誤的屬性名稱
                String field = item.getField();
                map.put(field, message);
            });
            return R.error().message("參數(shù)信息錯誤").data(map);
        }
        userService.save(user);
        return R.ok();
    }
}

方法二

當(dāng)接口非常多,每一個接口都要寫校驗(yàn)非常麻煩,寫一個統(tǒng)一異常處理的類來集中處理異常

統(tǒng)一異常處理類

@Slf4j
@Component //Spring容易自動管理
@RestControllerAdvice //在controller層添加通知。當(dāng)Controller層出現(xiàn)異常,這里的方法會捕獲異常,返回錯誤信息(相當(dāng)于服務(wù)降級)
public class UnifiedExceptionHandler {
 
    /**
     * 參數(shù)校驗(yàn)異常處理
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException e) {
        log.error("數(shù)據(jù)校驗(yàn)出現(xiàn)問題{}, 異常類型{}", e.getMessage(), e.getClass());
        BindingResult bindingResult = e.getBindingResult();
        Map<String, Object> map = new HashMap<>();
        bindingResult.getFieldErrors().forEach((item) -> {
            map.put(item.getField(), item.getDefaultMessage());
        });
        return R.error().message("參數(shù)信息錯誤").data(map);
    }
}

controller層

接口方法的參數(shù)如果有BindResult對象,代表校驗(yàn)出錯由BindResult接受異常

接口方法的參數(shù)沒有BindResult對象,代表校驗(yàn)出錯將拋出異常,被統(tǒng)一異常處理類的方法接受

接口方法的參數(shù)沒有BindResult對象,也沒有統(tǒng)一異常處理類的方法接受,就拋出400的異常

@PostMapping
public R addUser(@Valid @RequestBody User user) {
    userService.save(user);
    return R.ok();
}

測試

校驗(yàn)成功的測試

請求體的JSON數(shù)據(jù)

{
	"userName": "lixianchichi",
	"passWord": "104ee44",
	"groupId": 1,
	"cityId": 14,
	"email": "123456@qq.com"
}

返回的響應(yīng)信息

{
    "code": 0,
    "message": "成功",
    "data": {}
}

校驗(yàn)失敗的測試

請求體的JSON數(shù)據(jù)

{
	"userName": "lixianchichi",
	"passWord": "10444eeeeeeeeeeeeeeeeee44",
	"groupId": 1,
	"cityId": 1514,
	"email": "123456@qq.com"
}

返回的響應(yīng)信息

{
    "code": -1,
    "message": "參數(shù)信息錯誤",
    "data": {
        "passWord": "密碼的長度必須在6-20位",
        "cityId": "城市編號不等大于100"
    }
}

方法一與方法二測試結(jié)果相同,都為如上結(jié)果

分組校驗(yàn)

使用場景:不同情況下的校驗(yàn)規(guī)則是不同的,如新增的時(shí)候自動生成Id,所以數(shù)據(jù)不需要攜帶Id,而修改的時(shí)候必須要攜帶Id(不同場景觸發(fā)不同的校驗(yàn)條件)

創(chuàng)建valid包

包里面創(chuàng)建兩個空接口InsertGroup和UpdateGroup,代表新增和修改兩種環(huán)境。

Java Bean

每一個Bean校驗(yàn)注解都有一個groups屬性,值是一個接口字節(jié)碼對象的數(shù)據(jù),用來指定環(huán)境。

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    @TableId
    // 更新的時(shí)候校驗(yàn)
    @NotNull(message = "修改用戶id不能為null" ,groups = {UpdateGroup.class})
    // 新增的時(shí)候校驗(yàn)
    @Null(message = "新增用戶id必須為null" ,groups = {InsertGroup.class})
    private Long id;
 
    // 新增和修改的時(shí)候都校驗(yàn)
    @NotBlank(message = "用戶名不能為空" ,groups = {InsertGroup.class, UpdateGroup.class})
    @TableField("user_name")
    private String userName;
 
    ...
    // 修改的時(shí)候判斷email是否合法,可以null,不報(bào)錯(不傳就不校驗(yàn))
    @Email(message = "郵件不合法" ,groups = {UpdateGroup.class})
    @TableField("email")
    private String email;
}

controller層

使用@Validated代替@Valid注解,該注解可以指定環(huán)境(接口字節(jié)碼對象),

如下:代表當(dāng)前是新增的情況

@PostMapping
public R addUser(@Validated({InsertGroup.class}) @RequestBody User user) {
    userService.save(user);
    return R.ok();
}

注意:沒有指定groups屬性的注解,在controller層指定環(huán)境的情況下,不會生效

測試

在新增環(huán)境,前端傳遞JSON對象如果帶Id屬性

@PostMapping
public R addUser(@Validated({InsertGroup.class}) @RequestBody User user) {
    userService.save(user);
    return R.ok();
}

響應(yīng)結(jié)果

{
    "code": -1,
    "message": "參數(shù)信息錯誤",
    "data": {
        "id": "新增用戶id必須為null"
    }
}

在修改環(huán)境,前端傳遞JSON對象如果帶Id屬性

@PostMapping
public R addUser(@Validated({UpdateGroup.class}) @RequestBody User user) {
    userService.save(user);
    return R.ok();
}

響應(yīng)結(jié)果

{
    "code": -1,
    "message": "參數(shù)信息錯誤",
    "data": {
        "id": "修改用戶id不能為null"
    }
}

自定義校驗(yàn)注解

實(shí)現(xiàn)功能:校驗(yàn)Bean的某個屬性的字段只能是0和1

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    ...
    @TableField("group_id")
    @ListValue(vals = {0L, 1L}, groups = {UpdateGroup.class})
    private Long groupId;
    ...
}

自定義的校驗(yàn)注解

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 指定校驗(yàn)器,可以指定多個校驗(yàn)器,會自動適配,如:此注解還有一個Double數(shù)組的屬性,再添加一個Double類型的校驗(yàn)器,當(dāng)我們使用注解的時(shí)候,我們給Double數(shù)組賦值,就會自動找Double類型的校驗(yàn)器校驗(yàn)
@Constraint(validatedBy = {ListValueCondtraintValidator.class})
public @interface ListValue {
    
    // 前三個屬性都是每個JSR303注解必須有的
    // 默認(rèn)錯誤信息,從properties里獲取值
    String message() default "{com.lixianhe.valid.listValue.message}";
 
    Class<?>[] groups() default {};
 
    Class<? extends Payload>[] payload() default {};
    
    long[] vals() default {};
}

自定義校驗(yàn)器

/**
 * 自定義校驗(yàn)器
 */
public class ListValueCondtraintValidator implements ConstraintValidator<ListValue, Long> {
 
    private Set<Long> set = new HashSet<>();
 
    /**
     * 初始化方法
     *
     * @param constraintAnnotation
     */
    @Override
    public void initialize(ListValue constraintAnnotation) {
        long[] vals = constraintAnnotation.vals();
        for (long val : vals) {
            set.add(val);
        }
    }
 
    /**
     * 判斷是否校驗(yàn)成功
     *
     * @param value                      需要校驗(yàn)的值
     * @param constraintValidatorContext
     * @return 校驗(yàn)結(jié)果
     */
    @Override
    public boolean isValid(Long value, ConstraintValidatorContext constraintValidatorContext) {
        return set.contains(value);
    }
}

測試

當(dāng)groupId傳2的時(shí)候

{
	"userName": "lixianchichi",
	"passWord": "104eefd454545546456565tygpl[per44",
	"groupId": 2,
	"cityId": 10
}

響應(yīng)結(jié)果

{
    "code": -1,
    "message": "參數(shù)信息錯誤",
    "data": {
        "groupId": "必須提交指定的值"
    }
}

補(bǔ)充

Java Bean校驗(yàn)注解總結(jié)

限制說明
@Null限制只能為null
@NotNull限制必須不為null
@AssertFalse限制必須為false
@AssertTrue限制必須為true
@DecimalMax(value)限制必須為一個不大于指定值的數(shù)字
@DecimalMin(value)限制必須為一個不小于指定值的數(shù)字
@Digits(integer,fraction)限制必須為一個小數(shù),且整數(shù)部分的位數(shù)不能超過integer,小數(shù)部分的位數(shù)不能超過fraction
@Future限制必須是一個將來的日期
@Max(value)限制必須為一個不大于指定值的數(shù)字
@Min(value)限制必須為一個不小于指定值的數(shù)字
@Past限制必須是一個過去的日期
@Pattern(value)限制必須符合指定的正則表達(dá)式
@Size(max,min)限制字符長度必須在min到max之間
@Past驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間早
@NotEmpty驗(yàn)證注解的元素值不為null且不為空(字符串長度不為0、集合大小不為0)
@NotBlank驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會去除字符串的空格
@Email驗(yàn)證注解的元素值是Email,也可以通過正則表達(dá)式和flag指定自定義的email格式
@URL校驗(yàn)是否位合法的URL

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實(shí)現(xiàn)鏈表數(shù)據(jù)結(jié)構(gòu)的方法

    Java實(shí)現(xiàn)鏈表數(shù)據(jù)結(jié)構(gòu)的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)鏈表數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,每一個鏈表都包含多個節(jié)點(diǎn),節(jié)點(diǎn)又包含兩個部分,一個是數(shù)據(jù)域(儲存節(jié)點(diǎn)含有的信息),一個是引用域(儲存下一個節(jié)點(diǎn)或者上一個節(jié)點(diǎn)的地址),需要的朋友可以參考下
    2022-01-01
  • Java Hutool 包工具類推薦 ExcelUtil詳解

    Java Hutool 包工具類推薦 ExcelUtil詳解

    這篇文章主要介紹了Java Hutool 包工具類推薦 ExcelUtil詳解,需要引入hutool包,版本號可根據(jù)實(shí)際情況更換,除hutool包之外,還需要引入操作Excel必要包,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Java Swing JSlider滑塊的實(shí)現(xiàn)示例

    Java Swing JSlider滑塊的實(shí)現(xiàn)示例

    這篇文章主要介紹了Java Swing JSlider滑塊的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 詳解Java中Thread 和Runnable區(qū)別

    詳解Java中Thread 和Runnable區(qū)別

    這篇文章主要介紹了Java中Thread 和Runnable的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 精通Java接口的使用與原理

    精通Java接口的使用與原理

    接口,在JAVA編程語言中是一個抽象類型,是抽象方法的集合,接口通常以interface來聲明。一個類通過繼承接口的方式,從而來繼承接口的抽象方法
    2022-03-03
  • 詳細(xì)分析Java并發(fā)集合LinkedBlockingQueue的用法

    詳細(xì)分析Java并發(fā)集合LinkedBlockingQueue的用法

    這篇文章主要介紹了詳細(xì)分析Java并發(fā)集合LinkedBlockingQueue的用法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java封裝數(shù)組之添加元素操作實(shí)例分析

    Java封裝數(shù)組之添加元素操作實(shí)例分析

    這篇文章主要介紹了Java封裝數(shù)組之添加元素操作,結(jié)合實(shí)例形式分析了Java封裝數(shù)組實(shí)現(xiàn)元素追加、插入等相關(guān)操作技巧,需要的朋友可以參考下
    2020-03-03
  • Idea運(yùn)行單個main方法,不編譯整個工程的問題

    Idea運(yùn)行單個main方法,不編譯整個工程的問題

    這篇文章主要介紹了Idea運(yùn)行單個main方法,不編譯整個工程的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 淺談java監(jiān)聽器的作用

    淺談java監(jiān)聽器的作用

    這篇文章主要介紹了淺談java監(jiān)聽器的作用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • SpringBoot實(shí)現(xiàn)動態(tài)增刪啟停定時(shí)任務(wù)的方式

    SpringBoot實(shí)現(xiàn)動態(tài)增刪啟停定時(shí)任務(wù)的方式

    在spring?boot中,可以通過@EnableScheduling注解和@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù),也可以通過SchedulingConfigurer接口來實(shí)現(xiàn)定時(shí)任務(wù),但是這兩種方式不能動態(tài)添加、刪除、啟動、停止任務(wù),本文給大家介紹SpringBoot實(shí)現(xiàn)動態(tài)增刪啟停定時(shí)任務(wù)的方式,感興趣的朋友一起看看吧
    2024-03-03

最新評論