掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用
1: 注冊屬性編輯器
我們在接收參數(shù)的時候,對于基礎(chǔ)的數(shù)據(jù)類型,比如接收string,int等類型,springmvc是可以直接處理的,但是對于其他復(fù)雜的對象類型,有時候是無法處理的,這時候就需要屬性編輯器來進(jìn)行處理(源數(shù)據(jù)為string),過程一般就是 String->屬性編輯器->目標(biāo)類型 。spring為我們提供了一些默認(rèn)的屬性編輯器,如 org.springframework.beans.propertyeditors.CustomDateEditor 就是其中一個,我們也可以通過繼承 java.beans.PropertyEditorSuppotr 來根據(jù)具體的業(yè)務(wù)來定義自己的屬性編輯器。
1.1: 使用系統(tǒng)默認(rèn)提供的屬性編輯器
- 定義controller并使用@InitBinder注冊屬性編輯器
這里注冊的屬性編輯器為 org.springframework.beans.propertybeans.CustomDateEditor ,作用是根據(jù)提供的 java.text.SimpleDateFormat 將輸入的字符串?dāng)?shù)據(jù)轉(zhuǎn)換為 java.util.Date 類型的數(shù)據(jù),核心源碼如下:
org.springframework.beans.propertyeditors.CustomDateEditor#setAsText
public void setAsText(@Nullable String text) throws IllegalArgumentException {
...
else {
try {
// 使用用戶提供的java.text.SimpeDateFormat來將目標(biāo)字符串格式化為java.util.Date類型,并通過SetValue方法設(shè)置最終值
setValue(this.dateFormat.parse(text));
}
...
}
}接下來定義類:
@RequestMapping("/myInitBinder0954")
@Controller
public class MyInitBinderController {
/*
注冊將字符串轉(zhuǎn)換為Date的屬性編輯器,該編輯器僅僅對當(dāng)前controller有效
*/
@InitBinder
public void initBinderXXX(WebDataBinder binder) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
CustomDateEditor dateEditor = new CustomDateEditor(df, true);
binder.registerCustomEditor(Date.class, dateEditor);
}
// http://localhost:8080/myInitBinder0954/test?date=2020-09-03%2010:17:17會使用在
// dongshi.controller.initbinder.MyInitBinderController.initBinderXXX注冊的屬性編輯器轉(zhuǎn)換為,
// Date類型的
@RequestMapping(value = "/test", method = RequestMethod.GET)
@ResponseBody
public String testFormatData(Date date) {
Map<String, Object> map = new HashMap<>();
map.put("date", date);
return map.toString();
}
}訪問測試

看到返回了Date的toString的結(jié)果,就是說明成功了。
1.2: 使用自定義的屬性編輯器
假設(shè)我們的需求是這樣的,調(diào)用方傳過來的值是一個 _ 豎線分割的字符串,但是處理的過程使用的是通過 _ 號分割得到的一個 String[] ,我們當(dāng)然可以在接口內(nèi)部去處理,但是我們作為 專業(yè)的屌絲程序員,哈哈哈 ,還是要用專業(yè)一些的手段,這里就可以定義一個 將豎線分割的多個字符串轉(zhuǎn)換為String[] 的自定義屬性編輯器來實(shí)現(xiàn)。
- 自定義屬性編輯器
通過繼承 java.beans.PropertyEditorSupport 類并重寫其 setAdText(String text) 方法完成,最后調(diào)用 setValue(Object Value) 方法完成轉(zhuǎn)換后的值的設(shè)置。
public class StringToListPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
String[] resultArr = null;
if (!StringUtils.isEmpty(text)) {
resultArr = text.split("_");
}
setValue(resultArr);
}
}使用
@RequestMapping("/myStringToList")
@Controller
public class StringToListController {
@InitBinder
public void myStringToListBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(String[].class, new StringToListPropertyEditor());
}
@RequestMapping(value = "/test", method = RequestMethod.GET)
@ResponseBody
public String myStringToListTest(String[] strToListArr, HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
String result = "_分割字符串轉(zhuǎn)String[]不成功!";
if (strToListArr != null && strToListArr.length > 0) {
result = Arrays.asList(strToListArr).toString();
}
return result;
}
}訪問測試

2: 處理帶有前綴的form字段
比如這樣的場景,在People,Address兩個類中都有name字段,但是我們需要在一個表單中錄入People和Address的信息,然后在接口中直接通過People,Address兩個對象來接收頁面的表單數(shù)據(jù),但是 兩個name 是無法區(qū)分的,一般的做法就是指定一個前綴,然后通過@InitBinder通過調(diào)用 org.springframework.web.bind.WebDataBinder 的 setFieldDefaultPrefix(@Nullable String fieldDefaultPrefix) 方法,然后在接口中使用注解 public @interface ModelAttribute 設(shè)置要接收的參數(shù)的前綴,就可以區(qū)分并接收對應(yīng)的參數(shù)了。
2.1: 定義用到的實(shí)體
Person
public class People {
private String name;
private String age;
// getter setter toString
}Address
public class Address {
private String name;
private String city;
// getter setter toString
}2.2: 定義測試使用的表單
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/myInitBinder0954/test0942" method="post" enctype="multipart/form-data">
<input type="text" name="people.name" placeholder="人名"><br><br>
<input type="text" name="people.age" placeholder="人年齡"><br><br>
<input type="text" name="address.name" placeholder="地址名稱"><br><br>
<input type="text" name="address.city" placeholder="地址所在城市"><br><br>
<input type="submit" value="提交"/>
</form>
</body>
</html>2.3: 定義接口
@RequestMapping("/myInitBinder0954")
@Controller
public class MyInitBinderController {
@InitBinder(value = "people")
public void initBinderSetDefaultPreifixPeople(WebDataBinder dataBinder) {
dataBinder.setFieldDefaultPrefix("people.");
}
@InitBinder(value = "address")
public void initBinderSetDefaultPreifixAddress(WebDataBinder dataBinder) {
dataBinder.setFieldDefaultPrefix("address.");
}
@RequestMapping(value = "/test0942", method = RequestMethod.POST)
@ResponseBody
public String test0942(@ModelAttribute("people") People people, @ModelAttribute("address") Address address) {
StringBuffer sb = new StringBuffer();
sb.append(people.toString());
sb.append("---");
sb.append(address.toString());
return sb.toString();
}
}2.4: 訪問測試 錄入表帶數(shù)據(jù)

訪問返回結(jié)果

3:注冊校驗(yàn)器
3.1:定義測試實(shí)體
package dongshi.controller.initbinder;
public class User {
private String userName;
// getter setter toString
}3.2:自定義校驗(yàn)器
直接實(shí)現(xiàn) org.springframework.validation.Validator ,該接口只有兩個方法,一個是校驗(yàn)是否支持校驗(yàn)的 support(Class<?> clazz) 方法,一個是進(jìn)行具體校驗(yàn)的 validate(Object target, Errors errors) 方法,源碼如下:
public interface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errors errors);
}定義一個校驗(yàn)器:
@Component
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
// 只支持User類型對象的校驗(yàn)
return User.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
String userName = user.getUserName();
if (StringUtils.isEmpty(userName) || userName.length() < 8) {
errors.rejectValue("userName", "valid.userNameLen",
new Object[] { "minLength", 8 }, "用戶名不能少于{1}位");
}
}
}該校驗(yàn)器校驗(yàn)用戶錄入的userName長度是否大于8,并給出響應(yīng)的錯誤信息,錯誤信息直接設(shè)置到errors中,最終會設(shè)置到 org.springframework.validation.BindingReuslt ,在接口中直接定義該對象則會自動注入對象值,從而可以獲取到對應(yīng)的錯誤信息。
3.3:定義控制器
@Controller
@RequestMapping("/valid")
public class ValidatorController {
@Autowired
private UserValidator userValidator;
@InitBinder
private void initBinder(WebDataBinder binder) {
binder.addValidators(userValidator);
}
@RequestMapping(value = { "/index", "" }, method = { RequestMethod.GET })
public String index(ModelMap m) throws Exception {
m.addAttribute("user", new User());
return "initbinder/user.jsp";
}
@RequestMapping(value = { "/signup" }, method = { RequestMethod.POST })
public String signup(@Validated User user, BindingResult br, RedirectAttributes ra) throws Exception {
// 攜帶用戶錄入的信息方便回顯
ra.addFlashAttribute("user", user);
return "initbinder/user.jsp";
}
}3.4:定義user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>validate user</title>
</head>
<body>
<form:form modelAttribute="user" action="/valid/signup" method="post">
<!-- 顯示所有的錯誤信息 -->
<form:errors path="*"></form:errors>
用戶名:<form:input path="userName"/><form:errors path="userName"/>
</form:form>
</body>
</html>3.5:訪問user.jsp

錄入一個不合法的字符,并回車:

到此這篇關(guān)于掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用的文章就介紹到這了,更多相關(guān)SpringMVC中@InitBinder內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一次Jvm old過高的排查過程實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了一次Jvm old過高的排查過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
Java實(shí)現(xiàn)等待所有子線程結(jié)束后再執(zhí)行一段代碼的方法
這篇文章主要介紹了Java實(shí)現(xiàn)等待所有子線程結(jié)束后再執(zhí)行一段代碼的方法,涉及java多線程的線程等待與執(zhí)行等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
JMeter自定義日志與日志分析的實(shí)現(xiàn)
JMeter與Java程序一樣,會記錄事件日志,本文就介紹一下JMeter自定義日志與日志分析的實(shí)現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id
這篇文章主要介紹了mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
Java源碼難點(diǎn)突破Lambda表達(dá)式執(zhí)行原理
這篇文章主要為大家介紹了Java難點(diǎn)突破Lambda表達(dá)式執(zhí)行原理分析及示例的實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié)
這篇文章主要為大家介紹了Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
springboot項目maven引入本地包沒打包進(jìn)去的解決方案
這篇文章主要介紹了springboot項目maven引入本地包沒打包進(jìn)去的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-09-09

