Springmvc支持將參數封裝到對象中,步驟以下所示: java
和大部分框架同樣,Springmvc不支持StringàDate類型的轉換,這時就須要本身註冊一個「用戶數據編輯器」CustomDateEditor,這個註冊的步驟應該在initBinder(request,binder)方法中完成,以下所示: web
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); spring
CustomDateEditor dateEditor = new CustomDateEditor(sdf, true); mvc
binder.registerCustomEditor(Date.class, dateEditor); app
PhoneDataEditor phoneDataEditor = new PhoneDataEditor(); 框架
這樣就能夠將符合格式字符串轉換成Date對象。 編輯器
若是咱們想定義本身的「用戶編輯器」,應該繼承PropertyEditorSupport這個類,並覆寫public String getAsText()和public void setAsText(String text)方法,事例代碼以下: ide
編輯器 測試
public class PhoneDataEditor extends PropertyEditorSupport { this
@Override
public String getAsText() {
// TODO Auto-generated method stub
PhoneNumber number = (PhoneNumber)getValue();
return number == null?"":number.getAreaCode()+"--"+number.getPn();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
// TODO Auto-generated method stub
Pattern p = Pattern.compile("^(\\d{3,4})-(\\d{7,8})$");
if(text==null||!StringUtils.hasLength(text)){
setValue(null);
}
Matcher matcher = p.matcher(text);
if(matcher.matches()){
PhoneNumber number = new PhoneNumber();
number.setAreaCode(matcher.group(1));
number.setPn(matcher.group(2));
setValue(number);
}else{
throw new IllegalArgumentException("時間格式錯誤,沒法進行轉換");
}
}
}
Domain對象(1)
public class DataTest {
private String type;
private PhoneNumber phone;
private Date birthday;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public PhoneNumber getPhone() {
return phone;
}
public void setPhone(PhoneNumber phone) {
this.phone = phone;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
Domain對象(2)
public class PhoneNumber {
private String areaCode;
private String pn;
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getPn() {
return pn;
}
public void setPn(String pn) {
this.pn = pn;
}
}
Controller
public class DataTransferController extends AbstractCommandController{
public DataTransferController(){
this.setCommandClass(DataTest.class);
this.setCommandName("data");
}
@Override
protected ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
// TODO Auto-generated method stub
System.out.println(command);
return new ModelAndView("index").addObject("data1", command);
}
/* (non-Javadoc)
* @see org.springframework.web.servlet.mvc.BaseCommandController#initBinder(javax.servlet.http.HttpServletRequest, org.springframework.web.bind.ServletRequestDataBinder)
*/
@Override
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
// TODO Auto-generated method stub
super.initBinder(request, binder);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
CustomDateEditor dateEditor = new CustomDateEditor(sdf, true);
binder.registerCustomEditor(Date.class, dateEditor);
PhoneDataEditor phoneDataEditor = new PhoneDataEditor();
binder.registerCustomEditor(PhoneNumber.class, phoneDataEditor);
}
}
從上圖中能夠看到綁定命令對象執行方法的順序,實際上是在第三部binder.bind(request)方法中完成數據的綁定,所以在controller中能夠覆寫initBinder()方法,將自定義的「編輯器」註冊,從而完成數據的轉換。測試路徑(http://127.0.0.1:8080/springmvctest/dataBind?type=howareyou&birthday=2012-3-18%2016:48:48&phone=010-12345678)
經過跟蹤源代碼能夠看到,在BeanWrapperImpl的setPropertyValue()方法中綁定命令對象, setPropertyValue方法中有一個convertIfNecessary()方法,convertIfNecessary方法又調用了TypeConverterDelegate的convertIfNecessary()方法,這個方法中真正幹活的是doConvertValue()方法,doConvertValue方法又調用了另一個成員方法doConvertTextValue(),源代碼以下:
protected Object doConvertTextValue(Object oldValue, String newTextValue, PropertyEditor editor) {
try {
editor.setValue(oldValue);
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug("PropertyEditor [" + editor.getClass().getName() + "] does not support setValue call", ex);
}
// Swallow and proceed.
}
editor.setAsText(newTextValue);
return editor.getValue();
}
很容易發現,調用了editor的setAsText()方法,爲何要調用getAsText()方法,經過查看PropertyEditorSupport很容易理解