首页 > 代码库 > Struts2中转换Date类型的问题

Struts2中转换Date类型的问题

项目使用 strut2 ,spring,hibernate,提交表单时报错

java.lang.NoSuchMethodException: com.shop.jn.entity.Goods.setBuyDateTime([Ljava.lang.String;)]

异常详细信息:

11:23:30,113  WARN  - Error setting expression ‘goods.buyDateTime‘ with value ‘[Ljava.lang.String;@109558d‘
ognl.MethodFailedException: Method "setBuyDateTime" failed for object Goods [id=0, name=null, description=null] [java.lang.NoSuchMethodException: com.shop.jn.entity.Goods.setBuyDateTime([Ljava.lang.String;)]
	at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1289)
	at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:1478)
	at ognl.ObjectPropertyAccessor.setPossibleProperty(ObjectPropertyAccessor.java:85)
	at ognl.ObjectPropertyAccessor.setProperty(ObjectPropertyAccessor.java:162)
	at com.opensymphony.xwork2.ognl.accessor.ObjectAccessor.setProperty(ObjectAccessor.java:27)
	at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2315)
	at ognl.ASTProperty.setValueBody(ASTProperty.java:127)
	at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
	at ognl.SimpleNode.setValue(SimpleNode.java:301)
	at ognl.ASTChain.setValueBody(ASTChain.java:227)
	at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
	at ognl.SimpleNode.setValue(SimpleNode.java:301)
	at ognl.Ognl.setValue(Ognl.java:737)
	at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:217)
	at com.opensymphony.xwork2.ognl.OgnlValueStack.trySetValue(OgnlValueStack.java:186)
	at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:173)
	at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:151)
	at com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:317)
	at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:228)
	at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:236)
	at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:90)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
	at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:192)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
	at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
	at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:511)
	at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
	at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NoSuchMethodException: com.shop.jn.entity.Goods.setBuyDateTime([Ljava.lang.String;)
	at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1230)
	... 68 more
/-- Encapsulated exception ------------java.lang.NoSuchMethodException: com.shop.jn.entity.Goods.setBuyDateTime([Ljava.lang.String;)

JSP页面部分代码(表单中)如下 :

<s:hidden name="goods.buyDateTime"></s:hidden>

goods对应的实体类(部分getter,setter方法已省略):

package com.shop.jn.entity;

import java.io.Serializable;
import java.util.Date;

/**
 * entity:goods
 * @author huangwei
 *
 */
public class Goods  implements Serializable{
	private static final long serialVersionUID = 586940311263079808L;
	private int id;
	/**
	 * goods name
	 */
	private String name;
	/**
	 * alias of goods
	 */
	private String alias;
	/**
	 * when goods was brought
	 */
	private Date buyDateTime;
	/**
	 * when this record was modified
	 */
	private Date latestModDateTime;
	/**
	 * the price of goods
	 */
	private double price;
	/**
	 * the detail of the goods
	 */
	private String description;
	/**
	 * the supermarket the goods belong
	 */
	private Supermarket supermarket;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAlias() {
		return alias;
	}
	public void setAlias(String alias) {
		this.alias = alias;
	}

	
	public Date getLatestModDateTime() {
		return latestModDateTime;
	}
	public void setLatestModDateTime(Date latestModDateTime) {
		this.latestModDateTime = latestModDateTime;
	}
	
	
	public Date getBuyDateTime() {
		return buyDateTime;
	}
	public void setBuyDateTime(Date buyDateTime) {
		System.out.println("buyDateTime:"+buyDateTime);
		this.buyDateTime=buyDateTime;
	}
	
	
}

 实体类中buyDateTime 的类型是java.util.Date

使用IE浏览器有问题,但是使用google浏览器没问题。

IE的locale是en_US,见下图:



 

原因到底是什么呢?因为在火狐和谷歌浏览器中没问题啊

最后发现是IE浏览器的语言环境是英文

 把语言调整为中文就OK 了.

针对这个问题,我们没法要求客户一定设置中文为默认浏览器的语言环境。因而对于Date类型的转换,可以自己定义一个转换器。

package com.common.convert;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;

import ognl.DefaultTypeConverter;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;
/***
 * 日期转换器.<br>用于struts2
 * 
 * @author huangwei
 *
 */
public class DateConverter extends DefaultTypeConverter {
	private static final Logger logger = Logger.getLogger(DateConverter.class);

	private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
	private static final String DATETIME_PATTERN_NO_SECOND = "yyyy-MM-dd HH:mm";
	private static final String DATETIME_PATTERN_ZH ="yyyy年MM月dd日 HH点mm分ss秒";
	private static final String DATETIME_PATTERN_ZH2 ="yyyy年MM月dd日 HH时mm分ss秒";
	private static final String DATE_PATTERN = "yyyy-MM-dd";

	private static final String MONTH_PATTERN = "yyyy-MM";

	/**
	 * Convert value between types
	 */
	@SuppressWarnings("unchecked")
	public Object convertValue(Map ognlContext, Object value, Class toType) {
		Object result = null;
		// java.sql.Date 是java.util.Date 的子类
		if (toType == java.util.Date.class) {
			try {
				result = doConvertToDate(value,  toType);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else if (toType == java.sql.Timestamp.class) {
			try {
				java.util.Date date=doConvertToDate(value, toType);
				result = new Timestamp(date.getTime());
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else if (toType == String.class) {
			result = doConvertToString(value);
		}
		return result;
	}

	/**
	 * Convert String to Date
	 * 
	 * @param value
	 * @return
	 * @throws ParseException
	 */
	private java.util.Date doConvertToDate(Object value,Class toType) throws ParseException {
		java.util.Date result = null;

		if (value instanceof String) {
			result = DateUtils.parseDate((String) value, new String[] {DATETIME_PATTERN,
					DATE_PATTERN,  MONTH_PATTERN 
					,DATETIME_PATTERN_NO_SECOND,DATETIME_PATTERN_ZH,DATETIME_PATTERN_ZH2});
//			if(toType==java.sql.Timestamp.class){
//				result=new java.sql.Timestamp(result.getTime());
//			}
			// all patterns failed, try a milliseconds constructor
			if (result == null && StringUtils.isNotEmpty((String) value)) {

				try {
					result = new Date(new Long((String) value).longValue());
				} catch (Exception e) {
					logger.error("Converting from milliseconds to Date fails!");
					e.printStackTrace();
				}

			}

		} else if (value instanceof Object[]) {
			// let‘s try to convert the first element only
			Object[] array = (Object[]) value;

			if ((array != null) && (array.length >= 1)) {
				value = array[0];
				result = doConvertToDate(value,toType);
			}

		} else if (Date.class.isAssignableFrom(value.getClass())) {
			result = (Date) value;
		}
		return (java.util.Date)result;
	}

	/**
	 * Convert Date to String
	 * 
	 * @param value
	 * @return
	 */
	private String doConvertToString(Object value) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				DATETIME_PATTERN);
		String result = (String)value;
		if (value instanceof Date) {
			result = simpleDateFormat.format(value);
		}
		return result;
	}
}

可以将该转换器注册为全局的:在classpath下建立xwork-conversion.properties文件,内容为:java.util.Date=你的类型转换器的完整限定类名

xwork-conversion.properties 内容如下:

java.util.Date=com.common.convert.DateConverter
java.sql.Timestamp=com.common.convert.DateConverter

参考:

date java.lang.IllegalArgumentException: argument type mismatch 

【转】Struts2中转换Date类型的问题 


Struts2中转换Date类型的问题