无法从 String 值构造 java.util.Date 的实例 - 不是有效的表示
Posted
技术标签:
【中文标题】无法从 String 值构造 java.util.Date 的实例 - 不是有效的表示【英文标题】:Can not construct instance of java.util.Date from String value - not a valid representation 【发布时间】:2015-06-05 10:34:45 【问题描述】:抱歉,这似乎是一个多余的问题,但我确实有很多选择, 尽管我努力阅读了十几个线程,但我无法理解该怎么做。
我确实有一个 java 应用程序,它的工作是:
-
从 SOAP WS (XML) 获取数据,
做一些逻辑(传入的deliverydate会变成datebl)
最后将其发送到 REST WS(JSON 格式),这将更新 Oracle 表
因此计划如下:SOAP WS ---- deliverydate ----> JAVA APP (逻辑) ---- datebl -- --> REST WS
JAVA APP中使用的Jar有jackson-core-asl-1.9.13.jar
和jackson-mapper-asl-1.9.13.jar
等。
我遇到的问题是在处理日期时。
读数: (试图受到启发,但杰克逊版本似乎不一样):
JSON Serializing date in a custom format (Can not construct instance of java.util.Date from String value)
Jackson 2.3.2: Issue with deserializing a Date despite of setting the date format to ObjectMapper
编辑 01/04/15
http://jackson-users.ning.com/forum/topics/cannot-deserialize-a-date
现在的事实
第 1 点: 从 SOAP WS 恢复数据时,deliverydate 是一个字符串,其确切值为:
2014-07-31 07:00:00.0
第 2 点: 就在使用 setter 之前,我认为将这个字符串格式化为日期可能是个好主意。
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateebl = dateFormat.parse(deliverydate);
msi.setDatebl(dateebl);
POJO 中的 datebl 声明
private java.util.Date datebl;
在这个阶段,datebl的值已经转化为
2014 年 7 月 31 日星期四 07:00:00 CEST
(尽管选择了特定格式 yyyy-MM-dd HH:mm:ss)
第 3 点和我遇到的错误: 我遇到的错误是由其余服务器引发的:
无法从字符串值 'Thu 构造 java.util.Date 的实例 2014 年 7 月 31 日 07:00:00 CEST':不是有效的表示(错误:不能 解析日期“Thu Jul 31 07:00:00 CEST 2014”:与任何不兼容 标准格式(“yyyy-MM-dd'T'HH:mm:ss.SSSZ”, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", “yyyy-MM-dd”))在 [来源: org.glassfish.jersey.message.internal.EntityInputStream@5709779;线: 1、栏目:74](通过引用链: com.rest.entities.MvtSwapsIn["datebl"])
我想做什么: 为了解决这个问题,因为我使用的是 2.x 之前的版本,我认为我最好的选择是使用自定义序列化程序,所以:
在 pojo 中,注释是在 getter 之前添加的
@JsonSerialize(using = CustomJsonDateSerializer.class)
public java.util.Date getDatebl()
return datebl;
序列化器的创建如下
public class CustomJsonDateSerializer extends JsonSerializer<Date>
@Override
public void serialize(Date value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException
SimpleDateFormat dateFormat = new SimpleDateFormat(Properties.General.FORMAT_HEURE_JSON_SERIALIZE_2);
String dateString = dateFormat.format(value);
jgen.writeString(dateString);
例如,尝试使用 FORMAT_HEURE_JSON_SERIALIZE_2,但尝试了许多其他方法均未成功。
public static final String FORMAT_HEURE_JSON = new String("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static final String FORMAT_HEURE_JSON_SERIALIZE = new String("EEE yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static final String FORMAT_HEURE_JSON_SERIALIZE_2 = new String("EEE, dd MMM yyyy HH:mm:ss zzz");
public static final String FORMAT_HEURE_JSON_SERIALIZE_3 = new String("yyyy-MM-dd HH:mm:ss");
在这一点上,我迷路了。
我不知道在哪里以及如何更新我的代码。
-
从 SOAP ws 获取日期后,我还应该使用 SimpleDateFormat 吗?
鉴于我使用的是jackson 1.9,我的@JsonSerialize 注释好吗? (以及序列化程序?)
我需要修改其他服务器上的某些内容吗?
有人可以帮我整理一下思路吗?
亲切的问候,
皮埃尔
【问题讨论】:
“在这个阶段,datebl 值已转换为 [... string representation ...]” - 不,它已转换为Date
。 Date
对象距离 Unix 纪元只有几毫秒。它没有任何字符串表示的概念作为其状态的一部分。您正在查看调用Date.toString
的结果,它只是使用了一些默认格式。
Tanc,你错过了一些有用的信息。 “例如,用 FORMAT_HEURE_JSON_SERIALIZE_2 尝试过,但尝试了许多其他方法都没有成功。” “没有成功”是什么意思?您此时遇到的确切错误是什么?
感谢 Jon 澄清这一点。蒂姆,很抱歉这么不清楚。我的意思是无论我使用什么日期格式,yyyy-MM-dd'T'HH:mm:ss.SSSZ,EEE yyyy-MM-dd'T'HH:mm:ss.SSSZ, EEE, dd MMM yyyy HH :mm:ss zzz 或 yyyy-MM-dd HH:mm:ss,仍然有相同的其余服务器端错误。 “无法从字符串值构造 java.util.Date 的实例”我什至尝试不使用 @JsonSerialize(using = CustomJsonDateSerializer.class) 并且它仍然在做同样的错误。感谢您的帮助。
【参考方案1】:
打开你的 POJO,像这样注释日期字段声明
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "<your_date_pattern>")
your_date_pattern 可以是这样的
yyyy-MM-dd HH:mm:ss
完成
【讨论】:
+1,我猜你正在使用 Jersey 作为 JAX-RS 实现。您是否从堆栈跟踪中遗漏了一些细节?阅读堆栈跟踪,泽西岛似乎收到了字符串而不是日期:Can not construct instance of java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014'
。如果你的班级com.rest.entities.MvtSwapsIn["datebl"])
声明了一个日期,那么这种行为有点奇怪。
无论如何,要让 Jackson 工作,一个建议是使用 ContextResolver 将 Jackson ObjectMapper 注册到 REST 配置(这适用于 Jackson 1.x 和 2.x)。尝试在构造函数和 getContext() 方法中都设置一个断点,以查看它们是否在运行时被调用:
public class ObjectMapperConfigContextResolver implements ContextResolver<ObjectMapper>
ObjectMapper mapper;
public ObjectMapperConfigContextResolver()
mapper.setDateFormat(new SimpleDateFormat("<your pattern>"));
@Override
public ObjectMapper getContext(Class<?> type)
return mapper;
@Provider 注释应该让 JAX-RS 选择您配置的 ObjectMapper。如果没有,您可以手动完成:
@ApplicationPath("/")
public class RestApplication extends Application
@Override
public Set<Class<?>> getClasses()
Set<Class<?>> classes = new HashSet<>();
classes.add(ObjectMapperConfigContextResolver.class);
return classes;
如果您从 pom.xml 中提供了一些信息(如果您使用的是 Maven),将会很有帮助。
【讨论】:
【参考方案3】:非常感谢吉姆,乔恩。
托马斯。 即使我找到了解决方法,我也会仔细检查你写的内容。
尽管如此,我终于设法解决了这个问题。 由于我无法理解问题是否出在序列化(JavaApp)上,所以我决定看看反序列化(REST WS)的另一面。
快速提醒: SOAP WS ----> JAVA APP ----> REST WS
从 SOAP WS 接收的日期完全是作为字符串接收的,其值为
2014-07-31 07:00:00.0
在JAVA App中,我做到了
DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
DateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = originalFormat.parse(deliverydate);
String formattedDate = targetFormat.format(date);
msi.setDatebl(date);
此时,我仍然有同样的错误,直到我看到发送到 REST WS 的 JSON 是
"id":87434958,"datebl":"Thu Jul 31 07:00:00 CEST 2014","price":15.45,"model":"AAA"
*JSON 对象的某些部分被剪切。
在 REST WS 中,我已将以下内容添加到 pojo (可能其中一个是必要的)并创建了一个自定义反序列化器,如下所示:
@JsonDeserialize(using = CustomJsonDateDeserializer.class)
private java.util.Date datebl;
@JsonDeserialize(using = CustomJsonDateDeserializer.class)
public void setDatebl(java.util.Date datebl)
this.datebl = datebl;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
public class CustomJsonDateDeserializer extends JsonDeserializer<Date>
@Override
public Date deserialize(JsonParser jsonparser,
DeserializationContext deserializationcontext) throws IOException, JsonProcessingException
DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
String dateStr = jsonparser.getText();
try
return (Date)formatter.parse(dateStr);
catch (ParseException e)
throw new RuntimeException(e);
此时,更新已正确完成。在数据库中找到格式正确的日期。
读数: How to convert "Mon Jun 18 00:00:00 IST 2012" to 18/06/2012?
【讨论】:
Jackson 将 setDateFormat 方法作为一种方便的方法,因为它提供了内置的日期序列化程序,因此您不必编写它们:) public ObjectMapper setDateFormat(DateFormat dateFormat) _deserializationConfig = _deserializationConfig.with(dateFormat); _serializationConfig = _serializationConfig.with(dateFormat);返回这个;以上是关于无法从 String 值构造 java.util.Date 的实例 - 不是有效的表示的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型“java.lang.String”的属性值转换为属性“事务”所需的类型“java.util.List”
无法将类型“java.lang.String”的属性值转换为所需类型“java.util.Date”
无法将 java.lang.String 类型的属性值转换为所需的 java.util.Date 类型
无法将 java.lang.String 类型的值转换为所需的 java.util.Date 类型