使用 rest api 即时错误地解析纪元字符串 [closed]

Instant incorrectly parsing epoch string with rest api [closed]

提问人:Droid_Interceptor 提问时间:1/29/2023 最后编辑:AnonymousDroid_Interceptor 更新时间:1/29/2023 访问量:169

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将有助于其他人回答这个问题。

10个月前关闭。

我有一个 rest API,其输入值是一个纪元。但是,存储为 Instant 会忽略纳米,从而将其存储为将来的某个日期(我认为)。我也可能将它们存储在错误的类型中,因为也考虑过将它们存储为长期。

例: 根据683124845000输入,我期待 1991 年的日期和时间。它被转换为 +23617-05-13T13:23:20Z。

public class Booking {
    private Instant epoch;
    private String email;
}

JSON 输入为:

{
  "epoch": "683124845000", 
  "email": "[email protected]"
}

目前,我只有一个控制器,在我对输入进行建模时,无论输入如何,它都会返回 OK。

@PostMapping("/booking")
    public ResponseEntity createBooking(@RequestBody Booking booking) {
        return ResponseEntity.ok().build();
    }
java spring-boot rest 纪元 java.time.instant

评论

1赞 Anonymous 1/29/2023
683124845000的预期结果是什么?问是因为这个数字看起来很有趣,它是否应该表示今年或去年的一个时间点。如果自纪元以来的毫秒数,则表示 1991-08-25T12:54:05Z。是这样吗?
0赞 Droid_Interceptor 1/29/2023
1991年的时间是预期的时间。它来自一个随机生成的毫秒纪元

答:

0赞 Razib 1/29/2023 #1

若要正确存储纪元值,可以将 Booking 类中纪元字段的数据类型更改为 long。

例:

public class Booking {
private long epoch;
private String email;
}

然后在控制器中,您可以使用 Long.parseLong() 方法将请求正文中的字符串值转换为长字符串值。

例:

@PostMapping("/booking")
public ResponseEntity createBooking(@RequestBody Booking booking) {
booking.setEpoch(Long.parseLong(booking.getEpoch()));
return ResponseEntity.ok().build();
}
1赞 origeva 1/29/2023 #2

默认的即时序列化程序期望纪元以秒为单位。 以下是以下解决方案:

  1. 使用 long 或 long 来存储纪元。
  2. 将 API 更改为需要几秒钟。
  3. 创建自定义序列化程序/反序列化程序。

自定义序列化程序/反序列化程序实现:
(假设您想对 API 使用毫秒,因为问题中的纪元似乎是以毫秒为单位)

序列化程序

public class CustomInstantSerializer extends JsonSerializer<Instant> {

    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        long epoch = value.toEpochMilli();
        gen.writeNumber(epoch);
    }

}

解串器

public class CustomInstantDeserializer extends JsonDeserializer<Instant> {

    @Override
    public Instant deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        long epoch = jp.getLongValue();
        return Instant.ofEpochMilli(epoch);
    }

}

然后将串行器/解串器连接到现场:

public class Booking {

    @JsonSerialize(using = CustomInstantSerializer.class)
    @JsonDeserialize(using = CustomInstantDeserializer.class)
    private Instant epoch;

    private String email;

}