java - 通过自定义约束验证实体作为参数

标签 java spring validation annotations

使用 Spring Boot,我创建了一个示例应用程序。

package hello;

import org.springframework.web.bind.annotation.RestController;

import constraint.CheckHelloId;
import dto.HelloDto;

import javax.validation.Valid;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RestController
public class HelloController {

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public String index(@RequestBody @Valid final HelloDto hello) {
        hello.setId(null);
        validateFromMethodHeader(hello);
        return "Greetings from Spring Boot!";
    }

    private void validateFromMethodHeader(@CheckHelloId final HelloDto helloDto) {
        System.out.println("Validating DTO...");
    }

}

我正在尝试在私有(private)方法中向 DTO HelloDto 添加自定义约束,以检查 id 字段是否为空。

界面:

package constraint;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ FIELD, ANNOTATION_TYPE, TYPE, METHOD, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = CheckHelloIdValidator.class)
@Documented
public @interface CheckHelloId {

    String message() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

validator :

package constraint;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;

import org.apache.commons.lang3.StringUtils;

import dto.HelloDto;

@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class CheckHelloIdValidator implements ConstraintValidator<CheckHelloId, HelloDto> {

    private static final String ID_VALIDATION_ERROR = "Null or blank ID.";

    @Override
    public void initialize(CheckHelloId arg0) {
    }

    @Override
    public boolean isValid(HelloDto helloDto, ConstraintValidatorContext context) {
        if (StringUtils.isBlank(helloDto.getId())){
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(ID_VALIDATION_ERROR).addConstraintViolation();
            return false;
        }
        return true;
    }

}

DTO:

package dto;

import java.io.Serializable;

public class HelloDto implements Serializable {

    private static final long serialVersionUID = 8792903048191496378L;

    private String id;

    private String message;

    public String getId() {
        return id;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}
正如在 Controller 的私有(private)方法中看到的,我正在尝试在参数级别应用 DTO 的验证(我知道我可以通过实体验证在索引处执行此操作,但我想测试这个具体的情况下,这就是我在 Controller 中将 id 字段设置为 null 的原因。

当我运行应用程序并执行调用时,即使 id 字段为空,约束也不适用于私有(private)方法。有人能解释一下吗?预先感谢您。

最佳答案

要在带注释的方法参数旁边验证其余 Controller 上的消费 json @RequestBody @Valid final HelloDto hello,您必须使用特殊约束来注释 json 数据类的字段。对于您的情况,使用 hibernate 验证约束就足够了 @NotNull@NotEmpty :

package dto;

import java.io.Serializable;

public class HelloDto implements Serializable {

    private static final long serialVersionUID = 8792903048191496378L;

    @NotEmpty
    private String id;

关于java - 通过自定义约束验证实体作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42624903/

相关文章:

java - 如何在安装了java 8的机器中设置java 6项目的构建路径?

java - Spring 和 Jackson 集成

validation - Vue js vee 使用自定义组件验证密码确认

java - 为什么 localhost 可以工作,但外部 URL 在 tomcat 中却不起作用?

Java程序卡在TTransport Transport = new THttpClient ("this.host.com"上)

java - 使用倒计时闩锁或 Spring 集成并行调用 Web 服务哪个更好?

Django 表单验证取决于表单集中的数据

java - Spring @Autowired vs 使用 'new' 关键字创建对象

java - Hudson 和 maven-release-plugin

java - 如何以编程方式配置 Bean 验证?