我有這個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中打印值時,它只顯示前一個值而不是新值。 –