【问题标题】:Spring MVC - Binding a Date FieldSpring MVC - 绑定日期字段
【发布时间】:2011-04-11 22:35:46
【问题描述】:

对于表示字符串、数字和布尔值的请求参数,Spring MVC 容器可以将它们绑定到开箱即用的类型化属性。

如何让 Spring MVC 容器绑定代表日期的请求参数?

说到这里,Spring MVC是如何判断给定请求参数的类型的?

谢谢!

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    Spring MVC 如何确定给定请求参数的类型?

    Spring 使用ServletRequestDataBinder 绑定其值。过程可以描述如下

    /**
      * 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);
    

    在幕后,DataBinder 实例在内部使用 BeanWrapperImpl 实例,该实例负责设置命令对象的值。使用getPropertyType方法,获取属性类型

    如果你看到上面提交的请求(当然是使用mock),Spring会调用

    BeanWrapperImpl beanWrapper = new BeanWrapperImpl(person);
    
    Clazz requiredType = beanWrapper.getPropertyType("name");
    

    然后

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

    Spring MVC容器如何绑定代表Date的请求参数?

    如果你有人类友好的数据表示需要特殊转换,你必须注册一个PropertyEditor 例如,java.util.Date 不知道 13/09/2010 是什么,所以你告诉 Spring

    春天,使用下面的 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());
        }        
    
    });
    

    当调用 convertIfNecessary 方法时,Spring 会查找任何已注册的 PropertyEditor,它负责转换提交的值。要注册您的 PropertyEditor,您可以

    春季 3.0

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

    旧式 Spring 2.x

    @Override
    public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
        // as shown above
    }
    

    【讨论】:

    • Spring 2.5.x 也有一个@InitBinder:static.springsource.org/spring/docs/2.5.x/reference/…
    • 谢谢,因为这似乎是一个全面的答案,但对于非专家来说,包含一个简单的实际示例真的很有帮助。
    • 谢谢!非常清楚。但我想知道如何让这段代码全局化,而不是仅限于一个控制器。是否也可以使用Converter 来实现?
    • @ArthurRonald 非常感谢!
    • 耶稣!到 2021 年,这仍然是原始状态吗?
    【解决方案2】:

    作为对 Arthur 非常完整答案的补充:对于简单的 Date 字段,您不必实现整个 PropertyEditor。您可以只使用 CustomDateEditor ,您只需将日期格式传递给它即可使用:

    //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);
    }
    

    【讨论】:

    猜你喜欢
    • 2014-07-26
    • 2016-11-14
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多