Проверка Bean с помощью JAX-RS (rest-easy): имя параметра не распознано
Я использую ресурсы JAX-RS с проверкой Bean и интеграцией между этими двумя работами, как и ожидалось.
Однако сообщения об ошибках по умолчанию, генерируемые в случае отчета об ошибке проверки, называются arg0, например так
[PARAMETER]
[login.arg0.password]
[password is required]
[]
Соответствующее определение метода:
@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;
}
Хотя я в целом согласен с этим шаблоном сообщений, то, что на самом деле раздражает, - это тот факт, что исходное имя параметра не распознается, т. е.
Вход в систему.логинбоди .пароль вместо arg0.
Есть ли простой способ исправить это, например, каким-то образом предоставить явное имя для этого параметра?
Я использую Wildfly Swarm 2017.6.0. Из того, что я узнал, это означает, что у меня есть resteasy + resteasy-validator + hibernate-validator
Спасибо.
3 ответа:
Вы можете попробовать скомпилировать приложение с помощью
-parametersили поручить IDE сделать это, например, в случае eclipse: preferences - > java - > compiler - > "хранить информацию о параметрах метода (можно использовать через отражение)"С этим на месте вам тогда нужно проинструктировать инфраструктуру проверки Bean (например) hibernate-validator, чтобы используйте
ReflectiveParameterNamerчерезMETA-INF/validation.xml.<parameter-name-provider>org.hibernate.validator.parameternameprovider.ReflectionParameterNameProvider</parameter-name-provider>Смотрите также конфигурацию валидатора гибернации
У меня есть что-то надежно работающее с библиотека Паранамера
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>Чтобы получить
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; }, который дает следующий ответ на запрос, отправленный через
curl:curl -H "Content-Type: application/json" -H "Accept: application/json" -d '{"email":"foo@bar.com"}' -v http://localhost:8080/javaweb-training/resources/authОтвет:
{"exception":null,"fieldViolations":[],"propertyViolations":[],"classViolations":[],"parameterViolations":[{"constraintType":"PARAMETER","path":"login.authRequest.password","message":"password.required","value":""}],"returnValueViolations":[]}%... Примечание
login.authRequest.passwordвместо простоlogin.arg0.password
Можете ли вы попробовать реализовать отображение исключений для ConstraintViolationExceptions и посмотреть, может ли информация, которая у вас есть (список нарушений ограничений), помочь вам получить имя параметра?
Есть очень простое решение: вы можете установить свое собственное сообщение об ошибке в определении ограничения следующим образом
@NotNull(message = "password is required")Если вы хотите получить более общее решение, основанное на аннотациях параметров JAX-RS, вы можете реализовать свой собственный простой
ParameterNamProviderи зарегистрировать его вvalidation.xmlследующим образом. Это имеет то преимущество, что не нужно изменять структуру модуля jboss. Мне также не пришлось менять флаги компилятора...public class AnnotatedParameterNameProvider implements ParameterNameProvider { @Override public List<String> getParameterNames(Constructor<?> constructor) { return lookupParameterNames(constructor.getParameterAnnotations()); } @Override public List<String> getParameterNames(Method method) { return lookupParameterNames(method.getParameterAnnotations()); } private List<String> lookupParameterNames(Annotation[][] annotations) { final List<String> names = new ArrayList<>(); if (annotations != null) { for (Annotation[] annotation : annotations) { String annotationValue = null; for (Annotation ann : annotation) { annotationValue = getAnnotationValue(ann); if (annotationValue != null) { break; } } // if no matching annotation, must be the request body if (annotationValue == null) { annotationValue = "requestBody"; } names.add(annotationValue); } } return names; } private static String getAnnotationValue(Annotation annotation) { if (annotation instanceof HeaderParam) { return ((HeaderParam) annotation).value(); } else if (annotation instanceof PathParam) { return ((PathParam) annotation).value(); } else if (annotation instanceof QueryParam) { return ((QueryParam) annotation).value(); } return null; } }В валидации.xml:
<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"> <parameter-name-provider>com.yourcompany.providers.AnnotatedParameterNameProvider</parameter-name-provider> </validation-config>Обратите внимание, что вы также можете настройте форматирование сообщения об ошибке, реализовав свой собственный
MessageInterpolatorи зарегистрировав его вvalidation.xml