Spring3MVC 提交请求参数中的日期问题(java.lang.String cant not convert to java.util.Date)

本文介绍了解决Spring MVC中日期类型参数转换的问题,通过两种方法实现:一是修改Spring源码,二是配置自定义日期编辑器。推荐使用第二种方法。
 

Spring3MVC中Controller层接受前端页面的参数有一种情况:

@RequestMapping(value = "/updateStudent.do")
public ModelAndView updateStudent(Student entity) {
	// ...
}


Student 类中有如下两个属性

private String name; // 姓名
private Date registDate; // 入学时间

如果此时想修改入学时间,那么前端页面提交过来的日期必然是'2012-01-17'这样的字符串类型的日期
这个时候传入到服务器端会报一个String转成Date的类型转换错误
如果把private Date registDate改成private String registDate;就没问题
于是看了下Spring3的源码,略微做了下修改:在Spring3的core包下找到

org.springframework.core.convert.support.GenericConversionService.convert(Object, TypeDescriptor, TypeDescriptor);这个方法然后在assertNotNull(sourceType, targetType); 

这个方法然后在assertNotNull(sourceType, targetType); 这句话的下面添加:

if(targetType.getType().getName().equals("java.util.Date")
		 && source instanceof String){
	String date = (String)source;
	try {
		source = YMD_DATETIME_FORMAT.parse(date);
	} catch (ParseException e) {
		try {
			source = YMDHM_DATETIME_FORMAT.parse(date);
		} catch (ParseException e1) {
			try {
				source = YMDHMS_DATETIME_FORMAT.parse(date);
			} catch (ParseException e2) {
				source = null;
			}
		}
	}
	sourceType = targetType;
}

当然还要添加成员变量:

private static final DateFormat	YMD_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private static final DateFormat	YMDHM_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private static final DateFormat	YMDHMS_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

最后重新编译打包core包
这样当遇到Date类型的时候就把数据转换成Date类型的,接下去就不会报错了

 

方法二(推荐):

之后在网上找到一个解决方法:

在配置controller的那个xml中添加如下代码:

<!--  
     	   配置一个基于注解的定制的WebBindingInitializer,解决日期转换问题,方法级别的处理器映射,  
	-->  
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="cacheSeconds" value="0" />  
        <property name="webBindingInitializer">
	           <bean class="WebBinding" /> 
        </property>
    </bean>

这段配置最好放在其它配置的前面


WebBinding:

import java.util.Date;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;

public class WebBinding implements WebBindingInitializer {
	
	@Override
	public void initBinder(WebDataBinder binder, WebRequest request) {
		// 使用spring自带的CustomDateEditor  
		// 解决时间转换问题
		// yyyy-MM-dd
        binder.registerCustomEditor(Date.class, 
        		new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); 
	}
	
	
}


由此可见Spring的扩展性还是蛮强的

 

2025-10-10 14:42:39 ERROR MVCERRORLOG:69 - org.springframework.validation.BeanPropertyBindingResult: 2 errors Field error in object &#39;temuSalesGoodForm&#39; on field &#39;firstOnSalesDurationOfflineDateEnd&#39;: rejected value [2025-09-26T16:00:00.000Z]; codes [typeMismatch.temuSalesGoodForm.firstOnSalesDurationOfflineDateEnd,typeMismatch.firstOnSalesDurationOfflineDateEnd,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [temuSalesGoodForm.firstOnSalesDurationOfflineDateEnd,firstOnSalesDurationOfflineDateEnd]; arguments []; default message [firstOnSalesDurationOfflineDateEnd]]; default message [Failed to convert property value of type &#39;java.lang.String&#39; to required type &#39;java.util.Date&#39; for property &#39;firstOnSalesDurationOfflineDateEnd&#39;; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value &#39;2025-09-26T16:00:00.000Z&#39;; nested exception is java.lang.IllegalArgumentException: 2025-09-26T16:00:00.000Z cant be cast to java.util.Date] Field error in object &#39;temuSalesGoodForm&#39; on field &#39;firstOnSalesDurationOfflineDateStart&#39;: rejected value [2025-09-24T16:00:00.000Z]; codes [typeMismatch.temuSalesGoodForm.firstOnSalesDurationOfflineDateStart,typeMismatch.firstOnSalesDurationOfflineDateStart,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [temuSalesGoodForm.firstOnSalesDurationOfflineDateStart,firstOnSalesDurationOfflineDateStart]; arguments []; default message [firstOnSalesDurationOfflineDateStart]]; default message [Failed to convert property value of type &#39;java.lang.String&#39; to required type &#39;java.util.Date&#39; for property &#39;firstOnSalesDurationOfflineDateStart&#39;; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value &#39;2025-09-24T16:00:00.000Z&#39;; nested exception is java.lang.IllegalArgumentException: 2025-09-24T16:00:00.000Z cant be cast to java.util.Date]
10-11
调用 `getPixels()` 时出现 `java.lang.IllegalStateException: Can&#39;t call getPixels() on a recycled bitmap` 异常,通常是因为尝试访问一个已经被回收的 `Bitmap` 对象的像素数据。在 Android 中,`Bitmap` 对象一旦被回收(即调用了 `recycle()` 方法或被垃圾回收机制自动回收),其内部的像素数据将被释放,此时调用 `getPixels()` 将导致非法状态异常。 ### 原因分析 1. **Bitmap 被手动回收**:如果在代码中显式调用了 `bitmap.recycle()`,并且在之后尝试访问该 `Bitmap` 的像素数据,则会触发此异常。 2. **Bitmap 被自动回收**:在某些情况下,如内存不足时,系统可能会自动回收不再被引用的 `Bitmap` 对象。 3. **资源管理不当**:在异步加载或处理图像时,若未正确管理 `Bitmap` 生命周期,也可能导致访问已被回收的 `Bitmap` [^2]。 ### 解决方法 1. **检查 Bitmap 是否有效**:在调用 `getPixels()` 之前,应先检查 `Bitmap` 是否已经被回收。可以通过 `isRecycled()` 方法判断。 ```java if (!bitmap.isRecycled()) { int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()]; bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); } ``` 2. **避免提前回收 Bitmap**:确保在不再需要 `Bitmap` 时才调用 `recycle()` 方法,避免在仍需访问其像素数据时提前释放资源 [^2]。 3. **使用弱引用管理 Bitmap**:在需要长时间持有 `Bitmap` 的场景中,可以考虑使用 `WeakReference` 来管理,以避免内存泄漏,同时确保在 `Bitmap` 被回收后不会尝试访问其像素数据。 4. **优化资源加载与释放逻辑**:在异步加载图像的场景中,确保在主线程中处理图像数据时,后台加载任务已经完成,并且 `Bitmap` 仍然有效 [^1]。 ### 示例代码 以下是一个检查 `Bitmap` 是否已回收并安全调用 `getPixels()` 的示例: ```java Bitmap bitmap = ...; // 获取 Bitmap 对象 if (bitmap != null && !bitmap.isRecycled()) { int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()]; bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); // 处理像素数据 } else { // 处理 Bitmap 无效的情况 } ``` ### 总结 `IllegalStateException: Can&#39;t call getPixels() on a recycled bitmap` 是由于尝试访问已被回收的 `Bitmap` 的像素数据所致。通过检查 `Bitmap` 的有效性、避免提前回收、优化资源管理逻辑,可以有效解决这一问题
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值