Проверка 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-namer
JBoss-модуль и ссылайтесь на этот модуль из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