5

I have a spring boot app with a custom validator that I have created, very similarly to what is described here:

How to disable Hibernate validation in a Spring Boot project

I have tried the suggested solution, which means I added the following line to application.properties file:

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

Here's is the code(partial):

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

Then I have:

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

}

Then I have:

public class MyModel {
   @ReCaptchaResponse
   private Srting recaptcha;
}

I then stopped and recompiled the project, but the validator still runs twice. I don't know why this is happening really, I'm using the latest spring boot version whereas the suggested solution is from 2014...Maybe something has changed since then? Any ideas?

Thanks.

2
  • 1
    If you could share a minimal project which reproduces the issue, that would help Commented Jul 9, 2019 at 21:29
  • I am also not sure about that solution (faced myself), so for workaround you could have a separate Dto to receive the request and then map it to Entity Commented Jul 10, 2019 at 8:53

1 Answer 1

8

I have no idea why, but after replacing in my controller @Valid @RequestBody with @Validated @RequestBody it seems to do the trick, and now the validator runs only once.

Sign up to request clarification or add additional context in comments.

2 Comments

It works! but why?)
works, but why??

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.