常用参数校验 @Valid 类,枚举,时间,集合类,字符等

实体字段校验 @NotNull、@NotEmpty、@NotBlank

1.@NotNull

:不能为 null,但可以为 empty,一般用在 Integer 类型的基本数据类型的非空校验上,而且被其标注的字段可以使用
@size、@Max、@Min 对字段数值进行大小的控制

2.@NotEmpty

: 不能为 null,且长度必须大于 0,一般用在集合类上或者数组上

3.@NotBlank

:只能作用在接收的 String 类型上,注意是只能,不能为 null,而且调用 trim() 后,长度必须大于
0即:必须有实际字符

4. GET请求参数校验

4.1 直接在请求方法中对参数实现注解校验

需要在 Controller类上添加 @Validated ,否则会出翔意料外错误;

4.2 使用对象方式进行接收参数,请求对象中添加注解校验

需要再参数前添加 @Valid或者@Validated ,并且对象要实现 implements Serializable 接口
@Valid与@Validated区别:后者是前者的补充,前者能做的后者都能做,并且后者支持分组、级联操作等.所以在请求对象前面加@Valid同样生效.
https://blog.csdn.net/weixin_43401380/article/details/121845901
https://blog.csdn.net/yuanchangliang/article/details/109325867

4.3示例代码:
Controller

package net.cnki.editor.expense.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import net.cnki.editor.common.dto.CurrentUserDTO;
import net.cnki.editor.common.web.BaseController;
import net.cnki.editor.common.web.JsonResult;
import net.cnki.editor.common.web.PageParam;
import net.cnki.editor.common.web.PageResult;
import net.cnki.editor.expense.core.invoice.common.beans.ToInvoiceOrderDetail;
import net.cnki.editor.expense.dao.PayconfigDOMapper;
import net.cnki.editor.expense.pojo.dos.*;
import net.cnki.editor.expense.pojo.dto.IDDTO;
import net.cnki.editor.expense.pojo.dto.PayconfigDTO;
import net.cnki.editor.expense.pojo.dto.UpdatePayconfigDTO;
import net.cnki.editor.expense.pojo.query.ListPayconfigsQuery;
import net.cnki.editor.expense.pojo.vo.PayconfigInfoVO;
import net.cnki.editor.expense.pojo.vo.PayconfigVO;
import net.cnki.editor.expense.service.ExpenseCacheService;
import net.cnki.editor.expense.service.PayconfigDOService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Validated
@RestController
@Api(tags = "PayConfigController", description = "管理接口->客户支付服务配置")
@RequestMapping("/admin/payconfig")
@Slf4j
public class PayConfigController extends BaseController {


    //todo
    @ApiOperation("查看 客户支付服务配置详情")
    @RequestMapping(value = "/payconfig_info_byname", method = RequestMethod.GET)
    public JsonResult<PayconfigInfoVO> getPayconfig(
            @NotBlank @ApiParam("服务商标识") @RequestParam(name = "name", required = true) String name
            , @NotBlank @ApiParam("期刊代码") @RequestParam(name = "journalCode", required = true) String journalCode
            , @Valid ToInvoiceOrderDetail t1
            , @Validated ToInvoiceOrderDetail t2

    ) {
        PayconfigInfoVO vo = new PayconfigInfoVO();


        try {
            Optional<PayconfigDO> clientPayConfig = cacheService.getClientPayConfig(journalCode, journalCode, name);
            if (clientPayConfig.isPresent()) {
                PayconfigDO payconfigDO = clientPayConfig.get();
                BeanUtil.copyProperties(payconfigDO, vo);
                return JsonResult.success(vo);
            }
        } catch (Exception e) {
            log.error("支付服务配置 获取缓存失败 { }", e);
        }

        LambdaQueryWrapper<PayconfigDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayconfigDO::getPayProviderId, name)
                .eq(PayconfigDO::getClientAppKey, journalCode)
                .eq(PayconfigDO::getEnabled, true);
        PayconfigDO payconfigDO = payconfigDOMapper.selectOne(wrapper);
        BeanUtil.copyProperties(payconfigDO, vo);
        return JsonResult.success(vo);
    }



}

实体类

package net.cnki.editor.expense.core.invoice.common.beans;


import lombok.Data;

import javax.validation.constraints.NotBlank;
import java.io.Serializable;

/**
 * Author: xjiaopi
 * Date: 2024/4/29
 * Description: ToInvoiceOrderDetail
 */
@Data//todo
public class ToInvoiceOrderDetail  implements Serializable {
    /* 商品名称 */
    @NotBlank
    String goodsName;

    /* 含税金额,单位为元 */
    Double price;

    /* 数量 */
    Integer num;

    /* 税率 */
    Float taxRate;

    /* 商品编码 */
    String goodsCode;


    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }


    public Float getTaxRate() {
        return taxRate;
    }

    public void setTaxRate(Float taxRate) {
        this.taxRate = taxRate;
    }


    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }


    public String getGoodsCode() {
        return goodsCode;
    }

    public void setGoodsCode(String goodsCode) {
        this.goodsCode = goodsCode;
    }
}

注意

一个 BigDecimal 的字段使用字段校验标签应该为 @NotNull。
在使用 @Length 一般用在 String 类型上可对字段数值进行最大长度限制的控制。
在使用 @Range 一般用在 Integer 类型上可对字段数值进行大小范围的控制。

如下图示:
在这里插入图片描述
测试

1.String name = null;

@NotNull: false
@NotEmpty:false 
@NotBlank:false 



2.String name = "";

@NotNull:true
@NotEmpty: false
@NotBlank: false



3.String name = " ";

@NotNull: true
@NotEmpty: true
@NotBlank: false



4.String name = "Hello World!";

@NotNull: true
@NotEmpty:true
@NotBlank:true


常见类型校验

import java.util.Date; 时间类型

@NotNull 不能为 null,但可以为 empty,必须传

参考:
解决日期转换异常 https://blog.csdn.net/qq_40269087/article/details/112723364
@DateTimeFormat 和 @JsonFormat 注解详解 https://blog.csdn.net/weixin_43888891/article/details/126846791

public enum TaxMaterial 枚举类型

@NotNull 不能为 null,必须传入PAPRE或ELECTRONIC或ALLELECTRONIC_PAPER或ALLELECTRONIC_PDF 字符串

package net.cnki.editor.expense.core.invoice.common.beans;


public enum TaxMaterial {
    PAPRE("纸质发票"),
    ELECTRONIC("电子发票"),
    ALLELECTRONIC_PAPER("全电票纸质"),
    ALLELECTRONIC_PDF("全电票电子");
    String name;
    TaxMaterial(String name) {this.name = name;}}

实体类

@Valid      校验成员变量类内部属性
@NotNull(message = "不能为 null,但可以为 empty  ") 两个注解最好同时使用

类集合

@Valid    校验成员变量类内部属性
@NotNull(message = "不能为 null,但可以为 empty  ")  
@NotEmpty(message = "不能为 null,且长度必须大于 0")

包装类

@NotNull(message = "不能为 null,必须传值 ")  

基本数据类型

当入参为null时,会使用基本数据类型的默认值0;

BigDecimal 类型

@NotNull 一个 BigDecimal 的字段使用字段校验标签应该为 @NotNull。

示例代码

dto

package net.cnki.editor.expense.pojo.dto;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import net.cnki.editor.expense.core.invoice.common.beans.TaxMaterial;
import net.cnki.editor.expense.core.invoice.common.beans.ToInvoiceOrderDetail;


import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;

@Data
public class UpdatePayconfigDTO {

    @NotNull(message = "时间null  ")
    @ApiModelProperty(value = "时间 yyyy-MM-dd HH:mm:ss", required = true)
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    Date orderDate2;

    @NotNull(message = "枚举 ")
    @ApiModelProperty(value = "枚举 ", required = true)
    TaxMaterial taxMaterial;


    @NotNull(message = "类3  ")
    @ApiModelProperty(value = "类3 ", required = true)
    ToInvoiceOrderDetail lei3;

    @Valid
    @NotNull(message = "集合3 ")
    @ApiModelProperty(value = "类集合 ", required = true)
    List<ToInvoiceOrderDetail> orderDetails3;

    @Valid
    @NotEmpty(message = "类4 ")
    @ApiModelProperty(value = "类集合 ", required = true)
    List<ToInvoiceOrderDetail> orderDetails4;


    @NotNull(message = "包装类1 ")
    @ApiModelProperty(value = "包装类1 ", required = true)
    Integer num1;

    @ApiModelProperty(value = "包装类1 ", required = true)
    int num3;

}

枚举类 enum

package net.cnki.editor.expense.core.invoice.common.beans;

/**
 * Author: xjiaopi
 * Date: 2024/5/21
 * Description: TaxMaterial
 */
public enum TaxMaterial {
    PAPRE("纸质发票"),
    ELECTRONIC("电子发票"),
    ALLELECTRONIC_PAPER("全电票纸质"),
    ALLELECTRONIC_PDF("全电票电子")
    ;


    String name;

    TaxMaterial(String name) {
        this.name = name;
    }
}

对象类

package net.cnki.editor.expense.core.invoice.common.beans;


import lombok.Data;

import javax.validation.constraints.NotBlank;
import java.io.Serializable;

/**
 * Author: xjiaopi
 * Date: 2024/4/29
 * Description: ToInvoiceOrderDetail
 */
@Data//todo
public class ToInvoiceOrderDetail  implements Serializable {
    private static final long serialVersionUID = 1L;
    
    /* 商品名称 */
    @NotBlank
    String goodsName;

    /* 含税金额,单位为元 */
    Double price;

    /* 数量 */
    Integer num;

    /* 税率 */
    Float taxRate;

    /* 商品编码 */
    String goodsCode;


}

Controller

package net.cnki.editor.expense.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import net.cnki.editor.common.dto.CurrentUserDTO;
import net.cnki.editor.common.web.BaseController;
import net.cnki.editor.common.web.JsonResult;
import net.cnki.editor.common.web.PageParam;
import net.cnki.editor.common.web.PageResult;
import net.cnki.editor.expense.dao.PayconfigDOMapper;
import net.cnki.editor.expense.pojo.dos.*;
import net.cnki.editor.expense.pojo.dto.IDDTO;
import net.cnki.editor.expense.pojo.dto.PayconfigDTO;
import net.cnki.editor.expense.pojo.dto.UpdatePayconfigDTO;
import net.cnki.editor.expense.pojo.query.ListPayconfigsQuery;
import net.cnki.editor.expense.pojo.vo.PayconfigInfoVO;
import net.cnki.editor.expense.pojo.vo.PayconfigVO;
import net.cnki.editor.expense.service.ExpenseCacheService;
import net.cnki.editor.expense.service.PayconfigDOService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Validated
@RestController
@Api(tags = "PayConfigController", description = "管理接口->客户支付服务配置")
@RequestMapping("/admin/payconfig")
@Slf4j
public class PayConfigController extends BaseController {


    //todo
    @ApiOperation("查看 客户支付服务配置详情")
    @RequestMapping(value = "/payconfig_info_byname", method = RequestMethod.GET)
    public JsonResult<PayconfigInfoVO> getPayconfig(
            @NotBlank @ApiParam("服务商标识") @RequestParam(name = "name", required = true) String name
            , @NotBlank @ApiParam("期刊代码") @RequestParam(name = "journalCode", required = true) String journalCode
            , @Valid ToInvoiceOrderDetail t1
            , @Validated ToInvoiceOrderDetail t2

    ) {
        PayconfigInfoVO vo = new PayconfigInfoVO();


        try {
            Optional<PayconfigDO> clientPayConfig = cacheService.getClientPayConfig(journalCode, journalCode, name);
            if (clientPayConfig.isPresent()) {
                PayconfigDO payconfigDO = clientPayConfig.get();
                BeanUtil.copyProperties(payconfigDO, vo);
                return JsonResult.success(vo);
            }
        } catch (Exception e) {
            log.error("支付服务配置 获取缓存失败 { }", e);
        }

        LambdaQueryWrapper<PayconfigDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayconfigDO::getPayProviderId, name)
                .eq(PayconfigDO::getClientAppKey, journalCode)
                .eq(PayconfigDO::getEnabled, true);
        PayconfigDO payconfigDO = payconfigDOMapper.selectOne(wrapper);
        BeanUtil.copyProperties(payconfigDO, vo);
        return JsonResult.success(vo);
    }

  
  //todo
    @ApiOperation("修改 客户支付服务配置")
    @RequestMapping(value = "/update_payconfig", method = RequestMethod.POST)
    public JsonResult<?> update(@Valid @RequestBody UpdatePayconfigDTO dto) {
        System.out.println("入参: " + dto.toString());
        PayconfigDO tbPayconfigServiceById = tbPayconfigService.getById(dto.getId());
        try {
            if (tbPayconfigServiceById != null) {
                String jc = "";
                if (StrUtil.isNotBlank(tbPayconfigServiceById.getClientKey())) {
                    jc = tbPayconfigServiceById.getClientKey();
                } else {
                    jc = tbPayconfigServiceById.getClientAppKey();
                }
                cacheService.clearClientPayConfigs(jc);
            }
        } catch (Exception e) {
            log.error("支付服务配置 清除缓存失败 { }", e);
        }

        PayconfigDO payconfigDO = new PayconfigDO();
        BeanUtil.copyProperties(dto, payconfigDO);
        tbPayconfigService.updateById(payconfigDO);
        return JsonResult.success();
    }


}

常用的校验注解

javax.validation.constraints.xxx
注解 说明
@Null 被注释的元素必须为null
@NotNull 被注释的元素不能为null
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max,min) 被注释的元素的大小必须在指定的范围内。
@Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式。
@Email 被注释的元素必须是电子邮件地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串必须非空
@Range 被注释的元素必须在合适的范围内

附 @JsonFormat
有时使用 @JsonFormat 注解时,查到的时间可能会比数据库中的时间少八个小时,这是由于时区差引起的,JsonFormat 默认的时区是 Greenwich Time, 默认的是格林威治时间,而我们是在东八区上,所以时间会比实际我们想得到的时间少八个小时。需要在后面加上一个时区,如下示例:
1
@JsonFormat(pattern=“yyyy-MM-dd”,timezone=“GMT+8”)
private Date date;

@JsonFormat(pattern=“yyyy-MM-dd”,timezone=“GMT+8”)
private Date date;

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于构建独立的、生产级别的Java应用程序的框架。它简化了Java开发过程,提供了一种快速开发的方式。而@Valid是Spring Boot中用于数据校验的注解。 在Spring Boot中,我们可以使用@Valid注解来对请求参数进行校验。通过在Controller方法的参数上添加@Valid注解,可以触发校验器对该参数进行验证。校验器会根据参数上的注解进行验证,并将验证结果返回给调用方。 @Valid注解通常与其他校验注解一起使用,例如@NotNull、@Size、@Pattern等。这些注解可以用于对参数的各种约束条件进行定义,例如非空、长度范围、正则表达式等。 使用@Valid注解的步骤如下: 1. 在Controller方法的参数上添加@Valid注解。 2. 在参数对象的字段上添加相应的校验注解。 3. 在Controller类上添加@Validated注解,以启用校验功能。 以下是一个示例代码: ```java @RestController @Validated public class UserController { @PostMapping("/users") public ResponseEntity<String> createUser(@Valid @RequestBody User user) { // 处理创建用户的逻辑 return ResponseEntity.ok("User created successfully"); } } public class User { @NotNull(message = "Name cannot be null") private String name; @Min(value = 18, message = "Age must be at least 18") private int age; // 省略getter和setter方法 } ``` 在上述示例中,我们使用了@Valid注解对User对象进行校验。name字段使用了@NotNull注解,表示该字段不能为空;age字段使用了@Min注解,表示该字段的值必须大于等于18。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值