Spring Boot经验
Spring、 Spring Boot经验
本文记录作者在实际使用Spring或则Spring Boot过程中遇到比较好的案例或则经验,以供开发学习使用
1. 校验篇
生产过程中前后端都会进行数据格式的校验,后端校验一般采用JSR303的校验模式
1.1 使用
引入依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
1.2 简单校验
在相关实体类上增加校验注解
/**
* 品牌id
*/
@NotNull(message = "修改必须指定品牌id", groups = {UpdateGroup.class})
@Null(message = "新增不能指定id", groups = {AddGroup.class})
@TableId
private Long brandId;
然后在实际需要校验的地方增加@Valid注解或则@Validated注解
public R update(@Validated(value = {UpdateGroup.class}) @RequestBody BrandEntity brand);
1.3 分组校验
import org.springframework.validation.annotation.Validated; //来源于Spring Boot
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
/**
* Specify one or more validation groups to apply to the validation step
* kicked off by this annotation.
* <p>JSR-303 defines validation groups as custom annotations which an application declares
* for the sole purpose of using them as type-safe group arguments, as implemented in
* {@link org.springframework.validation.beanvalidation.SpringValidatorAdapter}.
* <p>Other {@link org.springframework.validation.SmartValidator} implementations may
* support class arguments in other ways as well.
*/
Class<?>[] value() default {};
}
在@Valid注解源码中可以看到value是个class的数组,可以进行分组作用
上文中有相关例子,在校验时如果使用分组校验,其他不匹配的分组校验或则不分组的校验将不生效。
自定义组
public interface UpdateGroup {
}
1.4 自定义异常
默认异常可以通过源码查看,也可以指定message
默认的返回值不一定符合系统设计时的结构,可以自定义全局异常来进行设置。
1.5 自定义校验规则
先查看@NotEmpty注解
@Documented
@Constraint(validatedBy = { }) //指定校验器
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface NotEmpty {
//默认提示
String message() default "{javax.validation.constraints.NotEmpty.message}";
//分组
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
例子
-
自定义校验注解
package com.cx.common.valid; import com.cx.common.valid.validator.ListValueValidator; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * @ClassName : ListValue * @Description : * @Author : cx * @Date: 2023-04-28 17:47 */ @Documented @Constraint(validatedBy = { ListValueValidator.class }) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) public @interface ListValue { String message() default "{com.cx.common.valid.ListValue.message}"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; int[] value(); }
com.cx.common.valid.ListValue.message 是定义在resources下的ValidationMessages.properties文件中,如果有中文用unicode表示。
-
是用自定义校验注解
/** * 显示状态[0-不显示;1-显示] */ @ListValue(value = {0, 1}, groups = {AddGroup.class}) private Integer showStatus;
-
增加校验解析器
package com.cx.common.valid.validator; import com.cx.common.valid.ListValue; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.HashSet; import java.util.Set; /** * @ClassName : ListValueValidator * @Description : * @Author : cx * @Date: 2023-04-28 17:57 */ public class ListValueValidator implements ConstraintValidator<ListValue, Integer> { private Set<Integer> set = new HashSet<>(); @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { if(set.contains(value)) return true; return false; } @Override public void initialize(ListValue constraintAnnotation) { int[] values = constraintAnnotation.value(); for (int value : values) { set.add(value); } } }
注意: 里面的ListValue指的就是自定义的校验注解, Integer是指这个校验注解针对哪一种类型进行校验,例如
如果是Double类型的就是写成Double,对于多种类型,需要写多个校验器,在自定义校验注解的时候可以指定多个类型的校验器,可以参看已有的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY