<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot 參數(shù)校驗(yàn)/參數(shù)驗(yàn)證,常用方法都給你總結(jié)好了!

          共 4419字,需瀏覽 9分鐘

           ·

          2021-12-24 08:39

          1、前言

          在控制器類的方法里自己寫校驗(yàn)邏輯代碼當(dāng)然也可以,只是代碼比較丑陋,有點(diǎn)“l(fā)ow”。業(yè)界有更好的處理方法,分別闡述如下。

          2、PathVariable校驗(yàn)

          @GetMapping("/path/{group:[a-zA-Z0-9_]+}/{userid}")
          @ResponseBody
          public?String?path(@PathVariable("group")?String?group,?@PathVariable("userid")?Integer?userid)?{
          ????return?group?+?":"?+?userid;
          }

          用法是:路徑變量:正則表達(dá)式。當(dāng)請(qǐng)求URI不滿足正則表達(dá)式時(shí),客戶端將收到404錯(cuò)誤碼。不方便的地方是,不能通過(guò)捕獲異常的方式,向前端返回統(tǒng)一的、自定義格式的響應(yīng)參數(shù)。

          3、方法參數(shù)校驗(yàn)

          @GetMapping("/validate1")
          @ResponseBody
          public?String?validate1(
          ????????@Size(min?=?1,max?=?10,message?=?"姓名長(zhǎng)度必須為1到10")
          @RequestParam("name")?String?name,
          ????????@Min(value?=?10,message?=?"年齡最小為10")@Max(value?=?100,message?=?"年齡最大為100")?@RequestParam("age")?Integer?age)?
          {
          ????return?"validate1";
          }

          如果前端傳遞的參數(shù)不滿足規(guī)則,則拋出異常。注解Size、Min、Max來(lái)自validation-api.jar,更多注解參見相關(guān)標(biāo)準(zhǔn)小節(jié)。

          4、表單對(duì)象/VO對(duì)象校驗(yàn)

          當(dāng)參數(shù)是VO時(shí),可以在VO類的屬性上添加校驗(yàn)注解。

          public?class?User?{
          ????@Size(min?=?1,max?=?10,message?=?"姓名長(zhǎng)度必須為1到10")
          ????private?String?name;

          ????@NotEmpty
          ????private?String?firstName;

          ????@Min(value?=?10,message?=?"年齡最小為10")@Max(value?=?100,message?=?"年齡最大為100")
          ????private?Integer?age;

          ????@Future
          ????@JSONField(format="yyyy-MM-dd?HH:mm:ss")
          ????private?Date?birth;
          ????。。。
          }

          其中,F(xiàn)uture注解要求必須是相對(duì)當(dāng)前時(shí)間來(lái)講“未來(lái)的”某個(gè)時(shí)間。

          @PostMapping("/validate2")
          @ResponseBody
          public?User?validate2(@Valid?@RequestBody?User?user){
          ????return?user;
          }

          5、自定義校驗(yàn)規(guī)則

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

          需要自定義一個(gè)注解類和一個(gè)校驗(yàn)類。

          import?javax.validation.Constraint;
          import?javax.validation.Payload;
          import?java.lang.annotation.*;

          @Documented
          @Retention(RetentionPolicy.RUNTIME)
          @Target({ElementType.PARAMETER,ElementType.FIELD})
          @Constraint(validatedBy?=?FlagValidatorClass.class)
          public?@interface?FlagValidator?
          {
          ????//?flag的有效值,多個(gè)使用,隔開
          ????String?values();

          ????//?flag無(wú)效時(shí)的提示內(nèi)容
          ????String?message()?default?"flag必須是預(yù)定義的那幾個(gè)值,不能隨便寫";

          ????Class[]?groups()?default?{};

          ????Class[]?payload()?default?{};
          }
          import?javax.validation.ConstraintValidator;
          import?javax.validation.ConstraintValidatorContext;

          public?class?FlagValidatorClass?implements?ConstraintValidator<FlagValidator,Object>?{
          ????/**
          ?????*?FlagValidator注解規(guī)定的那些有效值
          ?????*/

          ????private?String?values;

          ????@Override
          ????public?void?initialize(FlagValidator?flagValidator)?{
          ????????this.values?=?flagValidator.values();
          ????}

          ????/**
          ?????*?用戶輸入的值,必須是FlagValidator注解規(guī)定的那些值其中之一。
          ?????*?否則,校驗(yàn)不通過(guò)。
          ?????*?@param?value?用戶輸入的值,如從前端傳入的某個(gè)值
          ?????*/

          ????@Override
          ????public?boolean?isValid(Object?value,?ConstraintValidatorContext?constraintValidatorContext)?{
          ????????//?切割獲取值
          ????????String[]?value_array?=?values.split(",");
          ????????Boolean?isFlag?=?false;

          ????????for?(int?i?=?0;?i?????????????//?存在一致就跳出循環(huán)
          ????????????if?(value_array[i]?.equals(value)){
          ????????????????isFlag?=?true;?break;
          ????????????}
          ????????}

          ????????return?isFlag;
          ????}
          }

          使用我們自定義的注解:

          public?class?User?{
          ????//?前端傳入的flag值必須是1或2或3,否則校驗(yàn)失敗
          ????@FlagValidator(values?=?"1,2,3")
          ????private?String?flag?;
          ????。。。
          }
          5.2 分組校驗(yàn)
          import?org.hibernate.validator.constraints.Length;
          import?javax.validation.constraints.Min;
          import?javax.validation.constraints.NotNull;

          public?class?Resume?{
          ????public?interface?Default?{
          ????}

          ????public?interface?Update?{
          ????}

          ????@NotNull(message?=?"id不能為空",?groups?=?Update.class)
          ????private?Long?id
          ;

          ????@NotNull(message?=?"名字不能為空",?groups?=?Default.class)
          ????@Length(min?
          =?4,?max?=?10,?message?=?"name?長(zhǎng)度必須在?{min}?-?{max}?之間",?groups?=?Default.class)
          ????private?String?name
          ;

          ????@NotNull(message?=?"年齡不能為空",?groups?=?Default.class)
          ????@Min(value?
          =?18,?message?=?"年齡不能小于18歲",?groups?=?Default.class)
          ????private?Integer?age
          ;
          ????。。。
          }
          ????/**
          ?????*?使用Defaul分組進(jìn)行驗(yàn)證
          ?????*?@param?resume
          ?????*?@return
          ?????*/

          ????@PostMapping("/validate5")
          ????public?String?addUser(@Validated(value?=?Resume.Default.class)?@RequestBody?Resume?resume)?{
          ????????return?"validate5";
          ????}

          ????/**
          ?????*?使用Default、Update分組進(jìn)行驗(yàn)證
          ?????*?@param?resume
          ?????*?@return
          ?????*/

          ????@PutMapping("/validate6")
          ????public?String?updateUser(@Validated(value?=?{Resume.Update.class,?Resume.Default.class})?@RequestBody?Resume?resume)?{
          ????????return?"validate6";
          ????}

          建立了兩個(gè)分組,名稱分別為Default、Update。POST方法提交時(shí)使用Defaut分組的校驗(yàn)規(guī)則,PUT方法提交時(shí)同時(shí)使用兩個(gè)分組規(guī)則。

          6、異常攔截器

          通過(guò)設(shè)置全局異常處理器,統(tǒng)一向前端返回校驗(yàn)失敗信息。

          import?com.scj.springbootdemo.WebResult;
          import?org.slf4j.Logger;
          import?org.slf4j.LoggerFactory;
          import?org.springframework.util.CollectionUtils;
          import?org.springframework.validation.ObjectError;
          import?org.springframework.web.bind.MethodArgumentNotValidException;
          import?org.springframework.web.bind.annotation.ControllerAdvice;
          import?org.springframework.web.bind.annotation.ExceptionHandler;
          import?org.springframework.web.bind.annotation.ResponseBody;

          import?javax.validation.ConstraintViolation;
          import?javax.validation.ConstraintViolationException;
          import?java.util.List;
          import?java.util.Set;

          /**
          ?*?全局異常處理器
          ?*/

          @ControllerAdvice
          public?class?GlobalExceptionHandler?{

          ????private?Logger?logger?=?LoggerFactory.getLogger(GlobalExceptionHandler.class);

          ????/**
          ?????*?用來(lái)處理bean?validation異常
          ?????*?@param?ex
          ?????*?@return
          ?????*/

          ????@ExceptionHandler(ConstraintViolationException.class)
          ????@ResponseBody
          ????public??WebResult?resolveConstraintViolationException(ConstraintViolationException?ex)
          {
          ????????WebResult?errorWebResult?=?new?WebResult(WebResult.FAILED);
          ????????Set>?constraintViolations?=?ex.getConstraintViolations();
          ????????if(!CollectionUtils.isEmpty(constraintViolations)){
          ????????????StringBuilder?msgBuilder?=?new?StringBuilder();
          ????????????for(ConstraintViolation?constraintViolation?:constraintViolations){
          ????????????????msgBuilder.append(constraintViolation.getMessage()).append(",");
          ????????????}
          ????????????String?errorMessage?=?msgBuilder.toString();
          ????????????if(errorMessage.length()>1){
          ????????????????errorMessage?=?errorMessage.substring(0,errorMessage.length()-1);
          ????????????}
          ????????????errorWebResult.setInfo(errorMessage);
          ????????????return?errorWebResult;
          ????????}
          ????????errorWebResult.setInfo(ex.getMessage());
          ????????return?errorWebResult;
          ????}

          ????@ExceptionHandler(MethodArgumentNotValidException.class)
          ????@ResponseBody
          ????public?WebResult?resolveMethodArgumentNotValidException(MethodArgumentNotValidException?ex)
          {
          ????????WebResult?errorWebResult?=?new?WebResult(WebResult.FAILED);
          ????????List??objectErrors?=?ex.getBindingResult().getAllErrors();
          ????????if(!CollectionUtils.isEmpty(objectErrors))?{
          ????????????StringBuilder?msgBuilder?=?new?StringBuilder();
          ????????????for?(ObjectError?objectError?:?objectErrors)?{
          ????????????????msgBuilder.append(objectError.getDefaultMessage()).append(",");
          ????????????}
          ????????????String?errorMessage?=?msgBuilder.toString();
          ????????????if?(errorMessage.length()?>?1)?{
          ????????????????errorMessage?=?errorMessage.substring(0,?errorMessage.length()?-?1);
          ????????????}
          ????????????errorWebResult.setInfo(errorMessage);
          ????????????return?errorWebResult;
          ????????}
          ????????errorWebResult.setInfo(ex.getMessage());
          ????????return?errorWebResult;
          ????}
          }

          7、相關(guān)標(biāo)準(zhǔn)

          JSR 303 是Bean驗(yàn)證的規(guī)范 ,Hibernate Validator?是該規(guī)范的參考實(shí)現(xiàn),它除了實(shí)現(xiàn)規(guī)范要求的注解外,還額外實(shí)現(xiàn)了一些注解。

          validation-api-1.1.0.jar?包括如下約束注解:

          hibernate-validator-5.3.6.jar?包括如下約束注解:

          8、同時(shí)校驗(yàn)2個(gè)或更多個(gè)字段/參數(shù)

          常見的場(chǎng)景之一是,查詢某信息時(shí)要輸入開始時(shí)間和結(jié)束時(shí)間。顯然,結(jié)束時(shí)間要≥開始時(shí)間??梢栽诓樵?a target="_blank" textvalue="VO類" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2" wah-hotarea="click" hasload="1" style="outline: 0px;text-decoration: underline;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">VO類上使用自定義注解,下面的例子來(lái)自這里。劃重點(diǎn):@ValidAddress使用在類上。

          @ValidAddress
          public?class?Address?{

          ????@NotNull
          ????@Size(max?=?50)
          ????private?String?street1;

          ????@Size(max?=?50)
          ????private?String?street2;

          ????@NotNull
          ????@Size(max?=?10)
          ????private?String?zipCode;

          ????@NotNull
          ????@Size(max?=?20)
          ????private?String?city;

          ????@Valid
          ????@NotNull
          ????private?Country?country;

          ????//?Getters?and?setters
          }
          public?class?Country?{

          ????@NotNull
          ????@Size(min?=?2,?max?=?2)
          ????private?String?iso2;

          ????//?Getters?and?setters
          }
          @Documented
          @Target(TYPE)
          @Retention(RUNTIME)
          @Constraint(validatedBy?=?{?MultiCountryAddressValidator.class?})
          public?@interface?ValidAddress?
          {

          ????String?message()?default?"{com.example.validation.ValidAddress.message}";

          ????Class[]?groups()?default?{};

          ????Class[]?payload()?default?{};
          }
          public?class?MultiCountryAddressValidator?
          ???????implements?ConstraintValidator<ValidAddress,?Address>?
          {

          ????public?void?initialize(ValidAddress?constraintAnnotation)?{

          ????}

          ????@Override
          ????public?boolean?isValid(Address?address,?
          ???????????????????????????ConstraintValidatorContext?constraintValidatorContext)
          ?
          {

          ????????Country?country?=?address.getCountry();
          ????????if?(country?==?null?||?country.getIso2()?==?null?||?address.getZipCode()?==?null)?{
          ????????????return?true;
          ????????}

          ????????switch?(country.getIso2())?{
          ????????????case?"FR":
          ????????????????return?//?Check?if?address.getZipCode()?is?valid?for?France
          ????????????case?"GR":
          ????????????????return?//?Check?if?address.getZipCode()?is?valid?for?Greece
          ????????????default:
          ????????????????return?true;
          ????????}
          ????}
          }

          來(lái)源:blog.csdn.net/jinjiankang/article/details/89711493



          END


          推薦閱讀

          一鍵生成Springboot & Vue項(xiàng)目!【畢設(shè)神器】

          Java可視化編程工具系列(一)

          Java可視化編程工具系列(二)


          順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書籍都可以在這里找到,

          GitHub地址:https://github.com/javadevbooks/books

          Gitee地址:https://gitee.com/javadevbooks/books

          電子書已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..



          瀏覽 60
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲经典自拍 | 欧美天天视频 | 亚洲插逼视频 | 欧美一级黄色片子 | 国产黄色视频在线 |