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

Springboot接口參數(shù)校驗的方法

 更新時間:2024年03月06日 11:59:00   作者:Spirit_NKlaus  
在設(shè)計接口時我們通常需要對接口中的非法參數(shù)做校驗,以降低在程序運行時因為一些非法參數(shù)而導(dǎo)致程序發(fā)生異常的風(fēng)險,這篇文章給大家介紹Springboot接口參數(shù)校驗的方法,感興趣的朋友一起看看吧

在設(shè)計接口時我們通常需要對接口中的非法參數(shù)做校驗,以降低在程序運行時因為一些非法參數(shù)而導(dǎo)致程序發(fā)生異常的風(fēng)險,例如登錄的時候需要校驗用戶名密碼是否為空,創(chuàng)建用戶的時候需要校驗郵件、手機(jī)號碼格式是否準(zhǔn)確。如果在代碼中對接口參數(shù)一個個硬編碼校驗的話就太繁瑣了,代碼可讀性極差。這時不妨試試Validator框架。

原生的依賴是validation-api而hibernate-validator是對validation-api的增強(qiáng),hibernate-validator框架已經(jīng)集成在spring-boot-starter-web中。

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>5.2.0.Final</version>
</dependency>

但從springboot-2.3開始,校驗包被獨立成了一個starter組件,所以需要引入validation和web,而springboot-2.3之前的版本只需要引入web依賴就可以了。 

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

部分常見注解如下:

注解功能
@AssertFalse可以為null,如果不為null的話必須為false
@AssertTrue可以為null,如果不為null的話必須為true
@DecimalMax設(shè)置不能超過最大值
@DecimalMin設(shè)置不能超過最小值
@Digits設(shè)置必須是數(shù)字且數(shù)字整數(shù)的位數(shù)和小數(shù)的位數(shù)必須在指定范圍內(nèi)
@Future日期必須在當(dāng)前日期的未來
@Past日期必須在當(dāng)前日期的過去
@Max最大不得超過此最大值
@Min最大不得小于此最小值
@NotNull不能為null,可以是空
@Null必須為null
@Pattern必須滿足指定的正則表達(dá)式
@Size集合、數(shù)組、map等的size()值必須在指定范圍內(nèi)
@Email必須是email格式
@Length長度必須在指定范圍內(nèi)
@NotBlank字符串不能為null,字符串trim()后也不能等于“”
@NotEmpty不能為null,集合、數(shù)組、map等size()不能為0;字符串trim()后可以等于“”
@Range值必須在指定范圍內(nèi)
@URL必須是一個URL

一、基礎(chǔ)注解使用 

注解簡單演示類

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@Data
public class UserVo {
    @Length(min = 4, max = 12, message = "賬號長度必須位于4到10之間")
    private String userCode;
    @NotBlank(message = "用戶名不能為空")
    private String userName;
    @Email(message = "郵箱格式有誤")
    private String email;
    @Pattern(regexp = "^1[3456789]\\d{9}$", message = "手機(jī)號格式錯誤")
    private String phone;
    /**
     * 0:普通用戶;VIP:會員用戶;2:超級VIP用戶
     */
    @Pattern(regexp = "[012]", message = "用戶類型有誤,請輸入0:普通用戶;VIP:會員用戶;2:超級VIP用戶")
    private String type;
}

在全局異常處理里面加上對參數(shù)校驗異常的攔截

    @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    public ResponseVo validatedExceptionHandler(Exception e) {
        log.error("參數(shù)校驗異常!原因是{}", e);
        if (e instanceof MethodArgumentNotValidException) {
            //BeanValidation exception
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            return ResponseVo.error(ResponseEnum.BODY_NOT_MATCH.getResultCode(),
                    ex.getBindingResult().getAllErrors().stream()
                            .map(ObjectError::getDefaultMessage)
                            .collect(Collectors.joining("; ")));
        } else if (e instanceof ConstraintViolationException) {
            //BeanValidation GET simple param
            ConstraintViolationException ex = (ConstraintViolationException) e;
            return ResponseVo.error(ResponseEnum.BODY_NOT_MATCH.getResultCode(),
                    ex.getConstraintViolations().stream()
                            .map(ConstraintViolation::getMessage)
                            .collect(Collectors.joining("; ")));
        } else if (e instanceof BindException) {
            //BeanValidation GET object param
            BindException ex = (BindException) e;
            return ResponseVo.error(ResponseEnum.BODY_NOT_MATCH.getResultCode(),
                    ex.getAllErrors().stream()
                            .map(ObjectError::getDefaultMessage)
                            .collect(Collectors.joining("; ")));
        }
        return ResponseVo.error(ResponseEnum.BODY_NOT_MATCH.getResultCode(), ResponseEnum.BODY_NOT_MATCH.getResultMsg());
    }

 定義參數(shù)校驗的controller

import com.yx.light.element.mybatis.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.Email;
@RestController
@RequestMapping(value = "/valid")
@Validated
@Slf4j
public class ValidController {
    /**
     * 單參數(shù)校驗,單參數(shù)需要在controller上加上@Validated配合使用
     * @param email
     * @return
     */
    @PostMapping(value = "/oneParam", produces = "application/json; charset=UTF-8")
    public String oneParam(@Email(message = "郵箱格式有誤") String email) {
        log.info("校驗郵箱為:{}", email);
        return "郵箱校驗成功";
    }
    /**
     * body類型校驗
     * @param vo
     * @return
     */
    @PostMapping(value = "/bodyParam", produces = "application/json; charset=UTF-8")
    public String bodyParam(@Validated @RequestBody UserVo vo) {
        log.info("校驗body為:{}", vo);
        return "body校驗成功";
    }
    /**
     * 表單參數(shù)校驗
     * @param vo
     * @return
     */
    @PostMapping(value = "/formParam", produces = "application/json; charset=UTF-8")
    public String formParam(@Validated UserVo vo) {
        log.info("校驗表單為:{}", vo);
        return "表單校驗成功";
    }
}

oneParam接口

bodyParam接口

formParam接口

 二、自定義參數(shù)校驗

當(dāng)然你也可以自定義參數(shù)校驗,出現(xiàn)有些復(fù)雜的邏輯基本注解是沒辦法兼容的,需要我們自己去實現(xiàn)自動校驗。

自定義校驗注解

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
@Retention(RUNTIME)
@Target({FIELD, METHOD, PARAMETER, TYPE})
@Constraint(validatedBy = UserValidation.UniqueUserValidator.class)
public @interface UniqueUser {
    String message() default "用戶編碼、手機(jī)號碼、郵箱不允許與現(xiàn)存用戶重復(fù)";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

 想讓自定義驗證注解生效,需要實現(xiàn)ConstraintValidator接口。接口的第一個參數(shù)是 自定義注解類型,第二個參數(shù)是 被注解字段的類。

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.util.function.Predicate;
@Slf4j
public class UserValidation<T extends Annotation> implements ConstraintValidator<T, UserVo> {
    protected Predicate<UserVo> predicate = c -> true;
    @Override
    public boolean isValid(UserVo user, ConstraintValidatorContext constraintValidatorContext) {
        return predicate.test(user);
    }
    /**
     * 校驗用戶是否唯一
     * 即判斷數(shù)據(jù)庫是否存在當(dāng)前新用戶的信息,如用戶編碼,手機(jī),郵箱
     */
    public static class UniqueUserValidator extends UserValidation<UniqueUser> {
        @Override
        public void initialize(UniqueUser uniqueUser) {
            predicate = c -> !existsUser(c.getUserCode(), c.getEmail(), c.getPhone());
        }
        private boolean existsUser(String userCode, String email, String phone) {
            //TODO 寫一個數(shù)據(jù)庫查詢判斷是否存在相同的用戶,省略...
            return true;
        }
    }
}

在controller中添加測試接口

@PostMapping(value = "/addUser", produces = "application/json; charset=UTF-8")
public String addUser(@UniqueUser @Validated @RequestBody UserVo vo) {
	log.info("校驗body為:{}", vo);
	return "新增成功";
}

addUser接口 

 三、分組校驗

如果你的一個實體中的字段某一些是新增的時候必傳,某一些修改時又不用傳,那么對于不用傳的字段肯定不需要校驗的,這時候如果我們共用一個實體作為多個接口參數(shù)那肯定存在兼容問題,此時你就可以考慮將參數(shù)分組判斷。

定義一個分組接口ValidGroup讓其繼承javax.validation.groups.Default,再在分組接口中定義出多個不同的操作類型,Create,Update,Query,Delete。

import javax.validation.groups.Default;
public interface ValidGroup extends Default {
    interface Crud extends ValidGroup {
        interface Create extends Crud {
        }
        interface Update extends Crud {
        }
        interface Query extends Crud {
        }
        interface Delete extends Crud {
        }
    }
}

稍微修改一下原來的vo,給他們加上分組參數(shù)groups

import com.yx.light.element.mybatis.validation.ValidGroup;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@Data
public class UserVo {
    @Length(min = 4, max = 12, message = "賬號長度必須位于4到10之間", groups = ValidGroup.Crud.Update.class)
    private String userCode;
    @NotBlank(message = "用戶名不能為空", groups = ValidGroup.Crud.Create.class)
    private String userName;
    @Email(message = "郵箱格式有誤")
    private String email;
    @Pattern(regexp = "^1[3456789]\\d{9}$", message = "手機(jī)號格式錯誤")
    private String phone;
    /**
     * 0:普通用戶;VIP:會員用戶;2:超級VIP用戶
     */
    @Pattern(regexp = "[012]", message = "用戶類型有誤,請輸入0:普通用戶;VIP:會員用戶;2:超級VIP用戶")
    private String type;
}

在controller中添加如下方法,這里我們通過value屬性給addUserV2()和updateUser()方法分別指定Create和Update分組。

@PostMapping(value = "/addUserV2", produces = "application/json; charset=UTF-8")
public String addUserV2(@Validated(value = ValidGroup.Crud.Create.class) @RequestBody UserVo vo) {
	log.info("校驗body為:{}", vo);
	return "新增成功";
}
@PostMapping(value = "/updateUser", produces = "application/json; charset=UTF-8")
public String updateUser(@Validated(value = ValidGroup.Crud.Update.class) @RequestBody UserVo vo) {
	log.info("校驗body為:{}", vo);
	return "更新成功";
}

addUserV2接口

updateUser接口

到此這篇關(guān)于Springboot接口參數(shù)校驗的文章就介紹到這了,更多相關(guān)Springboot參數(shù)校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 全面掌握網(wǎng)絡(luò)編程篇

    Java 全面掌握網(wǎng)絡(luò)編程篇

    網(wǎng)絡(luò)編程是指編寫運行在多個設(shè)備(計算機(jī))的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。java.net 包中 J2SE 的 API 包含有類和接口,它們提供低層次的通信細(xì)節(jié)。你可以直接使用這些類和接口,來專注于解決問題,而不用關(guān)注通信細(xì)節(jié)
    2021-10-10
  • 在Spring Boot中使用swagger-bootstrap-ui的方法

    在Spring Boot中使用swagger-bootstrap-ui的方法

    這篇文章主要介紹了在Spring Boot中使用swagger-bootstrap-ui的方法,需要的朋友可以參考下
    2018-01-01
  • Java將CSV的數(shù)據(jù)發(fā)送到kafka的示例

    Java將CSV的數(shù)據(jù)發(fā)送到kafka的示例

    這篇文章主要介紹了Java將CSV的數(shù)據(jù)發(fā)送到kafka得示例,幫助大家更好得理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • SpringBoot處理跨域請求的四種方法

    SpringBoot處理跨域請求的四種方法

    在現(xiàn)代Web應(yīng)用中,由于安全性和隱私的考慮,瀏覽器限制了從一個域向另一個域發(fā)起的跨域HTTP請求,解決這個問題的一種常見方式是實現(xiàn)跨域資源共享(CORS),SpringBoot提供了多種方式來處理跨域請求,本文將介紹其中的幾種方法,感興趣的朋友可以參考下
    2023-12-12
  • 最新評論