HttpMessageConverter和JSON消息轉換器
HttpMessageConverter是定義從HTTP接受請求信息和應答給用戶的
HttpMessageConverter是一個比較廣的設計,雖然Spring MVC實現它的類有很多種,但是真正在工作和學習中使用得比較多的只有MappingJackson2HttpMessageConverter,這是一個關於JSON消息的轉換類,通過它能夠把控制器返回的結果在處理器內轉換為JSON數據
代碼清單16-3:使用XML配置MappingJackson2HttpMessageConverter
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jsonConverter"/> </list> </property> </bean> <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean>
對於它的應用十分簡單,只需要一個注解@ResponseBody就可以了。當遇到這個注解的時候,Spring MVC就會將應答類型轉變為JSON,然后就可以通過響應類型找到配置的MappingJackson2HttpMessageConverter進行轉換了
@RequestMapping(value = "/getRole3") //注解,使得Spring MVC把結果轉化為JSON類型響應,進而找到轉換器 @ResponseBody public Role getRole3(Long id) { // Role role = roleService.getRole(id); Role role = new Role(id, "射手", "遠程物理輸出"); return role; }
一對一轉換器(Converter)
Converter是一種一對一的轉換器
代碼清單16-6:字符串角色轉換器
package com.ssm.chapter15.converter; import com.ssm.chapter15.pojo.Role; import org.apache.commons.lang3.StringUtils; import org.springframework.core.convert.converter.Converter; public class StringToRoleConverter implements Converter<String, Role> { @Override public Role convert(String str) { //空串 if (StringUtils.isEmpty(str)) { return null; } //不包含指定字符 if (str.indexOf("-") == -1) { return null; } String[] arr = str.split("-"); //字符串長度不對 if (arr.length != 3) { return null; } Role role = new Role(); role.setId(Long.parseLong(arr[0])); role.setRoleName(arr[1]); role.setNote(arr[2]); return role; } }
代碼清單16-8:使用XML配置自定義轉換器
<mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.ssm.chapter15.converter.StringToRoleConverter"/> </list> </property> </bean>
代碼清單16-9:測試自定義轉換器
@RequestMapping(value = "/updateRole") @ResponseBody public Role updateRole(Role role) { System.out.println(role.toString()); // Map<String, Object> result = new HashMap<String, Object>(); //更新角色 // boolean updateFlag = (roleService.updateRole(role) == 1); // boolean updateFlag = false; // result.put("success", updateFlag); // if (updateFlag) { // result.put("msg", "更新成功"); // } else { // result.put("msg", "更新失敗"); // } // return result; return role; }
數組和集合轉換器GenericConverter
上述的轉換器是一種一對一的轉換,它存在一個弊端:只能從一種類型轉換成另一種類型,不能進行一對多轉換,比如把String轉換為List<String>或者String[],甚至是List,一對一轉換器都無法滿足。為了克服這個問題,Spring Core項目還加入了另外一個轉換器結構GenericConverter,它能夠滿足數組和集合轉換的要求。
使用格式化器(Formatter)
有些數據需要格式化,比如說金額、日期等。傳遞的日期格式為yyyy-MM-dd或者yyyy-MM-dd hh:ss:mm,這些是需要格式化的,對於金額也是如此,比如1萬元人民幣,在正式場合往往要寫作¥10 000.00,這些都要求把字符串按照一定的格式轉換為日期或者金額。
為了對這些場景做出支持,Spring Context提供了相關的Formatter。它需要實現一個接口——Formatter
在Spring內部用得比較多的兩個注解是@DateTimeFormat和@NumberFormat
代碼清單16-16:測試數據轉換的控制器
package com.ssm.chapter15.controller; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.NumberFormat; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.util.Date; @Controller @RequestMapping("/convert") public class ConvertController { @RequestMapping("/format") public ModelAndView format( //日期格式化 @RequestParam("date1") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date date, //金額格式化 @RequestParam("amount1") @NumberFormat(pattern = "#,###.##") Double amount) { ModelAndView mv = new ModelAndView("index"); mv.addObject("date", date); mv.addObject("amount", amount); return mv; } }