如何修改JJWT/Jackson所用的ObjectMapper?Spring Security JWT序列化问题
Hey, I’ve run into exactly this issue before when using JJWT with custom entities that include Java 8 date types like LocalDateTime. The truncated ldt... in your token payload is almost certainly due to Jackson not properly handling the LocalDateTime serialization, or missing getter methods on your entity. Let’s break down the fixes step by step:
1. Add Jackson’s Java 8 Date/Time Module Dependency
JJWT relies on Jackson for JSON serialization, but the default setup doesn’t include support for Java 8’s java.time types. First, make sure you have the necessary dependency in your build file:
Maven:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
Gradle:
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
2. Configure JJWT to Use a Custom ObjectMapper
Next, you need to tell JJWT to use an ObjectMapper that’s registered with the JavaTimeModule (to handle LocalDateTime properly). You can either create a custom mapper or reuse Spring’s pre-configured one (if you’re using Spring Boot):
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.jackson.io.JacksonSerializer; // Initialize a properly configured ObjectMapper ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); // Optional: Serialize dates as ISO-8601 strings instead of timestamp arrays // objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // Generate the JWT with the custom serializer String jwtToken = Jwts.builder() .setSubject("testuser@mydomain.com") .claim("entity", yourMyEntityInstance) // Pass your MyEntity object here .signWith(SignatureAlgorithm.HS256, "your-secure-secret-key") // Use a secure key from config, not hardcoded! .serializeToJsonWith(new JacksonSerializer(objectMapper)) // Critical: Use our configured mapper .compact();
3. Ensure Your Entity Has Proper Getter Methods
Jackson (and thus JJWT) needs getter methods to access your entity’s fields. If your MyEntity class is missing getters, Jackson can’t read the values properly, leading to incomplete serialization. Update your entity:
@Entity public class MyEntity { private String name; private LocalDateTime ldt; // Required getters (and setters if you need them) public String getName() { return name; } public void setName(String name) { this.name = name; } public LocalDateTime getLdt() { return ldt; } public void setLdt(LocalDateTime ldt) { this.ldt = ldt; } }
4. Verify the Result
After making these changes, your token’s payload should include the full, correctly serialized entity object. For example:
{ "sub": "testuser@mydomain.com", "exp": 1523659655, "entity": { "name": "testname", "ldt": "2024-05-20T14:30:00" } }
Quick Bonus Tip
If you’re using Spring Boot, you can inject the pre-configured ObjectMapper from the Spring context instead of creating a new one—it already has the JavaTimeModule registered by default, which saves you some setup work.
内容的提问来源于stack exchange,提问作者Pieter De Clercq




