Sunday, December 19, 2010

spring的属性编辑器CustomDateEditor及日期对象转化

在spring mvc的Controller中,属性在通过依赖注入(DI)时,普通数据类型都能够辨识。但诸如Date之类,就需要自定义属性编辑器解决。否则报如下错误:
org.springframework.beans.TypeMismatchException:
Failed to convert property value of type [java.lang.String] to required type
[java.util.Date] for property 'date'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'date': no matching editors or conversion strategy found
这表示spring无法找到合适的转换策略,需要自己写一个转换器,在spring中称之为属性编辑器。
spring中的属性编辑器可以将字符串转换为相应的对象,然后注入到其它对象中去。
编写自己的属性编辑器的步骤很简单,属性编辑器类需要从java.beans.PropertyEditorSupport类继承,在这个类中有一个setAsText方法,这个方法有一个String类型的参数,通过这个方法,可以将String类型的参数值转换成其他类型的属性。在这个方法中我们还需要使用一个setValue方法,就来指定转换后的对象实例。
spring 中有个 CustomDateEditor 的类就是继承 PropertyEditorSupport 的一个属性编辑器,在Controller中添加一个@InitBinder的Annotation到某个方法上,在方法中指明日期字符串的格式,就可以将符合此格式的字符串转化为日期对象,代码如下:


/**
* <pre>
* HTML forms work with string values only, when your Authority is a complex bean. You need to configure a PropertyEditor to perform conversion between Authority and String:
*
* @InitBinder
* public void initBinder(WebDataBinder b) {
* b.registerCustomEditor(Authority.class, new AuthorityEditor());
* }
*
* private class AuthorityEditor extends PropertyEditorSupport {
* @Override
* public void setAsText(String text) throws IllegalArgumentException {
* // 另外一个例子是根据字符串,从数据库中查找返回对象
* setValue(authorityService.findById(Long.valueOf(text)));
* }
*
* @Override
* public String getAsText() {
* return ((Authority) getValue()).getId();
* }
* }
* </pre>
*
* 这个方法用来将页面表单上传的Date字符串转化成java的Date对象
*
* @param binder
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}


Reference: how to pass a date into bean property

comments bug on firefox


<body>
<!--

这段HTML注释代码因为中间多了2个连字符,在firefox中会导致解析出错,这段内容被做为正常的文本内容显示在浏览器中。
This entire comment -- will show in web browser

-->
</body>

Reference: (SGMLComment) Mozilla interprets a -- (two dashes in a row) inside of a comment or an include improperly

javascript中array方法调用返回window对象

array中的很多方法通过call和apply调用时会返回window对象,如下写法在Firefox、Chrome等浏览器中会取到window对象:


window === ([]).sort.call();
window === ([]).reverse.call();
([]).concat.call()[0] === window


可以将这些array的方法重写,避免它在运行时的this指向window,如重写sort方法:

Array.prototype.sort = (function(sort) { return function(callback) {
return (this == window) ? null : (callback ? sort.call(this, function(a,b) {
return callback(a,b)}) : sort.call(this));
}})(Array.prototype.sort);