How does the Spring MVC determine the type of a given request parameter

http://stackoverflow.com/questions/3705282/spring-mvc-binding-a-date-field
up vote 58 down vote accepted

How does the Spring MVC determine the type of a given request parameter ?

Spring makes use of ServletRequestDataBinder to bind its values. The process can be described as follows

/**
  * Bundled Mock request
  */
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("name", "Tom");
request.addParameter("age", "25");

/**
  * Spring create a new command object before processing the request
  *
  * By calling <COMMAND_CLASS>.class.newInstance(); 
  */
Person person = new Person();

...

/**
  * And Then with a ServletRequestDataBinder, it bind the submitted values
  * 
  * It makes use of Java reflection To bind its values
  */
ServletRequestDataBinder binder = ServletRequestDataBinder(person);
binder.bind(request);

Behind the scenes, DataBinder instances internally makes use of a BeanWrapperImpl instance which is responsible for set up the values of the command object. With getPropertyType method, it retrieves the property type

If you see the submitted request above (of course, by using a mock), Spring will call

BeanWrapperImpl beanWrapper = new BeanWrapperImpl(person);

Clazz requiredType = beanWrapper.getPropertyType("name");

And Then

beanWrapper.convertIfNecessary("Tom", requiredType, methodParam)

How does Spring MVC container bind a request parameter representing a Date ?

If you have human-friendly representation of data which needs special conversion, you must register a PropertyEditor For instance, java.util.Date does not know what 13/09/2010 is, so you tell Spring

Spring, convert this human-friendly date by using the following PropertyEditor

binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
    public void setAsText(String value) {
        try {
            setValue(new SimpleDateFormat("dd/MM/yyyy").parse(value));
        } catch(ParseException e) {
            setValue(null);
        }
    }

    public String getAsText() {
        return new SimpleDateFormat("dd/MM/yyyy").format((Date) getValue());
    }        

});

When calling convertIfNecessary method, Spring looks for any registered PropertyEditor which takes care of converting the submitted value. To register your PropertyEditor, you can either

Spring 3.0

@InitBinder
public void binder(WebDataBinder binder) {
    // as shown above
}

Old-style Spring 2.x

@Override
public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
    // as shown above
}
share improve this answer
 
 
Thank you so much. –  Tom Tucker  Sep 14 '10 at 5:25
1 
Spring 2.5.x has a @InitBinder as well: static.springsource.org/spring/docs/2.5.x/reference/… –  Rihards  Mar 27 '11 at 0:20
1 
Thank you because this seems to be a comprehensive answer but for the non-experts it would really help to include a simple practical example. –  Marquez  Dec 12 '12 at 15:15
 
Thanks! very clear. but I want to know how to let this code global, not limit to one controller. And if could also use Converter to implement this? –  zhuguowei  Apr 6 at 2:42
 
@zhuguowei Thank you! See stackoverflow.com/a/1454877 –  Arthur Ronald  Apr 11 at 15:52

In complement to Arthur's very complete answer : in the case of a simple Date field, you don't have to implement the whole PropertyEditor. You can just use a CustomDateEditor to which you simply pass the date format to use :

//put this in your Controller 
//(if you have a superclass for your controllers 
//and want to use the same date format throughout the app, put it there)
@InitBinder
private void dateBinder(WebDataBinder binder) {
            //The date format to parse or output your dates
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
            //Create a new CustomDateEditor
    CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
            //Register it as custom editor for the Date type
    binder.registerCustomEditor(Date.class, editor);
}
share improve this answer
 
 
Adding some comments to your code will help the OP to understand your answer proposal. Check thismetaSO question and Jon Skeet: Coding Blog on how to give a correct answer. –  Yaroslav  Dec 27 '12 at 10:29 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值