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);
}

三、关键注意事项

  1. 自定义校验生效条件

    • 自定义注解上添加 @Constraint(validatedBy = StateValidation.class),关联校验实现类
    • 实体类字段上添加 @State 注解
    • Controller 接口参数前添加 @Validated 注解,开启校验
  2. 新增文章接口字段校验

    • title:非空校验(@NotEmpty
    • content:非空校验(@NotEmpty
    • categoryId:非空校验(@NotNull
    • state:自定义校验(@State),必须为 已发布草稿
  3. 用户 ID 安全获取

    • 不要由前端传入 createUser,统一从 ThreadLocal 中获取,避免越权发布文章
  4. 时间字段自动填充

    • 新增时 createTimeupdateTime 都设置为当前时间,保证数据一致性
相关推荐
用户37215742613514 分钟前
Java 将 Word 文档转换为 Markdown:基础转换与导出选项详解
java
行者全栈架构师27 分钟前
PolarDB + Spring Boot 实战:从自建MySQL到云原生数据库的零停机迁移
java·后端·架构
用户83562907805116 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
用户83562907805116 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
karry_k16 小时前
MyBatis批量insert-select踩坑:useGeneratedKeys=true 可能让PostgreSQL返回大量插入结果
java·后端
karry_k16 小时前
PostgreSQL 在 MyBatis 中执行正常 SQL 失效:一次 DELETE USING 踩坑记录
java·后端
SamDeepThinking20 小时前
从源码到代码:MyBatis-Flex 与 MyBatis-Plus 的逐项对比
java·后端·程序员
她的男孩1 天前
Spring Boot 接 Flowable 工作流:用 3 个注解搭一个请假审批流程
java·后端·架构
你好潘先生1 天前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
Agent_大师1 天前
WebSocket 行情重连成功,K线缺口不会自动消失
python