我有这个Web应用程序,我已经建立了bean验证,它的工作非常好。但是对于一个字段,它不会读取我在我的validation.properties文件中设置的消息。对于其他领域,它的作品。我感到困惑,为什么会发生这种情况?让我告诉你我的设置:自定义验证消息适用于某些错误
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setCacheSeconds(0);
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
messageSource.setBasenames("/WEB-INF/Validation/validation"); //I have tried setBaseName as well but same difference.
return messageSource;
}
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(this.messageSource());
return validator;
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(this.localValidatorFactoryBean());
return processor;
}
@Autowired
SpringValidatorAdapter validator; //global validator
@Override
public Validator getValidator() {
return this.validator;
}
我的属性文件位于正确的位置。我知道,因为一些错误,消息从这个validation.properties文件中读取。地点是:
的src \主\ web应用\ WEB-INF \确认\ validation.properties
里面的内容是:
validate.user.yearsexperience =只有数字可以在这里使用。
validate.user.phone =电话号码只能是数字,应该是10位数字。
validate.user.name.blank =名称不能留空或不能包含超过30个字符。它只会接受字母。也不允许使用数字或符号。
然后,我设置了以下错误代码,预期bean验证程序捕获这些消息之一(但它没有)。
typeMismatch.user.yearsexperience =在这里只能使用数字。
typeMismatch.yearsexperience =此处只能使用数字。
typeMismatch.java.lang.Integer =这里只能使用数字。
typeMismatch =此处只能使用数字。
所以,当我输入错误数据phone
或name
场,JSP显示,我在validation.properties
文件中设置这些消息,但对于yearsexperience
领域,它表明了自己的typeMismatch
或cannot convert String to Integer, etc exceptions
。
下面就让我来告诉你什么注解我曾经在我的模型:
public class User{
@NotBlankNoFancyLettersOrNumbers(message = "{validate.user.name.blank}") //My own custom annotation. Works like a charm and when user enters wrong data, it shows my custom error.
private String name;
@Pattern(regexp="(^$|[0-9]{10})", message = "{validate.user.phone}") //javax's builtin validation constraint
private String phone;
@So many things I have tried. But first I started with @Pattern
private Integer yearsexperience;
对于这个Integer
领域,我不能用@Pattern
,因为它只能放完了String
场(我说的对吗?)。
然后我试了@Digits
。当用户输入错误的输入时,它肯定会起作用,但不会显示我的错误消息,它显示用户的例外typeMismatch
。然后我做了自己的自定义注释,并给它起了个名字@DigitsOnly
。同样的问题,它不会显示我的错误消息。它显示了与旧的typeMismatch
例外情况相同的情况。
在这一点上,我想也许有一个表单绑定的问题(我应该不是认为,因为bean验证适用于其他领域)。不管怎么说,我注册了自己的自定义编辑器,像这样:
@InitBinder("user")
protected void binder(WebDataBinder binder, HttpSession session) throws Exception {
binder.registerCustomEditor(Date.class, new DateConvertor()); //This is unrelated to my question but it works!
binder.registerCustomEditor(Integer.class, "yearsexperience", new IntegerConvertor(session.getAttribute("user"), this.userdao));
}
这是我的类,它扩展PropertyEditorSupport
:
public class IntegerConvertor extends PropertyEditorSupport {
private User user;
private UserDAO userdao;
public IntegerConvertor(){}
public IntegerConvertor(Object object, UserDAO userdao) {
if (object instanceof User){
this.user= new User((User) object);
}
this.userdao = userdao;
}
@Override
public void setAsText(String value) {
if (!value.matches("[0-9]+")) { //if incoming value DOES NOT contains numbers only
setValue(this.userdao.getYearsExperienceBeforeChange(this.user.getId()));
} else {
setValue(value);
}
}
现在,我这样做的,希望typeMismatch
异常不会显示给用户,但是它仍然显示出异常。 (我知道从这个PropertyEditorSupport
,或者它不会从validation.properties
文件读取自定义的错误信息)。
无论如何,后来我尝试添加自定义验证通WebDataBinder.addValidator(myCustomValidator)
这样的:
@InitBinder("user")
protected void binder(WebDataBinder binder, HttpSession session) throws Exception {
binder.registerCustomEditor(Date.class, new DateConvertor());
binder.addValidators(new myCustormValidator());
}
这是我的自定义验证的样子,
public class MyCustormValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return User.class.equals(clazz); //return User.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
String a = Integer.toString(user.getYearsExperience());
if(!a.matches("[0-9]+")){
errors.rejectValue("yearsexperience","validate.user.yearsexperience");
}
}
}
我转换是Integer
到String
因为那时我能够检查传入值是否只包含数字而不包含字母。但在这里会引起另一个问题:它不显示传入值,它显示旧值。而且因为旧的价值已经是正确的,它不会引起任何问题。所以我添加了其他声明,只是为了抛出一个错误,希望现在至少会显示我的自定义错误。但它不!
因此,我来这里寻求帮助。任何帮助是极大的赞赏。
TL; DR为什么自定义错误消息不显示为一个字段。但对于其他领域,它工作得很好。
我建议你启用DEBUG甚至TRACE级别,看看在日志中会发生什么。 –
是的,谢谢你的建议。我会在今晚这样做,然后我会告诉你,如果我找到任何东西。 –
我试过了。我设置log4j2级别跟踪,然后全部。只是在我输入的价值被拒绝的任何地方都不会显示。无处!除非我手动打印错误,否则没有提及我的输入'55b'。它没有提到它被拒绝的地方。当我尝试在myCustomValidator中打印值时,它只显示前一个值而不是新值。 –