Home > Net >  Instant incorrectly parsing epoch string with rest api
Instant incorrectly parsing epoch string with rest api

Time:01-29

I have a rest API with an input value which is an epoch. However, storing as an Instant ignores the nanos, thus storing it as some date in the future (I think). I could be storing them in the wrong type also as had thought about storing them as a long either.

Example: The input of 683124845000 is converted to 23617-05-13T13:23:20Z

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

The JSON input is:

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

Currently, I just have a controller that returns OK regardless of input as I am modeling the input.

@PostMapping("/booking")
    public ResponseEntity createBooking(@RequestBody Booking booking) {
        return ResponseEntity.ok().build();
    }

CodePudding user response:

To store the epoch value correctly, you can change the data type of the epoch field in the Booking class to long.

Example:

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

Then in the controller, you can convert the string value from the request body to a long using Long.parseLong() method.

Example:

@PostMapping("/booking")
public ResponseEntity createBooking(@RequestBody Booking booking) {
booking.setEpoch(Long.parseLong(booking.getEpoch()));
return ResponseEntity.ok().build();
}

CodePudding user response:

The default Instant serializer is expecting the epoch to be in seconds. Here are the following solutions:

  1. Use long or Long to store the epoch.
  2. Change your API to expect seconds.
  3. Create custom serializer / deserializer.

Custom serializer / deserializer implementation:
(Assuming you want to use milliseconds for your API since the epoch in the question seemed to be in milliseconds)

Serializer

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

}

Deserializer

public class CustomInstantDeserializer extends JsonDeserializer<Instant> {

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

}

Then wiring the serializer / deserializer to the field:

public class Booking {

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

    private String email;

}
  • Related