• spring数据验证


    一般情况下,我们并不推荐在服务端做基础的数据校验,因为这有一个很主要的问题:它加重了服务器的负载,如果并发多,这种负载就更加明显。

    如果我们跟踪一个简单的Controller方法执行过程,就会发现Spring的一个http请求所需要执行的代码实在太多了。

    因为这种特性,所以spring很适合用于开发一些对实时性要求不太高,单实例并发不太高的系统,或者说它适合用于开发运行于资源比较充裕的环境。

    spring后续应该允许工程师做更灵活的配置--允许不加载一些不需要的,不必要的。 虽然现在已经部分有了,但是还不太够,因为它现在实在有点庞杂了。

    不过既然有这个功能,也不妨用用,例如如果前端不是那么给力的情况下,可以把一些压力负载在后端上。

    又或者把大部分的业务逻辑就放在后端,前端存粹就是展示而已,这样即使更换前端代码,耗费在前端的时间也比较少。

    网络上有许多例子,本文仅仅是为了做个笔记,我本人并不推荐这种做法--在服务端做一些简单的数据校验。

    本文例子参考了 https://blog.csdn.net/weixin_44953227/article/details/121841128

    以下是本人的例子。

    运行环境:springboot-2.6.7,jdk17,windows11.

    验证类-ValidMessage

    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    
    import study.config.anno.ValidIsPositive;
    
    public class ValidMessage implements ConstraintValidator<ValidIsPositive, String> {
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            if(value==null || value.trim().equals("")) {
                return true;
            }
            String message=value.trim();
            if (message.contains("混吃等死") || message.contains("得过且过")) {
                return false;
            }
            return true;
        }
    
    }

    注解-ValidIsPositive

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import javax.validation.Constraint;
    import javax.validation.Payload;
    
    import study.config.validate.ValidMessage;
    /**
     * 验证消息是否积极
     * @author lzfto
     *
     */
    @Target({ ElementType.FIELD })
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = {ValidMessage.class})
    @Documented
    public @interface ValidIsPositive {
        String message() default "";
        Class<?>[] groups() default { };
        Class<? extends Payload>[] payload() default { };
    }

    待验证对象-SaleInfo

    public class SaleInfo {
    
        private Integer id;
        @NotNull(message = "名称不能为空")
        private String name;
        @DecimalMax(message = "不能大于10000", value = "10000")
        private BigDecimal qty;
        private BigDecimal price;
        private BigDecimal totalAmount;
        @ValidIsPositive(message="请拼搏")
        private String comments;
        private Date addTime;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public BigDecimal getQty() {
            return qty;
        }
    
        public void setQty(BigDecimal qty) {
            this.qty = qty;
        }
    
        public BigDecimal getTotalAmount() {
            return totalAmount;
        }
    
        public void setTotalAmount(BigDecimal totalAmount) {
            this.totalAmount = totalAmount;
        }
    
        public Date getAddTime() {
            return addTime;
        }
    
        public void setAddTime(Date addTime) {
            this.addTime = addTime;
        }
    
        public BigDecimal getPrice() {
            return price;
        }
    
        public void setPrice(BigDecimal price) {
            this.price = price;
        }
        
        public String getComments() {
            return comments;
        }
    
        public void setComments(String comments) {
            this.comments = comments;
        }
    
    }

    控制器方法

    @RequestMapping("/spring/tran/")
    @Controller
    public class SpringTranController {
    
        @Autowired
        private SaleMainService saleMainService;
    
        @RequestMapping("/addSaleInfo")
        @ResponseBody
        public Object addSaleInfo(@RequestBody @Valid  SaleInfo saleInfo, Errors errors) {
            if (errors.getAllErrors().size() > 0) {
                return ValidUtils.getValidMapInfo(errors);
            }
            
            try {
                if (saleInfo.getTotalAmount()==null) {
                    saleInfo.setTotalAmount(saleInfo.getQty().multiply(saleInfo.getPrice()));
                }
                return saleMainService.sale(saleInfo);
            } catch (InvalidDataException e) {
                return PublicReturn.getUnSuccessful(e.getMessage());
            }
            catch (Exception e) {
                return PublicReturn.getUnSuccessful(e.getMessage());
            }
        }
    }

    js-测试代码

    var settings = {
      "url": "http://localhost:9999/spring/tran/addSaleInfo",
      "method": "GET",
      "timeout": 0,
      "headers": {
        "Content-Type": "application/json"
      },
      "data": JSON.stringify({
        "name": "大米",
        "qty": 10000.1,
        "price": 1000,
        "comments": "混吃等死"
      }),
    };
    
    $.ajax(settings).done(function (response) {
      console.log(response);
    });

    返回的结果:

    {
        "comments""请拼搏",
        "qty""不能大于10000"
    }
     
  • 相关阅读:
    uiwebview底部黑边解决
    ssh连接速度慢解决
    rutime中动态调用类的方法
    performSelector may cause a leak because its selector is unknown解决
    alpha阶段 代码结构及技术难点简介
    第十二次小组会议记录
    【第三组】心·迹 Alpha版本 成果汇报
    数据库接口使用示例
    第十一次小组会议:进一步对接记录
    2018.6.4 ~ 6.10 周进度管理
  • 原文地址:https://www.cnblogs.com/lzfhope/p/16307324.html
Copyright © 2020-2023  润新知