使用javax.validation
目標:在Spring+JSF專案上使用javax.validation
,用標籤即可達到基本檢查
根據https://beanvalidation.org/2.0/有實作的包似乎只有Hibernate Validator
public class Sysclitime {
/** 診別代碼(PK) */
@Id
@NotBlank
private String code;
/** 語系代碼(PK) */
@Id
@NotBlank
private String langcode;
/** 診別名稱 */
@Size(min=0, max=10)
private String name;
}
遇到的問題
訊息沒有繁體中文
所有訊息都放在hibernate-validator.jar
的org.hibernate.validator
中,但就是沒有繁中,因此只好複製修改一份放在src/main/resource
內的最外層,也就是跟application.properties
放一起,似乎有設定可以指定位置,但沒有特別研究
客製的訊息
預設訊息內容雖然清楚,但對於表單輸入總是需要說明是哪個欄位有怎樣的問題,因此需要在預設訊息前面加上欄位名稱。因此需要自定MessageInterpolator
(參考),但實作起來頗為麻煩,因此改為在驗證完取得Set<ConstraintViolation<Object>>
後另外處理
JSF的自動檢查
由於JSF在validation階段就會自動啟用檢查,是滿方便的,但要改成客製的Validator
好像有點麻煩,因此可以用<f:validateBean disabled="true">
把全範圍包起來,就完全關閉JSF自動檢查了
Spring與Hibernate沒有共用Validator
預期進行檢查的時間點是在進資料庫之前,也就是Repository的操作,而此時Hibernate也確實會自動進行檢查。由於需要客製訊息,因此需要替換預設的Validator。Spring可以透過設定Bean來替換,但Spring的Validator跟Hibernate沒有共用*1,*2,所以需要直接替換Hibernate的Validator,考慮所有設定都透過Spring型式,就沒再研究
@Bean
public Validator validator(MessageSource messageSource) {
LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
factory.setValidationMessageSource(messageSource);
return factory;
}
結論
由於需要訊息前方加上欄位名稱,如果無法在MessageInterpolator
達成,就勢必要手動觸發驗證。要在MessageInterpolator
達成,就需要替換Hibernate的Validator