千家信息网

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

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容主要讲解"Spring boot怎么实现超灵活的注解式数据校验",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring boot怎么实现超灵活的
千家信息网最后更新 2026年11月01日Spring boot怎么实现超灵活的注解式数据校验

本篇内容主要讲解"Spring boot怎么实现超灵活的注解式数据校验",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring boot怎么实现超灵活的注解式数据校验"吧!

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

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

Spring MVC的校验方式

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

public class User {    private Long id;    @NotBlank(message = "name不能为空")    @Size(min = 5, max = 10, message = "字符在5到10个")    private String name;    private String des;    @NotNull    @Max(value = 3, message = "type 参数错误")    @Min(value = 0, message = "type 参数错误")    private Integer type;    @Min(value = 0, message = "参数错误, limit必须大于或等于0")      private int limit;    @Pattern(regexp = "^(true|false)$", message = "参数错误, 参数isActive只能是true或者false")    private String flag;    // setters and getters

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

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

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

参看validator的官方文档

引入依赖:

   org.hibernate   hibernate-validator-cdi   5.4.1.Final   org.glassfish   javax.el   3.0.1-b08

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

定义一个切面:

@Aspect  //一个切面@Configuration  // spring boot 配置类public class RequestParamValidAspect {    private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();    private final ExecutableValidator methodValidator = factory.getValidator().forExecutables();    private final Validator beanValidator = factory.getValidator();    private  Set> validMethodParams(T obj, Method method, Object [] params){        return methodValidator.validateParameters(obj, method, params);    }    private  Set> validBeanParams(T bean) {        return beanValidator.validate(bean);    }    @Pointcut("execution(* com.jiaobuchong.commodity.service.*.*(..))")    public void soaServiceBefore(){}    /* * 通过连接点切入 */    @Before("soaServiceBefore()")    public void twiceAsOld1(JoinPoint point) {        //  获得切入目标对象        Object target = point.getThis();        // 获得切入方法参数        Object [] args = point.getArgs();        // 获得切入的方法        Method method = ((MethodSignature)point.getSignature()).getMethod();        // 校验以基本数据类型 为方法参数的        Set> validResult = validMethodParams(target, method, args);        Iterator> violationIterator = validResult.iterator();        while (violationIterator.hasNext()) {            // 此处可以抛个异常提示用户参数输入格式不正确            System.out.println("method check---------" + violationIterator.next().getMessage());        }        // 校验以java bean对象 为方法参数的         for (Object bean : args) {            if (null != bean) {                validResult = validBeanParams(bean);                violationIterator = validResult.iterator();                while (violationIterator.hasNext()) {            // 此处可以抛个异常提示用户参数输入格式不正确                    System.out.println("bean check-------" + violationIterator.next().getMessage());                }            }        }    }}

具体的Service

// DemoService.javapublic interface DemoService {    void one(@NotNull(message = "不能为null") Integer a, @NotBlank String b);    void two(@NotNull(message = "paramsVo不能为null") ParamsVo paramsVo,             @NotNull(message = "go不能为null") String go);}// ParamsVo.javapublic class ParamsVo {    @NotBlank(message = "不能为空")    private String name;    @NotBlank    @Length(min = 2, max = 20, message = "不可以为空,最多20个字")    private String desc;    @NotNull    @Valid  // 需要加上@Valid注解,不然不会校验到Img对象    private List imgList;    @NotNull(message = "length不能为null")    @Range(min = 3, max = 100, message = "长度范围3-100")    private Integer length;    // omitted other code}public class Img {    @NotNull(message = "img id 不能为null")    private Long id;    @NotBlank(message = "img name 不能为空")    private String name;    // omitted other code}

运行DemoService:

@Autowired     private DemoService demoService;    @Test    public void testGo() {        demoService.one(null, "");        ParamsVo paramsVo = new ParamsVo();        List list = new ArrayList<>();        Img img = new Img();        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的校验功能还强大了,

// Spring MVC中对下面这样的校验是没有作用的void one(@NotNull(message = "不能为null") Integer a, @NotBlank String b);

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

Spring boot aop注解数据权限校验

注解类

@Retention(RetentionPolicy.RUNTIME)public @interface DataAuthValid{        //位置    public int index() default 0;        //字段   id    //public String id() default "id";        //字段   id    public String orgId() default "org_id";        //mapper    @SuppressWarnings("rawtypes")    public Class mapper();}

AOP切面

@Aspect@Component@Order(1)public class DataAuthAop {     private static String types = "java.lang.String,java.lang.Long,long";        @Before("@annotation(dataAuth)")    public void beforeMethod(JoinPoint point,DataAuthValid dataAuth) throws Exception {                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        Map payloadMap = (Map) request.getAttribute("payloadMap");        Long companyid = Long.parseLong(payloadMap.get("companyid")+"");        if(companyid != 1) {            Object[] args = point.getArgs();            Object obj = args[dataAuth.index()];            String ids = null;            String typeName = obj.getClass().getTypeName();            if(types.contains(typeName)) {                ids = obj + "";            }else {                Field[] fields = obj.getClass().getDeclaredFields();                for (Field f : fields) {                    f.setAccessible(true);                    if("id".equals(f.getName())) {                        Long id = (Long) f.get(obj);                        ids = id + "";                    }                }            }            String[] idArr = ids.split(",");            for (String id : idArr) {                Class cla = dataAuth.mapper();                Mapper mapper = (Mapper) SpringBeanFactoryUtils.getApplicationContext().getBean(cla);                Object object = mapper.selectByPrimaryKey(Long.valueOf(id));                Field field = obj.getClass().getDeclaredField(dataAuth.orgId());                field.setAccessible(true);                Long orgId = (Long)field.get(obj);                if(!companyid.equals(orgId)) {                    throw new RuntimeException();                }            }        }    }}

使用

到此,相信大家对"Spring boot怎么实现超灵活的注解式数据校验"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

参数 注解 数据 代码 切面 方法 对象 错误 字段 用户 逻辑 输入 业务 内容 格式 范围 学习 提示 运行 实用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 花魁咖啡 喔噻互联网科技有限公司 深圳市人人互联网科技有限公司 山东特亿宝互联网科技有限公司 中国互联网科技股 北京互联网络科技有限公司 小马过河互联网科技 南京欣网互联网科技 广州善班互联网科技 四个字互联网科技公司取名 北京大学互联网科技怎么样 黑科技闪耀互联网之光 广州市恰铎互联网科技有限公司 山东子淼互联网科技有限公司 郑州欣桑互联网科技有限公司 宁波跨境商互联网科技有限公司 上海同邻互联网科技有限公司规模 玉溪新华互联网科技怎么选 互联网金融金融科技 杭州科技互联网公司有哪些 互联网科技工作委员会毛军 新华互联网科技学院 四个字互联网科技公司取名 互联网科技与大数据专业 美国互联网科技公司 2021世界互联网领先科技成果发布 容联科技互联网电商 唯美互联网科技 利用互联网等科技手段 每日互联网科技新闻
0