学习进度条

今日所花时间:一个半小时
今日代码量:150行
博客量:一篇
继续完成项目跟练
了解到的知识点:自定义校验

自定义校验

已有的注解不能满足所有的校验需求,特殊的情况需要自定义校验(自定义校验注解)
1.自定义注解State(message、groups、payload)
2.自定义校验数据的类StateValidation
实现ConstraintValidator接口
3.在需要校验的地方使用自定义注解
测试代码:
Article实体类

package com.example.day0225.pojo;



import com.example.day0225.anno.State;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;

import java.time.LocalDateTime;

public class Article {
    private Integer id;//主键ID
    @NotEmpty
    @Pattern(regexp = "^\\S{1,10}$")
    private String title;//文章标题
    @NotEmpty
    private String content;//文章内容
    @NotEmpty
    @URL
    private String coverImg;//封面图像
    @State
    private String state;//发布状态 已发布|草稿
    @NotNull
    private Integer categoryId;//文章分类id
    private Integer createUser;//创建人ID
    private LocalDateTime createTime;//创建时间
    private LocalDateTime updateTime;//更新时间

    public Article() {
    }

    public Article(Integer id, String title, String content, String coverImg, String state, Integer categoryId, Integer createUser, LocalDateTime createTime, LocalDateTime updateTime) {
        this.id = id;
        this.title = title;
        this.content = content;
        this.coverImg = coverImg;
        this.state = state;
        this.categoryId = categoryId;
        this.createUser = createUser;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getCoverImg() {
        return coverImg;
    }

    public void setCoverImg(String coverImg) {
        this.coverImg = coverImg;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public Integer getCreateUser() {
        return createUser;
    }

    public void setCreateUser(Integer createUser) {
        this.createUser = createUser;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }
}

ArticleController

package com.example.day0225.controller;

import com.example.day0225.pojo.Article;
import com.example.day0225.pojo.Result;
import com.example.day0225.service.ArticleService;
import com.example.day0225.utils.JwtUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.coyote.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpServerErrorException;

import java.util.Map;

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @PostMapping
    public Result<String> add(@RequestBody @Validated Article article) {
        articleService.add(article);
        return Result.success();
    }
}

ArticleService

package com.example.day0225.service;

import com.example.day0225.pojo.Article;

public interface ArticleService {
    //新增文章
    void add(Article article);
}

ArticleServiceImpl

package com.example.day0225.service.impl;

import com.example.day0225.mapper.ArticleMapper;
import com.example.day0225.pojo.Article;
import com.example.day0225.service.ArticleService;
import com.example.day0225.utils.ThreadLocalUtil;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    @Override
    public void add(Article article) {
        //补充属性值
        article.setCreateTime(LocalDateTime.now());
        article.setUpdateTime(LocalDateTime.now());
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        article.setCreateUser(userId);
        articleMapper.add(article);
    }
}

ArticleMapper

package com.example.day0225.mapper;

import com.example.day0225.pojo.Article;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;

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

在当前项目的软件包下创建一个新的软件包anno创建一个注解State
注解内容如下:

package com.example.day0225.anno;

import com.example.day0225.validation.StateValidation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import jakarta.validation.constraints.NotEmpty;

import java.lang.annotation.*;

@Documented//元注解(用来标识)
//元注解(标识这个State能用在什么地方)(在这个项目中State要用到属性上,所以只保留ElementType.FIELD即可)
//@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)//元注解(State什么时候被保留,要求保留到运行时)
@Constraint(
        validatedBy = {StateValidation.class}
)//用来指定将来谁给注解来提供校验规则


//@Repeatable(NotEmpty.List.class)不需要
public @interface State {
    //用来提供校验失败后的提示信息
    String message() default "state参数的值只能是已发布或者草稿";
    //指定分组
    Class<?>[] groups() default {};
    //负载的意思 获取到State注解的附加信息
    Class<? extends Payload>[] payload() default {};
}

在当前项目的软件包下继续创建一个软件包validation,接着创建StateValidation类(完善项目对state属性的要求)

package com.example.day0225.validation;

import com.example.day0225.anno.State;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

//<>中写给哪个注解提供校验规则,将来校验的数据类型
public class StateValidation implements ConstraintValidator<State,String> {
    /**
     *
     * @param s 将来要校验的数据
     * @param constraintValidatorContext
     * @return 如果返回false则校验不通过,如果返回true通过
     */
    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        //提供校验规则
        if (s == null){
            return false;
        }
        if(s.equals("已发布") || s.equals("草稿")){
            return true;
        }
        return false;
    }
}

posted @ 2025-03-06 19:21  haoyinuo  阅读(16)  评论(0)    收藏  举报