4

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.

Mister_L
  • 2,469
  • 6
  • 30
  • 64
  • 1
    If you could share a minimal project which reproduces the issue, that would help – Adam Jul 09 '19 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` – Avi Jul 10 '19 at 08:53

1 Answers1

5

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.

Mister_L
  • 2,469
  • 6
  • 30
  • 64