您的位置:首頁>正文

Java國際化之(五)——自訂國際化formatter注解實現

引言

由於Spring MVC自帶的@NumberFormat和@DateTimeFormat格式化不能很好的支持國際化, 在《java國際化之---springMVC+Freemaker demo(三)》http://moon-walker.iteye.com/blog/2379940的demo中我們實現了自定的formatter:MyDateFormatter、MyCurrencyFormatter分別支援國際化的日期、貨幣處理。 但有個弊端, 表單物件中所有的Date、BigDecimal類型都會進行相同規則的轉換, 不能像Spring MVC自帶的@NumberFormat和@DateTimeFormat對指定屬性添加注解, 只對指定物件進行轉換。

慶倖的是Spring MVC支持我們對自訂的Formatter添加自己的注解。 下面我們進行詳細講解, 並附上demo代碼, 詳見文章末尾Github地址。

自訂的Formatter注解

要實現自訂的Formatter注解, 其實可以參考Spring MVC自帶的@NumberFormat實現方法, 這裡我們以上一篇demo中實現的MyDateFormatter為例, 進行講解。

創建過程分為三步:

第一步:首先我們看下@DateTimeFormat注解在Spring MVC中的實現,

並模擬創建自己的@MyDateFormat注解, 內容如下:

/** * Created by gantianxing on 2017/6/17. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) public @interface MyDateFormat { }

第二步:仿照Spring MVC中的DateTimeFormatAnnotationFormatterFactory創建自己AnnotationFormatterFactory實現類MyDateFormatAnnotationFormatterFactory, 內容如下:

/** * Created by gantianxing on 2017/6/17. */ public class MyDateFormatAnnotationFormatterFactory implements AnnotationFormatterFactory { private static final Set> FIELD_TYPES; static { Set> fieldTypes = new HashSet>(4); fieldTypes.add(Date.class);//這裡只處理Date類型 FIELD_TYPES = Collections.unmodifiableSet(fieldTypes); } @Override public Set> getFieldTypes { return FIELD_TYPES;//返回支援的類型列表 } @Override public Printer getPrinter(MyDateFormat myDateFormat, Class aClass) { return getFormatter(myDateFormat, aClass); } @Override public Parser getParser(MyDateFormat myDateFormat, Class aClass) { return getFormatter(myDateFormat, aClass); } protected Formatter getFormatter(MyDateFormat annotation, Class fieldType) { MyDateFormatter formatter = new MyDateFormatter; return formatter; } }

第三步:將自訂的MyDateFormatAnnotationFormatterFactory注入到spring mvc, 在spring-mvc.xml中的配置代碼如下:

為了對比, 這裡MyCurrencyFormatter沒有採用自訂注解方式實現, 感覺興趣的朋友可以參照上述三個步驟自己實現。

使用自訂注解

為了方便對比, 在User類中同時使用自帶的@DateTimeFormat注解、自訂的@MyDateFormat注解。 在上一篇代碼的基礎上, 對birthday欄位添加@DateTimeFormat注解, 新增regTime欄位並添加@DateTimeFormat(pattern="yyyy-MM-dd"),修改後的代碼如下:

/** * Created by gantianxing on 2017/6/8. */ public class User implements Serializable { private static final long serialVersionUID = 1L; @NotNull(message="{user.name.null}") @Size(min=2,max =5,message = "{user.name.error}") private String name;//姓名 @NotNull(message="{user.birthday.null}") @Past(message="{user.birthday.error}") @MyDateFormat private Date birthday;//生日 @DateTimeFormat(pattern="yyyy-MM-dd") private Date regDate;//註冊時間 @NotNull(message="{user.money.null}") @Digits(integer=3,fraction=2,message="{user.money.error}") @NumberFormat(pattern = "¥#.##") private BigDecimal money;//資產 @NotNull(message="{user.phoneNum.null}") @Pattern(regexp="\d{11}",message="{user.phoneNum.error}") private String phoneNum;//手機號 public String getName { return name; } public void setName(String name) { this.name = name; } public Date getBirthday { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public BigDecimal getMoney { return money; } public void setMoney(BigDecimal money) { this.money = money; } public String getPhoneNum { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } public Date getRegDate { return regDate; } public void setRegDate(Date regDate) { this.regDate = regDate; } }

啟動tomcat, 訪問http://localhost/add頁面, 填寫表單, Register Date的格式必須為yyyy-MM-dd, 輸入錯誤的情況下, 報如下錯誤:

這種錯誤提示不能直接暴露給用戶, 我們可以通過列印器錯誤碼, 並在國際化設定檔中進行配置。 比如這裡的列印的錯誤碼為:typeMismatch, 在中文和英文的屬性設定檔中分別配置:

typeMismatch.user.regDate=格式:yyyy-MM-dd

typeMismatch.user.regDate=Style:yyyy-MM-dd

重啟tomcat, 重新提交錯誤格式的regDate表單, 顯示如下:

再切換到中文(ps:如果切換不成功, tomcat版本請換成tomcat8以上):

同時在birthday欄位上使用的自訂注解@MyDateFormat, 也已經生效。

如果在同一個表單物件中, 有多個Date類型, 只需要對其中部分Date欄位進行自訂格式化轉換, 另外的採用Spring MVC默認的格式化轉換, 這個時候就不得不用到自訂注解實現。

ok, 關於“自訂國際化formatter注解實現”方法講解完畢, 最後奉上代碼 GitHub位址:https://github.com/gantianxing/locale-demo2.git。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示