Angular2 Spring boot 日期序列化

4
我正在制作一个带有Angular2前端的REST API。在我的Spring jackson配置中,我设置了这个spring.jackson.date-format=EEE MMM dd yyyy HH:mm:ss zzz (zzzz),因为我使用bootstrap-datepicker插件输出的日期格式如下:Wed May 31 2017 00:00:00 GMT+0200 (W. Europe Daylight Time)。当我尝试将日期提交到一个具有此变量的DTO时,即private Date defaultDatetime;,REST API返回400错误请求。
{"timestamp":"mer. mai 03 2017 14:16:47",
"status":400,
"error":"Bad Request",
"exception":"org.springframework.http.converter.HttpMessageNotReadableException",
"message":"Could not read document: Can not construct instance of java.util.Date from String value '2017-05-01T22:00:00.000Z': not a valid representation (error: Failed to parse Date value '2017-05-01T22:00:00.000Z': Unparseable date: \"2017-05-01T22:00:00.000Z\")\n at [Source: java.io.PushbackInputStream@77b19daf; line: 1, column: 68] (through reference chain: ch.heigvd.form.api.dto.FormDTO[\"fields\"]->java.util.ArrayList[0]->ch.heigvd.form.api.dto.field.DateFieldDTO[\"defaultDate\"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.util.Date from String value '2017-05-01T22:00:00.000Z': not a valid representation (error: Failed to parse Date value '2017-05-01T22:00:00.000Z': Unparseable date: \"2017-05-01T22:00:00.000Z\")\n at [Source: java.io.PushbackInputStream@77b19daf; line: 1, column: 68] (through reference chain: ch.heigvd.form.api.dto.FormDTO[\"fields\"]->java.util.ArrayList[0]->ch.heigvd.form.api.dto.field.DateFieldDTO[\"defaultDate\"])",
"path":"/api/forms"}

你有什么想法关于jackson反序列化时应该输入哪种日期格式?或者我应该直接在前端更改格式?

更新

我通过自定义序列化器使其工作。这是属性文件中的配置:

spring.jackson.date-format=ch.heigvd.form.configuration.CustomJsonDateDeserializer spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

以下是序列化器:

public class CustomJsonDateDeserializer extends ISO8601DateFormat {

    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        toAppendTo.append(format.format(date));
        return toAppendTo;
    }

    @Override
    public Date parse(String source, ParsePosition pos) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        try {
            return format.parse(source);
        } catch (ParseException var4) {
            return null;
        }
    }

}

1
我非常确定boostrsrap-datepicker返回js Date()对象。当您进行后端请求时,它会使JSON.stringify(date),该字符串返回为"2017-05-03T15:07:34.056Z"。同样的内容反映在您收到的错误消息中。因此,请设置Jackson格式以能够解析该格式。 - A. Tim
1个回答

2
你可以选择以下两个选项之一: 选项1: 由于它返回ISOFormat,请编写自己的反序列化器。
@JsonDeserialize(using=CustomerDateAndTimeDeserialize .class)
public class CustomJsonDateDeserializer extends JsonDeserializer<Date>
{
    @Override
    public Date deserialize(JsonParser jsonparser,
            DeserializationContext deserializationcontext) throws IOException, JsonProcessingException {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        String date = jsonparser.getText();
        try {
            return format.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }
}

在每个地方都用注释标记每个setter。
@JsonDeserialize(using = CustomJsonDateDeserializer.class)

选项2:将您的格式更改为与ISO字符串格式相匹配。
spring.jackson.date-format=YYYY-MM-dd'T'HH:mm:ss.SSS'Z'

我尝试了选项2,但一开始仍然出现错误。我将属性编辑为spring.jackson.date-format=YYYY-MM-dd'T'HH:mm:ss.SSS'Z',现在似乎可以工作了。谢谢! - Elbbard
我刚刚意识到Jackson反序列化的日期与给定的日期不同。当前端发送“2017-05-16T22:00:00.000Z”时,它总是将其反序列化为“2017-01-02T23:00:00.000Z”。我应该尝试选项1吗? - Elbbard
@Servietsky:很奇怪,是的,选项1是完美的:)。我也会尝试复制您的问题。 - Parth Ghiya
我如何将选项1应用于每个类。我将反序列化的每个日期都具有相同的格式。 - Elbbard
我使用了某种自定义序列化程序,现在它可以工作了。我还将YYYY替换为yyyy,不知道是否有所改变。你可以在我的原始帖子中看到它。 - Elbbard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接