spring boot 自定义验证器运行两次

Posted

技术标签:

【中文标题】spring boot 自定义验证器运行两次【英文标题】:spring boot custom validator runs twice 【发布时间】:2019-11-19 07:39:43 【问题描述】:

我有一个带有我创建的自定义验证器的 Spring Boot 应用程序,与此处描述的非常相似:

How to disable Hibernate validation in a Spring Boot project

我已经尝试了建议的解决方案,这意味着我将以下行添加到 application.properties 文件:

spring.jpa.properties.javax.persistence.validation.mode=none

这是代码(部分):

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;


@Target(FIELD)
@Retention(RUNTIME)
@Constraint(validatedBy = ReCaptchaResponseValidator.class)
public @interface ReCaptchaResponse 
   String message() default "RECAPTCHA_RESPONSE_INVALID";

   Class<?>[] groups() default ;

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

那么我有:

import org.json.JSONObject;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;


public class ReCaptchaResponseValidator implements 
ConstraintValidator<ReCaptchaResponse, String> 
private boolean status = true;

@Override
public boolean isValid(String value, ConstraintValidatorContext context) 
    final String secretKey = "xxxxxxxxxx";

    System.out.println("Calling isValid with value: " + value);


    try 
        String url = "https://www.google.com/recaptcha/api/siteverify?"
                + "secret=" + secretKey
                + "&response=" + value;

        InputStream res = new URL(url).openStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(res, Charset.forName("UTF-8")));

        StringBuilder sb = new StringBuilder();

        int cp;

        while ((cp = rd.read()) != -1) 
            sb.append((char) cp);
        

        String jsonText = sb.toString();

        res.close();

        JSONObject json = new JSONObject(jsonText);

        return json.getBoolean("success");
     catch (Exception e) 
    

    return false;

那么我有:

public class MyModel 
   @ReCaptchaResponse
   private Srting recaptcha;

然后我停止并重新编译了项目,但验证器仍然运行了两次。我不知道为什么会发生这种情况,我使用的是最新的 Spring Boot 版本,而建议的解决方案是 2014 年......也许从那以后发生了一些变化?有什么想法吗?

谢谢。

【问题讨论】:

如果您可以分享一个重现该问题的最小项目,那将有所帮助 我也不确定该解决方案(面对我自己),因此对于解决方法,您可以有一个单独的 Dto 来接收请求,然后将其映射到 Entity 【参考方案1】:

我不知道为什么,但是在将我的控制器中的 @Valid @RequestBody 替换为 @Validated @RequestBody 之后,它似乎可以解决问题,现在验证器只运行一次。

【讨论】:

以上是关于spring boot 自定义验证器运行两次的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot Thymeleaf 自定义验证器不显示错误

Spring Boot 从 1.5.3 升级到 1.5.4,自定义验证配置启动失败

spring boot spring security 基于自定义令牌的身份验证和自定义授权

如何从 facebook/google/... oauth2 身份验证在 Spring (Boot) 中为单页应用程序派生自定义登录令牌?

jhipster spring boot 自定义身份验证提供程序

spring boot中自定义验证的参数化junit测试