Springmvc(2)命令對象的綁定


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很容易理解

相關文章
相關標籤/搜索