无法从 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.jarjackson-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 ...]” - 不,它已转换为 DateDate 对象距离 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, 也可以是任何日期格式,例如:dd-MM-yyyy,JsonFormat 将转换为 DB 可接受的格式,如“yyyy-MM-dd”【参考方案2】:

我猜你正在使用 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 类型

Spring - 无法将java.lang.String类型的属性值转换为必需类型java.util.Date

import java.util.Random; 构造函数来取随机数