Spring Boot项目中Instant类型时间戳JSON解析异常求助
Hey there! I totally get why you're using Instant for your timestamp field—handling Duration operations is way cleaner with Java 8's time API, and that's a great choice. The issue here is that Spring Boot's default Jackson setup expects Instant values to be in ISO-8601 string format (like "2024-05-20T14:30:00Z"), but your frontend is sending a numeric long timestamp instead. Let's fix this step by step.
Solution 1: Global Jackson Configuration for Long Timestamps
If your frontend is sending millisecond-level timestamps (the most common case), you can configure Jackson globally to automatically convert long values to Instant.
Option A: Using application.yml
Add these settings to your application.yml (or equivalent .properties file):
spring: jackson: modules: java.time deserialization: adjust-dates-to-context-time-zone: false read-date-timestamps-as-nanoseconds: false serialization: write-date-timestamps-as-nanoseconds: false
Option B: Using a Code-Based Configuration Class
If you prefer explicit code configuration, create a Jackson config bean:
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JacksonTimeConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); return mapper; } }
Solution 2: Custom Deserializer for Second-Level Timestamps
If your frontend is sending second-level timestamps (instead of milliseconds), the above config will convert them to incorrect early dates (since it treats seconds as milliseconds). In this case, create a custom deserializer:
Step 1: Build the Custom Deserializer
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.time.Instant; public class SecondsToInstantDeserializer extends StdDeserializer<Instant> { public SecondsToInstantDeserializer() { super(Instant.class); } @Override public Instant deserialize(JsonParser parser, DeserializationContext context) throws IOException { long timestampInSeconds = parser.getLongValue(); return Instant.ofEpochSecond(timestampInSeconds); } }
Step 2: Apply the Deserializer to Your Transaction Field
Annotate the timestamp field in your Transaction class to use this custom logic:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.time.Instant; public class Transaction { private double amount; @JsonDeserialize(using = SecondsToInstantDeserializer.class) private Instant timestamp; // Add constructors, getters, and setters here }
Quick Check: Verify Your Transaction Class
Make sure your amount field matches the frontend's double type (no mismatches here, but it's worth a quick look):
public class Transaction { private double amount; // ... timestamp field and other class members }
All these solutions let you keep using Instant for your Duration operations while resolving the JSON parsing exception from the long timestamp input.
内容的提问来源于stack exchange,提问作者Ashish K Agarwal

