无法从字符串值构造 java.util.Date 的实例 - 不是有效的表示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29379623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:53:36  来源:igfitidea点击:

Can not construct instance of java.util.Date from String value - not a valid representation

javadateHymansonserializer

提问by Tanc

Sorry for what it seems to be a redundant question but i do have many options, and despite my effort reading dozen of threads, i'm not able to understand what to do.

抱歉,这似乎是一个多余的问题,但我确实有很多选择,尽管我努力阅读了几十个线程,但我还是不明白该怎么做。

I do have a java application which job is to :

我确实有一个 Java 应用程序,它的工作是:

  1. get datas from a SOAP WS (XML),
  2. do some logic ( incoming deliverydate will become datebl )
  3. Finally send it to a REST WS (JSON Format), which will update an Oracle Table
  1. 从 SOAP WS (XML) 获取数据,
  2. 做一些逻辑(传入的交付日期将成为 datebl )
  3. 最后将其发送到 REST WS(JSON 格式),它将更新 Oracle 表

Plan is thus as follows :
SOAP WS---- deliverydate ----> JAVA APP(logic) ---- datebl ----> REST WS

因此计划如下:
SOAP WS---- deliverydate ----> JAVA APP(逻辑)---- datebl ----> REST WS

Jar used in JAVA APP are Hymanson-core-asl-1.9.13.jarand Hymanson-mapper-asl-1.9.13.jaramong others.

在Java应用程序是使用的JARHymanson-core-asl-1.9.13.jarHymanson-mapper-asl-1.9.13.jar等等。

Issues i have is when dealing with dates.

我遇到的问题是在处理日期时。

Readings : ( Tried to be inspired but Hymanson version seems not to be the same ) :

阅读:(试图受到启发,但Hyman逊版本似乎不一样):

JSON Serializing date in a custom format (Can not construct instance of java.util.Date from String value)

JSON 以自定义格式序列化日期(无法从字符串值构造 java.util.Date 的实例)

Hymanson 2.3.2: Issue with deserializing a Date despite of setting the date format to ObjectMapper

Hymanson 2.3.2:尽管将日期格式设置为 ObjectMapper,但反序列化日期仍存在问题

Edit 01/04/15

编辑 01/04/15

http://Hymanson-users.ning.com/forum/topics/cannot-deserialize-a-date

http://Hymanson-users.ning.com/forum/topics/cannot-deserialize-a-date

The facts now

现在的事实

Point 1 :When recovering data from SOAP WS, deliverydate is a String which exact value is :

第 1 点:从 SOAP WS 恢复数据时,deliverydate 是一个字符串,其确切值为:

2014-07-31 07:00:00.0

2014-07-31 07:00:00.0

Point 2:Just before using the setter, i thought it could be a good idea to format this String to a date.

第 2 点:就在使用 setter 之前,我认为将此 String 格式化为日期可能是个好主意。

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    Date dateebl = dateFormat.parse(deliverydate);
                                    msi.setDatebl(dateebl);

datebl declaration in POJO

POJO 中的 datebl 声明

private java.util.Date    datebl;

At this stage, datebl value has transformed to

在这个阶段,datebl 值已经转化为

Thu Jul 31 07:00:00 CEST 2014

2014 年 7 月 31 日星期四 07:00:00 CEST

(despite choosing the specific format yyyy-MM-dd HH:mm:ss)

(尽管选择了特定格式 yyyy-MM-dd HH:mm:ss)

Point 3 and ERROR i have :The error i have is thrown by the rest server:

第 3 点和我遇到的错误:我遇到的错误是由其余服务器抛出的:

Can not construct instance of java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014': not a valid representation (error: Can not parse date "Thu Jul 31 07:00:00 CEST 2014": not compatible with any of standard forms ("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")) at [Source: org.glassfish.jersey.message.internal.EntityInputStream@5709779; line: 1, column: 74] (through reference chain: com.rest.entities.MvtSwapsIn["datebl"])

无法从字符串值 'Thu Jul 31 07:00:00 CEST 2014' 构造 java.util.Date 的实例:不是有效表示(错误:无法解析日期“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"])

What i tried to do :To resolve this, as i'm using a version prior to 2.x, i thought that my best option was to use a custom serializer, so :

我试图做的是:为了解决这个问题,因为我使用的是 2.x 之前的版本,我认为我最好的选择是使用自定义序列化程序,所以:

  • In pojo, annotation was added just before the getter

    @JsonSerialize(using = CustomJsonDateSerializer.class)
        public java.util.Date getDatebl() {
            return datebl;
        }
    
  • Serializer was created as follows

    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);       
    }
    

    }

  • 在 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);       
    }
    

    }

In example,tried with FORMAT_HEURE_JSON_SERIALIZE_2, but tried many others without success.

例如,尝试使用 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");

At this point, i'm lost.

在这一点上,我迷路了。

I don't know where and how to update my code.

我不知道在哪里以及如何更新我的代码。

  1. Should i still use SimpleDateFormat after getting date from SOAP ws ?
  2. Given the fact i'm using Hymanson 1.9, is my @JsonSerialize annotation good ? ( as well as the serializer ?)
  3. Do i have to modify something on the rest server ?
  1. 从 SOAP ws 获取日期后,我还应该使用 SimpleDateFormat 吗?
  2. 鉴于我使用的是 Hymanson 1.9,我的 @JsonSerialize 注释好吗?(以及序列化器?)
  3. 我是否必须在其余服务器上修改某些内容?

Please can someone help me organize my thoughts ?

请问有人能帮我整理一下思路吗?

Kind regards,

亲切的问候,

Pierre

皮埃尔

回答by thomas77

I guess you are using Jersey as a JAX-RS implementation. Have you left some details out from the stacktrace? Reading the stacktrace it seems the Jersey receives a String instead of a Date: Can not construct instance of java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014'. If your class com.rest.entities.MvtSwapsIn["datebl"])declares a date, this behaviour is a bit strange.

我猜您正在使用 Jersey 作为 JAX-RS 实现。您是否从堆栈跟踪中遗漏了一些细节?阅读堆栈跟踪似乎 Jersey 收到一个 String 而不是 Date: Can not construct instance of java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014'。如果您的类com.rest.entities.MvtSwapsIn["datebl"])声明了日期,则这种行为有点奇怪。

Anyway, for Hymanson to work, one suggestion is to register a Hymanson ObjectMapper to the REST config with a ContextResolver (this applies to both Hymanson 1.x and 2.x). Try putting a breakpoint in both the constructor and getContext()-method to see if they are invoked at runtime:

无论如何,为了让 Hymanson 工作,一个建议是使用 ContextResolver 将 Hymanson ObjectMapper 注册到 REST 配置(这适用于 Hymanson 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;
}

}

}

The @Provider annotation should make JAX-RS pick up your configured ObjectMapper. If no you can do it manually:

@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;
    }
}

It would be helpful if you provided some information from your pom.xml (if you are using Maven).

如果您从 pom.xml 中提供了一些信息(如果您使用的是 Maven),那将会很有帮助。

回答by Tanc

Thanks a lot Jim, Jon.

非常感谢吉姆,乔恩。

Thomas. Even if i found a workaround, i will check what you wrote carefully.

托马斯。即使我找到了解决方法,我也会仔细检查您写的内容。

Nevertheless,i finally managed to solve this. As i was not able to understand if problem was on Serialization(JavaApp) i've decided to have a look on the other side Deserialization(REST WS).

尽管如此,我终于设法解决了这个问题。因为我无法理解问题是否出在序列化(JavaApp)上,所以我决定看看另一端的反序列化(REST WS)。

Quick reminder :SOAP WS ----> JAVA APP ----> REST WS

快速提醒:SOAP WS ----> JAVA APP ----> REST WS

Date received from SOAP WS was exactly received as String, its value was

从 SOAP WS 接收的日期被准确地作为字符串接收,其值为

2014-07-31 07:00:00.0

2014-07-31 07:00:00.0

Within JAVA App, i did

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);

At this point, i had still the same error until i saw that JSON sent to REST WS was

在这一点上,我仍然有同样的错误,直到我看到 JSON 发送到 REST WS 是

{"id":87434958,"datebl":"Thu Jul 31 07:00:00 CEST 2014","price":15.45,"model":"AAA"}

*Some parts of JSON Object were cutted.

* JSON Object 的部分内容被删减。

Within REST WS, i've added the following to the pojo (Probably one of them is necessary) and created a custom deserializer as follows :

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.Hymanson.JsonParser;
import org.codehaus.Hymanson.JsonProcessingException;
import org.codehaus.Hymanson.map.DeserializationContext;
import org.codehaus.Hymanson.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);
        }

    }
}

At this point, update has been done properly. Date was found in database in a proper format.

至此,更新已正常完成。在数据库中以正确的格式找到日期。

Readings :How to convert "Mon Jun 18 00:00:00 IST 2012" to 18/06/2012?

阅读:如何将“Mon Jun 18 00:00:00 IST 2012”转换为 18/06/2012?

回答by Christopher Kikoti

Open your POJO, annotate the date field declaration like so

打开你的 POJO,像这样注释日期字段声明

@JsonFormat
  (shape = JsonFormat.Shape.STRING, pattern = "<your_date_pattern>")

Where your_date_pattern can be something like

your_date_pattern 可以是这样的

yyyy-MM-dd HH:mm:ss

Done

完毕