Spring boot怎么实现超灵活的注解式数据校验(springboot,开发技术)

时间:2024-05-08 09:57:17 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

通过切面,实现超灵活的注解式数据校验

在企业系统的开发中,用户表单输入的场景是会经常遇见的,如何让数据校验脱离于业务代码逻辑,谁也不想在逻辑代码里对字段逐一判断。。。。

Spring MVC的校验方式

在使用Spring MVC时的时候,直接使用hibernate-validator的注解,如下:

publicclassUser{privateLongid;@NotBlank(message="name不能为空")@Size(min=5,max=10,message="字符在5到10个")privateStringname;privateStringdes;@NotNull@Max(value=3,message="type参数错误")@Min(value=0,message="type参数错误")privateIntegertype;@Min(value=0,message="参数错误,limit必须大于或等于0")privateintlimit;@Pattern(regexp="^(true|false)$",message="参数错误,参数isActive只能是true或者false")privateStringflag;//settersandgetters

然后将User对象作为Controller的参数,交给Spring MVC去帮你校验。

通过切面实现自己的注解式数据校验

这是一个SOA的微服务应用,没有controller和Spring MVC,当然也没有所谓的容器(Tomcat、Jetty),对于来自于client的调用,也要进行参数校验。继续基于hibernate-validator,

参看validator的官方文档

引入依赖:

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator-cdi</artifactId><version>5.4.1.Final</version></dependency><dependency><groupId>org.glassfish</groupId><artifactId>javax.el</artifactId><version>3.0.1-b08</version></dependency>

这里需要引入spring boot和aop的一些知识点,自行去网上google吧。我直接上代码了,谁叫我是代码的搬运工。

定义一个切面:

@Aspect//一个切面@Configuration//springboot配置类publicclassRequestParamValidAspect{privatefinalValidatorFactoryfactory=Validation.buildDefaultValidatorFactory();privatefinalExecutableValidatormethodValidator=factory.getValidator().forExecutables();privatefinalValidatorbeanValidator=factory.getValidator();private<T>Set<ConstraintViolation<T>>validMethodParams(Tobj,Methodmethod,Object[]params){returnmethodValidator.validateParameters(obj,method,params);}private<T>Set<ConstraintViolation<T>>validBeanParams(Tbean){returnbeanValidator.validate(bean);}@Pointcut("execution(*com.jiaobuchong.commodity.service.*.*(..))")publicvoidsoaServiceBefore(){}/**通过连接点切入*/@Before("soaServiceBefore()")publicvoidtwiceAsOld1(JoinPointpoint){//获得切入目标对象Objecttarget=point.getThis();//获得切入方法参数Object[]args=point.getArgs();//获得切入的方法Methodmethod=((MethodSignature)point.getSignature()).getMethod();//校验以基本数据类型为方法参数的Set<ConstraintViolation<Object>>validResult=validMethodParams(target,method,args);Iterator<ConstraintViolation<Object>>violationIterator=validResult.iterator();while(violationIterator.hasNext()){//此处可以抛个异常提示用户参数输入格式不正确System.out.println("methodcheck---------"+violationIterator.next().getMessage());}//校验以javabean对象为方法参数的for(Objectbean:args){if(null!=bean){validResult=validBeanParams(bean);violationIterator=validResult.iterator();while(violationIterator.hasNext()){//此处可以抛个异常提示用户参数输入格式不正确System.out.println("beancheck-------"+violationIterator.next().getMessage());}}}}}

具体的Service

//DemoService.javapublicinterfaceDemoService{voidone(@NotNull(message="不能为null")Integera,@NotBlankStringb);voidtwo(@NotNull(message="paramsVo不能为null")ParamsVoparamsVo,@NotNull(message="go不能为null")Stringgo);}//ParamsVo.javapublicclassParamsVo{@NotBlank(message="不能为空")privateStringname;@NotBlank@Length(min=2,max=20,message="不可以为空,最多20个字")privateStringdesc;@NotNull@Valid//需要加上@Valid注解,不然不会校验到Img对象privateList<Img>imgList;@NotNull(message="length不能为null")@Range(min=3,max=100,message="长度范围3-100")privateIntegerlength;//omittedothercode}publicclassImg{@NotNull(message="imgid不能为null")privateLongid;@NotBlank(message="imgname不能为空")privateStringname;//omittedothercode}

运行DemoService:

@AutowiredprivateDemoServicedemoService;@TestpublicvoidtestGo(){demoService.one(null,"");ParamsVoparamsVo=newParamsVo();List<Img>list=newArrayList<>();Imgimg=newImg();list.add(img);paramsVo.setImgList(list);paramsVo.setDesc("你");paramsVo.setLength(1);demoService.two(paramsVo,null);}

运行结果:

method check———不能为空
method check———不能为null
method check———go不能为null
bean check——-img name 不能为空
bean check——-不能为空
bean check——-深度范围3-100
bean check——-img id 不能为null
bean check——-不可以为空,最多20个字

这样比Spring MVC的校验功能还强大了,

//SpringMVC中对下面这样的校验是没有作用的voidone(@NotNull(message="不能为null")Integera,@NotBlankStringb);

经过一番改造后,啥都支持了。而且独立于业务逻辑,维护和新增校验都很方便,代码量也变少了!

Spring boot aop注解数据权限校验

注解类

@Retention(RetentionPolicy.RUNTIME)public@interfaceDataAuthValid{//位置publicintindex()default0;//字段id//publicStringid()default"id";//字段idpublicStringorgId()default"org_id";//mapper@SuppressWarnings("rawtypes")publicClass<?extendsMapper>mapper();}

AOP切面

@Aspect@Component@Order(1)publicclassDataAuthAop{privatestaticStringtypes="java.lang.String,java.lang.Long,long";@Before("@annotation(dataAuth)")publicvoidbeforeMethod(JoinPointpoint,DataAuthValiddataAuth)throwsException{HttpServletRequestrequest=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();Map<String,Object>payloadMap=(Map<String,Object>)request.getAttribute("payloadMap");Longcompanyid=Long.parseLong(payloadMap.get("companyid")+"");if(companyid!=1){Object[]args=point.getArgs();Objectobj=args[dataAuth.index()];Stringids=null;StringtypeName=obj.getClass().getTypeName();if(types.contains(typeName)){ids=obj+"";}else{Field[]fields=obj.getClass().getDeclaredFields();for(Fieldf:fields){f.setAccessible(true);if("id".equals(f.getName())){Longid=(Long)f.get(obj);ids=id+"";}}}String[]idArr=ids.split(",");for(Stringid:idArr){Classcla=dataAuth.mapper();Mappermapper=(Mapper)SpringBeanFactoryUtils.getApplicationContext().getBean(cla);Objectobject=mapper.selectByPrimaryKey(Long.valueOf(id));Fieldfield=obj.getClass().getDeclaredField(dataAuth.orgId());field.setAccessible(true);LongorgId=(Long)field.get(obj);if(!companyid.equals(orgId)){thrownewRuntimeException();}}}}}

使用

Spring boot怎么实现超灵活的注解式数据校验

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Spring boot怎么实现超灵活的注解式数据校验的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:linux系统下如何实现用户管理下一篇:

4 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18