项目使用 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页面部分代码(表单中)如下 :

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;/*** * 日期转换器.
用于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.DateConverterjava.sql.Timestamp=com.common.convert.DateConverter

参考: