日期、數字格式化顯示,是web開發中的常見需求,spring mvc采用XXXFormatter來處理,先看一個最基本的單元測試:
1 package com.cnblogs.yjmyzz.test; 2 3 import java.math.BigDecimal; 4 import java.util.Date; 5 import java.util.Locale; 6 7 import org.junit.Test; 8 import org.springframework.context.i18n.LocaleContextHolder; 9 import org.springframework.format.datetime.DateFormatter; 10 import org.springframework.format.number.CurrencyFormatter; 11 import org.springframework.format.support.DefaultFormattingConversionService; 12 13 public class FormatterTest { 14 15 @Test 16 public void testFormatter() { 17 18 //設置上下語言的語言環境 19 LocaleContextHolder.setLocale(Locale.US); 20 21 //--------測試日期格式化---------- 22 Date d = new Date(); 23 DateFormatter dateFormatter = new DateFormatter(); 24 //按中文格式輸出日期 25 System.out.println(dateFormatter.print(d, Locale.CHINESE));//2014-10-30 26 27 DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(); 28 //添加前面的DateFormatter 29 conversionService.addFormatter(dateFormatter); 30 31 System.out.println(conversionService.convert(d, String.class));//Oct 30, 2014 32 33 dateFormatter.setPattern("yyyy年MM月dd日"); 34 System.out.println(conversionService.convert(d, String.class));//2014年10月30日 35 36 // --------測試貨幣格式化------------- 37 CurrencyFormatter currencyFormatter = new CurrencyFormatter(); 38 BigDecimal money = new BigDecimal(1234567.890); 39 System.out.println(currencyFormatter.print(money, Locale.CHINA));//¥1,234,567.89 40 conversionService.addFormatter(currencyFormatter); 41 System.out.println(conversionService.convert(money, String.class));//$1,234,567.89 42 43 44 } 45 46 }
除了DateFormatter、CurrencyFormatter,常用還有的以下Formatter:

這些Formatter全都實現了接口org.springframework.format.Formatter<T>,web開發中使用起來很方便:
一、先在servlet-context.xml中參考下面的內容,修改配置:
1 <mvc:annotation-driven conversion-service="conversionService" /> 2 3 <bean id="conversionService" 4 class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 5 </bean>
二、dto類中,在需要設置格式化的字段上,打上相關的注解
1 @NumberFormat(style=Style.CURRENCY) 2 //@NumberFormat(pattern="#,###.00") 3 double amount; 4 5 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") 6 Date createTime;
三、jsp頁面上,使用<spring:eval />標簽綁定
1 <td><spring:eval expression="c.amount" /></td> 2 <td><spring:eval expression="c.createTime" /></td>
四、枚舉問題
表單提交的html頁面中,經常會遇到一些諸如:性別(男、女) 的RadioButton組,背后通常對應Enum,表單提交的是String,默認情況下並不能自動映射成Model中的Enum成員,需要額外的Converter處理
4.1 先定義一個基本的枚舉
1 package com.cnblogs.yjmyzz.enums; 2 3 public enum SEX { 4 5 /** 6 * 男 7 */ 8 Male("1", "男"), 9 10 /** 11 * 女 12 */ 13 Female("-1", "女"), 14 15 /** 16 * 保密 17 */ 18 Unknown("0", "保密"); 19 20 private final String value; 21 22 private final String description; 23 24 private SEX(String v, String desc) { 25 this.value = v; 26 this.description = desc; 27 } 28 29 public String getValue() { 30 return value; 31 } 32 33 public String getDescription() { 34 return description; 35 } 36 37 public static SEX get(String strValue) { 38 for (SEX e : values()) { 39 if (e.getValue().equals(strValue)) { 40 return e; 41 } 42 } 43 return null; 44 } 45 46 @Override 47 public String toString() { 48 return this.value; 49 } 50 51 }
保存到db中時,性別字段我們希望"男"存成"1","女"存成"-1","保密"存成"0"(當然,這只是個人喜好,僅供參考)
4.2 定義SEX枚舉的Converter
1 package com.cnblogs.yjmyzz.convertor; 2 3 import org.springframework.core.convert.converter.Converter; 4 import com.cnblogs.yjmyzz.enums.SEX; 5 6 public class String2SexConvertor implements Converter<String, SEX> { 7 8 @Override 9 public SEX convert(String enumValueStr) { 10 String value = enumValueStr.trim(); 11 if (value.isEmpty()) { 12 return null; 13 } 14 return SEX.get(enumValueStr); 15 } 16 }
代碼很短,不多解釋,Convert方法,完成類似 "1" -> SEX.Male的轉換
4.3 配置修改
1 <bean id="conversionService" 2 class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 3 <property name="converters"> 4 <set> 5 <bean class="com.cnblogs.yjmyzz.convertor.String2SexConvertor" /> 6 </set> 7 </property> 8 </bean>
只需要在剛才的conversionService加上自己的Converter就行
4.4 form頁面上的綁定示例:
1 <form:radiobuttons path="sex" items="${sexMap}" delimiter=" " />
sexMap是ModelAndView中的一個屬性,參考代碼如下:
1 package com.cnblogs.yjmyzz.repository; 2 3 import java.util.EnumSet; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import com.cnblogs.yjmyzz.enums.SEX; 8 9 public class EnumRepository { 10 static Map<String, String> sexMap = null; 11 12 public static Map<String, String> getSexMap() { 13 if (sexMap == null) { 14 sexMap = new HashMap<String, String>(); 15 EnumSet<SEX> sexs = EnumSet.allOf(SEX.class); 16 for (SEX sex : sexs) { 17 sexMap.put(sex.getValue(), sex.getDescription()); 18 } 19 } 20 return sexMap; 21 } 22 23 }
Action中,這樣寫:
1 @RequestMapping(value = "edit/{id}") 2 public ModelAndView edit(@PathVariable int id, HttpServletRequest request, 3 HttpServletResponse response) throws Exception { 4 ModelAndView model = new ModelAndView(); 5 Order order = orderService.get(id + ""); 6 model.addObject("sexMap", EnumRepository.getSexMap());//枚舉列表,便於頁面綁定 7 model.addObject("data", order); 8 model.setViewName("orders/edit"); 9 return model; 10 }
4.5 頁面顯示時,如何轉義
就剛才的示例而言,性別“男”,對應SEX.Male,自定義值是"1",自定義描述是“男”,默認情況下${model.sex}顯示成Male,如果想顯示“自定義值”或“自定義描述”,不考慮國際化的話,直接調用value或description屬性即可,參考下面的內容:
1 <td>${c.sex}/${c.sex.description}/${c.sex.value}</td>
最終顯示成: Male/男/1
