Jersey中@NotNull与@QueryParam结合验证参数无效问题排查
Hey there! Let's figure out why your @NotNull annotations aren't working for those @QueryParam parameters in Jersey. I see a couple of key issues in your setup that are likely causing this, so let's walk through fixing them step by step.
1. Fix Your Dependencies (You're Missing a Validation Implementation)
Your pom.xml excludes hibernate-validator, but here's the thing: validation-api is just the specification—it doesn't actually do the validation work. Jersey's jersey-bean-validation relies on a concrete implementation like Hibernate Validator to execute the checks.
Update your dependency section to remove the exclusion and ensure you have a valid implementation:
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-bean-validation</artifactId> <version>2.12</version> <!-- Remove the hibernate-validator exclusion here --> </dependency> <!-- Add the Hibernate Validator implementation (compatible with Jersey 2.12) --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency>
2. Register the Bean Validation Feature in Jersey
Jersey won't automatically enable parameter validation unless you explicitly register the BeanValidationFeature in your application configuration.
If you're using a ResourceConfig class, add this registration:
import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.validation.beanvalidation.BeanValidationFeature; public class MyApplication extends ResourceConfig { public MyApplication() { // Register your resource classes/packages packages("your.package.where.resides"); // Enable bean validation register(BeanValidationFeature.class); } }
If you're using web.xml for configuration, add the feature to your Jersey servlet's init parameters:
<servlet> <servlet-name>Jersey Servlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.validation.beanvalidation.BeanValidationFeature</param-value> </init-param> <!-- Your other init params go here --> </servlet>
3. Double-Check Your @ValidateOnExecution Annotation
While @ValidateOnExecution can control when validation runs, for method parameter validation you don't strictly need it—though it's fine to keep it. Just make sure you're importing the correct version from javax.validation.executable.ValidateOnExecution.
4. Add a Validation Exception Mapper (Optional but Recommended)
To return a user-friendly error response when validation fails, create an exception mapper for ConstraintViolationException:
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; import java.util.HashMap; import java.util.Map; @Provider public class ValidationExceptionMapper implements ExceptionMapper<ConstraintViolationException> { @Override public Response toResponse(ConstraintViolationException exception) { Map<String, String> errors = new HashMap<>(); for (ConstraintViolation<?> violation : exception.getConstraintViolations()) { String paramName = violation.getPropertyPath().toString(); errors.put(paramName, violation.getMessage()); } return Response.status(Response.Status.BAD_REQUEST) .entity(errors) .type(MediaType.APPLICATION_JSON) .build(); } }
Don't forget to register this mapper in your ResourceConfig or web.xml too!
Final Check
After making these changes, restart your app and test a request without the phone or email query parameter. You should get a 400 Bad Request with validation errors instead of the code proceeding to your try block.
内容的提问来源于stack exchange,提问作者user9769408

