使用JAX-RS进行Bean验证(轻松实现):无法识别参数名称

omi*_*lke 6 jax-rs resteasy bean-validation wildfly-swarm

我正在使用带有Bean验证的JAX-RS资源,并且按预期在这两个作品之间进行了集成。

但是,在验证错误报告参数名称为arg0的情况下会生成默认错误消息,如下所示

[PARAMETER]
[login.arg0.password]
[password is required]
[]
Run Code Online (Sandbox Code Playgroud)

对应的方法定义:

@POST //and other JAX-RS annotations
public Response login(
        @NotNull
        @Valid
        LoginBody loginBody) {

   [...]

protected static class LoginBody {

    @NotNull(message =  EMAIL_REQUIRED)
    public String email;

    @NotNull(message = PASSWORD_REQUIRED)
    public String password;
}
Run Code Online (Sandbox Code Playgroud)

尽管我对这种消息模式总体上很满意,但实际上令人anny恼的是,原始参数名称未被识别,即,我希望看到

登录。loginBody .password而不是arg0

是否有解决此问题的简便方法,例如以某种方式为该参数提供一个明确的名称?

我正在使用WildFly Swarm 2017.6.0。从我发现的结果来看,这意味着我拥有resteasy + resteasy-validator +休眠验证器

谢谢。

Tho*_*ont 2

您可以尝试使用-parameters或指示您的 IDE 来编译您的应用程序,例如在 Eclipse 的情况下:首选项 -> java -> 编译器 -> “存储有关方法参数的信息(可通过反射使用)”

完成后,您需要指示 Bean 验证基础结构(例如) hibernate-validator 使用ReflectiveParameterNamervia META-INF/validation.xml

<parameter-name-provider>org.hibernate.validator.parameternameprovider.ReflectionParameterNameProvider</parameter-name-provider>
Run Code Online (Sandbox Code Playgroud)

另请参阅Hibernate 验证器配置

我得到了与Paranamer 库可靠配合的东西

META-INF/validation.xml

<?xml version="1.0" encoding="UTF-8"?>
<validation-config
   xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
                    http://jboss.org/xml/ns/javax/validation/configuration
                    validation-configuration-1.1.xsd"
   version="1.1">
   <default-provider>org.hibernate.validator.HibernateValidator
   </default-provider>
   <message-interpolator>org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator
   </message-interpolator>
   <traversable-resolver>org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver
   </traversable-resolver>
   <constraint-validator-factory>org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl
   </constraint-validator-factory>
   <parameter-name-provider>org.hibernate.validator.parameternameprovider.ParanamerParameterNameProvider</parameter-name-provider>
</validation-config>
Run Code Online (Sandbox Code Playgroud)

为了paranamer使用 wildfly,我需要创建一个parameter-namerjboss 模块并从模块引用该module.xml模块hibernate-validator

有了这个,我就可以简单地写:

@POST
public Response login(@NotNull @Valid @Named("authRequest") AuthRequest authRequest) {
    return Response.ok().build();
}
...

public class AuthRequest {

    @NotNull(message = AuthMessages.EMAIL_REQUIRED)
    public String email;

    @NotNull(message = AuthMessages.PASSWORD_REQUIRED)
    public String password;
}
Run Code Online (Sandbox Code Playgroud)

对于通过 发送的请求,会产生以下响应curl

curl -H "Content-Type: application/json" -H "Accept: application/json" -d '{"email":"foo@bar.com"}' -v http://localhost:8080/javaweb-training/resources/auth
Run Code Online (Sandbox Code Playgroud)

回复:

{"exception":null,"fieldViolations":[],"propertyViolations":[],"classViolations":[],"parameterViolations":[{"constraintType":"PARAMETER","path":"login.authRequest.password","message":"password.required","value":""}],"returnValueViolations":[]}%
Run Code Online (Sandbox Code Playgroud)

...注意login.authRequest.password而不只是login.arg0.password