Spring MVC - Binding a Date Field

前端 未结 2 1885
傲寒
傲寒 2020-11-30 20:32

For request parameters representing string, number, and boolean values, the Spring MVC container can bind them to typed properties out of the box.

How do you have th

相关标签:
2条回答
  • 2020-11-30 21:12

    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 binds the submitted values
      * 
      * It makes use of Java reflection To bind its values
      */
    ServletRequestDataBinder binder = new 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
    }
    
    0 讨论(0)
  • 2020-11-30 21:33

    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);
    }
    
    0 讨论(0)
提交回复
热议问题