Spring MVC 框架的 Converter<S,T> 是一個可以將一種數據類型轉換成另一種數據類型的接口,這里 S 表示源類型,T 表示目標類型。開發者在實際應用中使用框架內置的類型轉換器基本上就夠了,但有時需要編寫具有特定功能的類型轉換器。
例如,用戶輸入的日期可能有許多種形式,如“December 25,2014”“12/25/2014”和“2014-12-25”,這些都表示同一個日期。默認情況下,Spring 會期待用戶輸入的日期樣式與當前語言區域的日期樣式相同。例如,對於美國的用戶而言,就是月/日/年的格式。如果希望 Spring 在將輸入的日期字符串綁定到 LocalDate 時,使用不同的日期樣式,則需要編寫一個 Converter,才能將字符串轉換成日期。
java.time.LocalDate 類是 Java 8 的一個新類型,用來替代 java.util.Date。還需使用新的 Date/Time API 來替換舊有的 Date 和 Calendar 類。
類型轉換是在視圖與控制器相互傳遞數據時發生的。Spring MVC 框架對於基本類型(例如 int、long、float、double、boolean 以及 char 等)已經做好了基本類型轉換。
例如需要用戶在頁面表單中輸入信息來創建商品信息。當輸入“bianchengbang,18,1.85”時表示在程序中自動創建一個 new User,並將“bianchengbang”值自動賦給 name 屬性,將“18”值自動賦給 age 屬性,將“1.85”值自動賦給 height 屬性。
如果想實現上述應用,需要做以下 5 件事:
創建 ConverterController 控制器,代碼如下。
創建顯示用戶頁面 showUser.jsp,代碼如下。
addUser.jsp
showUser.jsp
例如,用戶輸入的日期可能有許多種形式,如“December 25,2014”“12/25/2014”和“2014-12-25”,這些都表示同一個日期。默認情況下,Spring 會期待用戶輸入的日期樣式與當前語言區域的日期樣式相同。例如,對於美國的用戶而言,就是月/日/年的格式。如果希望 Spring 在將輸入的日期字符串綁定到 LocalDate 時,使用不同的日期樣式,則需要編寫一個 Converter,才能將字符串轉換成日期。
java.time.LocalDate 類是 Java 8 的一個新類型,用來替代 java.util.Date。還需使用新的 Date/Time API 來替換舊有的 Date 和 Calendar 類。
內置的類型轉換器
在 Spring MVC 框架中,對於常用的數據類型,開發者無須創建自己的類型轉換器,因為 Spring MVC 框架有許多內置的類型轉換器用於完成常用的類型轉換。Spring MVC 框架提供的內置類型轉換包括以下幾種類型。1)標量轉換器
名稱 | 作用 |
---|---|
StringToBooleanConverter | String 到 boolean 類型轉換 |
ObjectToStringConverter | Object 到 String 轉換,調用 toString 方法轉換 |
StringToNumberConverterFactory | String 到數字轉換(例如 Integer、Long 等) |
NumberToNumberConverterFactory | 數字子類型(基本類型)到數字類型(包裝類型)轉換 |
StringToCharacterConverter | String 到 Character 轉換,取字符串中的第一個字符 |
NumberToCharacterConverter | 數字子類型到 Character 轉換 |
CharacterToNumberFactory | Character 到數字子類型轉換 |
StringToEnumConverterFactory | String 到枚舉類型轉換,通過 Enum.valueOf 將字符串轉換為需要的枚舉類型 |
EnumToStringConverter | 枚舉類型到 String 轉換,返回枚舉對象的 name 值 |
StringToLocaleConverter | String 到 java.util.Locale 轉換 |
PropertiesToStringConverter | java.util.Properties 到 String 轉換,默認通過 ISO-8859-1 解碼 |
StringToPropertiesConverter | String 到 java.util.Properties 轉換,默認使用 ISO-8859-1 編碼 |
2)集合、數組相關轉換器
名稱 | 作用 |
---|---|
ArrayToCollectionConverter | 任意數組到任意集合(List、Set)轉換 |
CollectionToArrayConverter | 任意集合到任意數組轉換 |
ArrayToArrayConverter | 任意數組到任意數組轉換 |
CollectionToCollectionConverter | 集合之間的類型轉換 |
MapToMapConverter | Map之間的類型轉換 |
ArrayToStringConverter | 任意數組到 String 轉換 |
StringToArrayConverter | 字符串到數組的轉換,默認通過“,”分割,且去除字符串兩邊的空格(trim) |
ArrayToObjectConverter | 任意數組到 Object 的轉換,如果目標類型和源類型兼容,直接返回源對象;否則返回數組的第一個元素並進行類型轉換 |
ObjectToArrayConverter | Object 到單元素數組轉換 |
CollectionToStringConverter | 任意集合(List、Set)到 String 轉換 |
StringToCollectionConverter | String 到集合(List、Set)轉換,默認通過“,”分割,且去除字符串兩邊的空格(trim) |
CollectionToObjectConverter | 任意集合到任意 Object 的轉換,如果目標類型和源類型兼容,直接返回源對象;否則返回集合的第一個元素並進行類型轉換 |
ObjectToCollectionConverter | Object 到單元素集合的類型轉換 |
注意:在使用內置類型轉換器時,請求參數輸入值與接收參數類型要兼容,否則會報 400 錯誤。請求參數類型與接收參數類型不兼容問題需要學習輸入校驗后才可解決。
自定義類型轉換器
當 Spring MVC 框架內置的類型轉換器不能滿足需求時,開發者可以開發自己的類型轉換器。例如需要用戶在頁面表單中輸入信息來創建商品信息。當輸入“bianchengbang,18,1.85”時表示在程序中自動創建一個 new User,並將“bianchengbang”值自動賦給 name 屬性,將“18”值自動賦給 age 屬性,將“1.85”值自動賦給 height 屬性。
如果想實現上述應用,需要做以下 5 件事:
- 創建實體類。
- 創建控制器類。
- 創建自定義類型轉換器類。
- 注冊類型轉換器。
- 創建相關視圖。
示例
1. 創建實體類
在 net.biancheng.po 包下創建 User 實體類,代碼如下。package net.biancheng.po; public class User { private String name; private Integer age; private Double height; /**省略setter和getter方法*/ }
2. 創建控制器類
在 net.biancheng.controller 包下創建 UserController 控制器,代碼如下。package net.biancheng.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import net.biancheng.po.User; @Controller public class UserController { @RequestMapping("/addUser") public String addUser() { return "addUser"; } }
package net.biancheng.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import net.biancheng.po.User; @Controller public class ConverterController { @RequestMapping("/converter") public String myConverter(@RequestParam("user") User user, Model model) { model.addAttribute("user", user); return "showUser"; } }
3. 創建自定義類型轉換器
創建 net.biancheng.converter,在該包下創建自定義類型轉換器 UserConverter,代碼如下。package net.biancheng.converter; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import net.biancheng.po.User; @Component public class UserConverter implements Converter<String, User> { @Override public User convert(String source) { // 創建User實例 User user = new User(); // 以“,”分隔 String stringvalues[] = source.split(","); if (stringvalues != null && stringvalues.length == 3) { // 為user實例賦值 user.setName(stringvalues[0]); user.setAge(Integer.parseInt(stringvalues[1])); user.setHeight(Double.parseDouble(stringvalues[2])); return user; } else { throw new IllegalArgumentException(String.format("類型轉換失敗, 需要格式'編程幫, 18,1.85',但格式是[% s ] ", source)); } } }
4. 配置轉換器
在 springmvc-servlet.xml 文件中添加以下代碼。<mvc:annotation-driven conversion-service="conversionService" /> <!--注冊類型轉換器UserConverter --> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="net.biancheng.converter.UserConverter" /> </list> </property> </bean>
5. 創建相關視圖
創建添加用戶頁面 addUser.jsp,代碼如下。<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>添加用戶</title> </head> <body> <form action="${pageContext.request.contextPath}/converter" method="post"> 請輸入用戶信息(格式為編程幫, 18,1.85): <input type="text" name="user" /> <br> <input type="submit" value="提交" /> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>文件上傳</title> </head> <body> 您創建的用戶信息如下: <br/> <!-- 使用EL表達式取出model中的user信息 --> 用戶名:${user.name } <br/> 年齡:${user.age } <br/> 身高:${user.height } </body> </html>
6. 測試
訪問地址:http://localhost:8080/springmvcDemo2/addUser,運行結果如下圖所示。
addUser.jsp

showUser.jsp