最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
怎么在Java中使用@Validated注解進(jìn)行參數(shù)驗(yàn)證

本篇文章給大家分享的是有關(guān)怎么在Java中使用@Validated注解進(jìn)行參數(shù)驗(yàn)證,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)是專業(yè)的新洲網(wǎng)站建設(shè)公司,新洲接單;提供成都網(wǎng)站建設(shè)、做網(wǎng)站,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行新洲網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

// 要驗(yàn)證的實(shí)體類
@Data
public class User implements Serializable {
  @NotBlank(message = "id不能為空!",groups = Update.class)
  protected String id = "";
  @NotBlank(message = "商戶id不能為空!")
  protected String tenantId;
  @NotBlank(message = "名稱不能為空!")
  protected String name = "";
}
// controller
// 在要驗(yàn)證的參數(shù)上添加@Validated注解即可
@PostMapping("add")
public boolean addUser(@Validated @RequestBody User user) {
    ProdAllotStandard info = allotStandardService.getProdAllotStandardWithDetailById(id);
    return info;
}
// 修改則需要比添加的基礎(chǔ)上多驗(yàn)證一個(gè)id,可以通過group的方式進(jìn)行區(qū)分
// 實(shí)體類上不設(shè)置groups,默認(rèn)會(huì)是Default,所以修改的時(shí)候,我們需要指定Update和Default這兩個(gè)組
// group是可以自定義的,我默認(rèn)定義了Add,Update,Delete,Search這四個(gè)組
@PostMapping("update")
public boolean updateUser(@Validated({Update.class, Default.class}) @RequestBody User user) {
    ProdAllotStandard info = allotStandardService.getProdAllotStandardWithDetailById(id);
    return info;
}
// 當(dāng)然該注解也支持service上實(shí)現(xiàn),同樣的使用方法,在service的實(shí)現(xiàn)類的參數(shù)上加上對應(yīng)注解即可,如:
public boolean addUser(@Validated User user) {
     
}
// 通過不同group的搭配,我們就可以靈活的在實(shí)體類上配置不同場景的驗(yàn)證了
// group為一個(gè)接口,用以下方式創(chuàng)建
public interface Add {
}

下面看一下具體的實(shí)現(xiàn),驗(yàn)證框架的核心實(shí)現(xiàn)采用的是hibernate-validator,我采用的是5.4.3.Final版本。

controller和service的實(shí)現(xiàn)方式不同,下面分別介紹下。

不管哪種實(shí)現(xiàn),我們都需要先定義一個(gè)異常和一個(gè)異常攔截器,當(dāng)參數(shù)校驗(yàn)出現(xiàn)問題時(shí),我們就拋出對應(yīng)異常。

// 為了簡短,省略了部分代碼
public class ParamsException extends RuntimeException{
  private String code;
  public BusinessException() {
  }
  public ParamsException(String code,String message) {
    super(message);
    this.code = code;
  }
  public ParamsException(String message) {
    super(message);
  }
}
// 定義異常處理類
@ControllerAdvice
public class ExceptionAdvice {
 
  private static Logger L = LoggerFactory.getLogger(ExceptionAdvice.class);
 
  // 對所有的ParamsException統(tǒng)一進(jìn)行攔截處理,如果捕獲到該異常,則封裝成MessageBody返回給前端
  @ExceptionHandler(value = ParamsException.class)
  @ResponseStatus(HttpStatus.OK)
  @ResponseBody
  public MessageBody handleParamsException(HttpServletRequest request, BusinessException e){
    L.error(e.getMessage(),e);
    return getErrorMessageBody(e.getData(),e.getMessage(),e.getMessage(),
        StringUtils.isEmpty(e.getCode())?ResponseCode.BUSINESS_ERROR:e.getCode());
  }
  private MessageBody getErrorMessageBody(Object data,String message,String errorInfo,String code){
    MessageBody body = new MessageBody();
    body.setCode(code);
    body.setData(data);
    body.setErrorCode(Integer.parseInt(code));
    body.setErrorInfo(errorInfo);
    body.setMessage(message);
    body.setSuccess(false);
    return body;
  }
}

controller的驗(yàn)證的實(shí)現(xiàn):

主要是通過實(shí)現(xiàn)spring mvc給我們留下的接口進(jìn)行實(shí)現(xiàn)的,該方案沒有用到反射和代理。

1.  實(shí)現(xiàn)spring提供的SmartValidator接口

public class ParamsValidator implements SmartValidator {
 
  private javax.validation.Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
 
  @Override
  public boolean supports(Class clazz) {
    return true;
  }
  // 注解上沒有有g(shù)roup的驗(yàn)證邏輯
  @Override
  public void validate(Object target, Errors errors) {
    validate(target,errors,null);
  }
  // 注解上帶有g(shù)roup的驗(yàn)證邏輯
  // 第一個(gè)參數(shù)為我們要驗(yàn)證的參數(shù),第二個(gè)不用管,第三個(gè)為注解上設(shè)置個(gè)groups
  @Override
  public void validate(Object target, Errors errors, Object... validationHints) {
    // 這里面為驗(yàn)證實(shí)現(xiàn),可以根據(jù)自己的需要進(jìn)行完善與修改
    if (target == null) {
      throw new ParamsException("參數(shù)不能為空!");
    } else {
      if(target instanceof String) {
        if(StringUtils.isEmpty(target)) {
          throw new ParamsException("參數(shù)不能為空!");
        }
      }else if(target instanceof Collection) {
        for(Object o:(Collection)target){
          validate(o,validationHints);
        }
      }else {
        validate(target,validationHints);
      }
 
    }
 
  }
  private void validate(Object target,Object ... objs) {
    Set> violations;
    // 沒有g(shù)roups的驗(yàn)證
    if(objs==null || objs.length==0) {
      violations = validator.validate(target);
    } else {
    // 基于groups的驗(yàn)證
      Set> groups = new LinkedHashSet>();
      for (Object hint : objs) {
        if (hint instanceof Class) {
          groups.add((Class) hint);
        }
      }
      violations = validator.validate(target, ClassUtils.toClassArray(groups));
    }
    // 若為空,則驗(yàn)證通過
    if(violations==null||violations.isEmpty()) {
      return;
    }
    // 驗(yàn)證不通過則拋出ParamsException異常。
    for(ConstraintViolation item:violations) {
      throw new ParamsException(item.getMessage());
    }
  }
}

2. 配置并設(shè)置Validator驗(yàn)證器

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter{
  // 我們在這里重寫spring的一個(gè)方法,返回我們自定義的驗(yàn)證器
  @Override
  public Validator getValidator() {
    return createValidator();
  }
  @Bean
  public ParamsValidator createValidator(){
    return new ParamsValidator();
  }
}

非常簡單,通過上面配置,就可以在controller上使用注解了。

spring mvc對這個(gè)注解的處理主要是在RequestResponseBodyMethodProcessor這個(gè)類中的resolveArgument方法實(shí)現(xiàn)的,該類主要處理方法的參數(shù)和返回值。

spring mvc調(diào)用的一段代碼。

protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
  Annotation[] annotations = parameter.getParameterAnnotations();
  for (Annotation ann : annotations) {
    Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
    if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
      Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
      Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
      binder.validate(validationHints);
      break;
    }
  }
}

service的驗(yàn)證的實(shí)現(xiàn):

該方案主要通過aop進(jìn)行攔截處理的。如下配置:

@Component
@Aspect
public class ParamsValidateAdvice {
  // 這里重用上面定義的那個(gè)validator
  private ParamsValidator validator = new ParamsValidator();
  /**
   * 攔截參數(shù)上加了@Validated的注解的方法
   * 排除掉controller,因?yàn)閏ontroller有自己的參數(shù)校驗(yàn)實(shí)現(xiàn) 不需要aop
   */
  @Pointcut("execution(* com.choice..*(..,@org.springframework.validation.annotation.Validated (*), ..)) && " +
      "!execution(* com.choice..api..*(..)) && " +
      "!execution(* com.choice..controller..*(..)) ")
  public void pointCut(){}
 
  @Before("pointCut()")
  public void doBefore(JoinPoint joinPoint){
    Object[] params=joinPoint.getArgs();
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    Parameter[] parameters = method.getParameters();
    // 驗(yàn)證參數(shù)上的注解
    for(int i=0;i0) {
        validator.validate(params[i],null,validated.value());
      } else {
        validator.validate(params[i],null);
      }
    }
  }
}

Java的特點(diǎn)有哪些

Java的特點(diǎn)有哪些 1.Java語言作為靜態(tài)面向?qū)ο缶幊陶Z言的代表,實(shí)現(xiàn)了面向?qū)ο罄碚?,允許程序員以優(yōu)雅的思維方式進(jìn)行復(fù)雜的編程。 2.Java具有簡單性、面向?qū)ο蟆⒎植际?、安全性、平臺(tái)獨(dú)立與可移植性、動(dòng)態(tài)性等特點(diǎn)。 3.使用Java可以編寫桌面應(yīng)用程序、Web應(yīng)用程序、分布式系統(tǒng)和嵌入式系統(tǒng)應(yīng)用程序等。

以上就是怎么在Java中使用@Validated注解進(jìn)行參數(shù)驗(yàn)證,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


本文標(biāo)題:怎么在Java中使用@Validated注解進(jìn)行參數(shù)驗(yàn)證
網(wǎng)站鏈接:http://fisionsoft.com.cn/article/jigcgs.html