无法从String值构造java.util.Date的实例 - 不是有效的表示形式

时间:2015-03-31 22:23:53

标签: java date jackson serializer

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

我有一个java应用程序,其工作是:

  1. 从SOAP WS(XML)获取数据,
  2. 做一些逻辑(传入的deliverydate将成为datebl)
  3. 最后将其发送到REST WS(JSON格式),它将更新Oracle表
  4. 计划如下:
         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是一个String,其精确值为:

      

    2014-07-31 07:00:00.0

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

    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值已转换为

      

    Thu Jul 31 07:00:00 CEST 2014

    (尽管选择具体格式yyyy-MM-dd HH:mm:ss)

    第3点和ERROR我有: 我有的错误是由其他服务器抛出的:

      

    无法从String value' Thu构造java.util.Date的实例   7月31日07:00:00 CEST 2014':不是有效的陈述(错误:不能   解析日期" Thu Jul 31 07:00:00 CEST 2014":与任何一个不兼容   标准形式(" yyyy-MM-dd' T' HH:mm:ss.SSSZ",   " yyyy-MM-dd' HH:mm:ss.SSS' Z'"," EEE,dd MMM yyyy HH:mm:ss zzz& #34 ;,   " 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;
          }
      
    • Serializer创建如下

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

    此时,我迷路了。

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

    1. 从SOAP ws获取日期后我还应该使用SimpleDateFormat吗?
    2. 鉴于我使用的是jackson 1.9,我的@JsonSerialize注释是否合适? (以及序列化器?)
    3. 我是否必须修改其余服务器上的内容?
    4. 有人可以帮我组织一下我的想法吗?

      亲切的问候,

      皮尔

3 个答案:

答案 0 :(得分:7)

打开您的POJO,注明日期字段声明,如此

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

your_date_pattern可以是

yyyy-MM-dd HH:mm:ss

完成

答案 1 :(得分: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),将会很有帮助。

答案 2 :(得分:0)

非常感谢Jim,Jon。

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

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

快速提醒: SOAP WS ----&gt; JAVA APP ----&gt; REST WS

从SOAP WS收到的日期完全收到String,其值为

  

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?