【发布时间】:2011-04-11 22:35:46
【问题描述】:
对于表示字符串、数字和布尔值的请求参数,Spring MVC 容器可以将它们绑定到开箱即用的类型化属性。
如何让 Spring MVC 容器绑定代表日期的请求参数?
说到这里,Spring MVC是如何判断给定请求参数的类型的?
谢谢!
【问题讨论】:
标签: java spring spring-mvc
对于表示字符串、数字和布尔值的请求参数,Spring MVC 容器可以将它们绑定到开箱即用的类型化属性。
如何让 Spring MVC 容器绑定代表日期的请求参数?
说到这里,Spring MVC是如何判断给定请求参数的类型的?
谢谢!
【问题讨论】:
标签: java spring spring-mvc
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
}
【讨论】:
Converter 来实现?
作为对 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);
}
【讨论】: