spring boot 12
一、自定义校验(@State注解)
1. 自定义注解@State
用于校验文章状态是否为已发布或草稿:
java
运行
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = StateValidation.class) public @interface State { // 校验失败的提示信息 String message() default "文章状态只能是:已发布或者草稿"; // 分组校验支持 Class[] groups() default {}; // 负载信息 Class<? extends Payload>[] payload() default {}; }2. 校验逻辑实现类StateValidation
实现ConstraintValidator接口,编写具体校验规则:
java
运行
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class StateValidation implements ConstraintValidator<State, String> { @Override public boolean isValid(String value, ConstraintValidatorContext context) { // 状态不能为空 if (value == null) { return false; } // 校验是否为允许的状态值 return value.equals("已发布") || value.equals("草稿"); } }3. 在实体类中使用@State注解
java
运行
@Data public class Article { private Integer id; // 主键ID @NotEmpty(message = "文章标题不能为空") private String title; // 文章标题 @NotEmpty(message = "文章内容不能为空") private String content; // 文章内容 private String coverImg; // 封面图像 @State(message = "文章状态只能是:已发布或者草稿") private String state; // 发布状态:已发布/草稿 @NotNull(message = "文章分类ID不能为空") private Integer categoryId; // 文章分类ID private Integer createUser; // 创建人ID private LocalDateTime createTime; // 创建时间 private LocalDateTime updateTime; // 更新时间 }二、新增文章接口实现
1. Controller 层
java
运行
@RestController @RequestMapping("/article") public class ArticleController { @Autowired private ArticleService articleService; @PostMapping public Result add(@RequestBody @Validated Article article) { articleService.add(article); return Result.success(); } }2. Service 层
java
运行
@Service public class ArticleServiceImpl implements ArticleService { @Autowired private ArticleMapper articleMapper; @Override public void add(Article article) { // 从 ThreadLocal 获取当前登录用户ID Map<String, Object> claims = ThreadLocalUtil.get(); Integer userId = (Integer) claims.get("id"); // 自动填充字段 article.setCreateUser(userId); LocalDateTime now = LocalDateTime.now(); article.setCreateTime(now); article.setUpdateTime(now); articleMapper.add(article); } }3. Mapper 层(SQL)
java
运行
@Mapper public interface ArticleMapper { @Insert("insert into article(title, content, cover_img, state, category_id, create_user, create_time, update_time) " + "values(#{title}, #{content}, #{coverImg}, #{state}, #{categoryId}, #{createUser}, #{createTime}, #{updateTime})") void add(Article article); }三、关键注意事项
自定义校验生效条件
- 自定义注解上添加
@Constraint(validatedBy = StateValidation.class),关联校验实现类 - 实体类字段上添加
@State注解 - Controller 接口参数前添加
@Validated注解,开启校验
- 自定义注解上添加
新增文章接口字段校验
title:非空校验(@NotEmpty)content:非空校验(@NotEmpty)categoryId:非空校验(@NotNull)state:自定义校验(@State),必须为已发布或草稿
用户 ID 安全获取
- 不要由前端传入
createUser,统一从ThreadLocal中获取,避免越权发布文章
- 不要由前端传入
时间字段自动填充
- 新增时
createTime和updateTime都设置为当前时间,保证数据一致性
- 新增时
