or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/maven-io-jsonwebtoken--jjwt-jackson

Jackson JSON serialization support extension for JJWT (Java JWT library) providing high-performance JSON processing capabilities for JWT token handling

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.jsonwebtoken/jjwt-jackson@0.12.x

To install, run

npx @tessl/cli install tessl/maven-io-jsonwebtoken--jjwt-jackson@0.12.0

index.mddocs/

JJWT Jackson Extension

JJWT Jackson extension is an optional extension module that provides Jackson-based JSON serialization and deserialization support for the JJWT (Java JWT) library. When present in the classpath, it enables high-performance JSON processing with Jackson's proven serialization framework for JWT token handling, offering advanced features like custom serializers, deserializers, and configuration options for optimal performance in JWT token management scenarios.

Package Information

  • Package Name: jjwt-jackson
  • Package Type: maven
  • Language: Java
  • Maven Coordinates: io.jsonwebtoken:jjwt-jackson:0.12.6
  • Jackson Version: 2.12.7.1
  • Installation: Add dependency to your Maven pom.xml or Gradle build.gradle

Maven:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.12.6</version>
</dependency>

Gradle:

implementation 'io.jsonwebtoken:jjwt-jackson:0.12.6'

Core Imports

import io.jsonwebtoken.jackson.io.JacksonSerializer;
import io.jsonwebtoken.jackson.io.JacksonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;

Basic Usage

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.jackson.io.JacksonSerializer;
import io.jsonwebtoken.jackson.io.JacksonDeserializer;
import java.security.Key;

// Using default Jackson configuration
JacksonSerializer<Object> serializer = new JacksonSerializer<>();
JacksonDeserializer<Object> deserializer = new JacksonDeserializer<>();

// Build JWT with Jackson serialization
String jwt = Jwts.builder()
    .json(serializer)
    .subject("user123")
    .claim("role", "admin")
    .signWith(key)
    .compact();

// Parse JWT with Jackson deserialization
Claims claims = Jwts.parser()
    .json(deserializer)
    .verifyWith(key)
    .build()
    .parseSignedClaims(jwt)
    .getPayload();

Architecture

The jjwt-jackson extension consists of three main components:

  • JacksonSerializer: Handles serialization of Java objects to JSON for JWT creation
  • JacksonDeserializer: Handles deserialization of JSON to Java objects for JWT parsing
  • JacksonSupplierSerializer: Internal serializer for handling Supplier objects

The extension automatically registers a custom Jackson module (jjwt-jackson) with specialized serializers and configures the ObjectMapper with optimal settings for JWT processing.

Capabilities

JSON Serialization

Serializes Java objects to JSON format using Jackson for JWT token creation.

public class JacksonSerializer<T> extends io.jsonwebtoken.io.AbstractSerializer<T> {
    public JacksonSerializer();
    public JacksonSerializer(ObjectMapper objectMapper);
}

Constructors:

  • JacksonSerializer() - Creates serializer with JJWT's default ObjectMapper configuration
  • JacksonSerializer(ObjectMapper objectMapper) - Creates serializer with custom ObjectMapper instance

Usage with custom ObjectMapper:

ObjectMapper customMapper = new ObjectMapper();
// Configure custom mapper as needed
customMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true);

JacksonSerializer<Object> serializer = new JacksonSerializer<>(customMapper);

String jwt = Jwts.builder()
    .json(serializer)
    .claim("customData", myObject)
    .compact();

JSON Deserialization

Deserializes JSON to Java objects using Jackson for JWT token parsing with support for custom claim type mapping.

public class JacksonDeserializer<T> extends io.jsonwebtoken.io.AbstractDeserializer<T> {
    public JacksonDeserializer();
    public JacksonDeserializer(ObjectMapper objectMapper);
    public JacksonDeserializer(Map<String, Class<?>> claimTypeMap);
}

Constructors:

  • JacksonDeserializer() - Creates deserializer with JJWT's default ObjectMapper configuration
  • JacksonDeserializer(ObjectMapper objectMapper) - Creates deserializer with custom ObjectMapper instance
  • JacksonDeserializer(Map<String, Class<?>> claimTypeMap) - Creates deserializer with custom claim type mapping for specific claims (creates a new ObjectMapper internally)

Usage with custom claim types:

import java.util.Map;

// Define custom claim types
Map<String, Class<?>> claimTypes = Map.of(
    "user", User.class,
    "permissions", Permission[].class,
    "metadata", Metadata.class
);

JacksonDeserializer<Object> deserializer = new JacksonDeserializer<>(claimTypes);

Claims claims = Jwts.parser()
    .json(deserializer)
    .verifyWith(key)
    .build()
    .parseSignedClaims(jwt)
    .getPayload();

// Claims are now deserialized to their proper types
User user = claims.get("user", User.class);
Permission[] permissions = claims.get("permissions", Permission[].class);

Usage with custom ObjectMapper:

ObjectMapper customMapper = new ObjectMapper();
customMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

JacksonDeserializer<Object> deserializer = new JacksonDeserializer<>(customMapper);

Claims claims = Jwts.parser()
    .json(deserializer)
    .verifyWith(key)
    .build()
    .parseSignedClaims(jwt)
    .getPayload();

Default ObjectMapper Configuration

The extension provides a pre-configured ObjectMapper with optimal settings for JWT processing.

// Package-protected static constants in JacksonSerializer (not part of public API)
static final String MODULE_ID = "jjwt-jackson";
static final Module MODULE; // Jackson module with custom serializers
static final ObjectMapper DEFAULT_OBJECT_MAPPER; // Pre-configured ObjectMapper

// Package-protected utility method
static ObjectMapper newObjectMapper(); // Creates new ObjectMapper with jjwt-jackson module

Default Configuration:

  • Registers jjwt-jackson module with custom serializers
  • Enables JsonParser.Feature.STRICT_DUPLICATE_DETECTION (true)
  • Disables DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES (false)
  • Configures JsonGenerator.Feature.AUTO_CLOSE_TARGET (false) during serialization

POJO Claim Support

Enable seamless serialization and deserialization of Plain Old Java Objects (POJOs) as JWT claims.

public class User {
    private String name;
    private String email;
    private List<String> roles;
    
    // Constructors, getters, setters
    public User() {}
    public User(String name, String email, List<String> roles) {
        this.name = name;
        this.email = email;
        this.roles = roles;
    }
    
    // getters and setters...
}

// Serialize POJO as claim
User user = new User("John Doe", "john@example.com", Arrays.asList("admin", "user"));

String jwt = Jwts.builder()
    .json(new JacksonSerializer<>())
    .claim("user", user)
    .signWith(key)
    .compact();

// Deserialize claim back to POJO
Map<String, Class<?>> claimTypes = Map.of("user", User.class);
JacksonDeserializer<Object> deserializer = new JacksonDeserializer<>(claimTypes);

Claims claims = Jwts.parser()
    .json(deserializer)
    .verifyWith(key)
    .build()
    .parseSignedClaims(jwt)
    .getPayload();

User deserializedUser = claims.get("user", User.class);

Integration with JJWT

Automatic Discovery

When jjwt-jackson is present in the classpath, JJWT automatically discovers and uses it for JSON processing without explicit configuration. This works through Java's Service Provider Interface (SPI) mechanism - the extension registers JacksonSerializer and JacksonDeserializer in META-INF/services/ files.

Manual Configuration

For fine-grained control, explicitly set serializers on JWT builders and parsers:

// JWT Creation
String jwt = Jwts.builder()
    .json(new JacksonSerializer<>(customObjectMapper))
    .subject("user123")
    .claim("data", customObject)
    .signWith(key)
    .compact();

// JWT Parsing
Claims claims = Jwts.parser()
    .json(new JacksonDeserializer<>(claimTypeMap))
    .verifyWith(key)
    .build()
    .parseSignedClaims(jwt)
    .getPayload();

JWK Serialization

The extension also supports serialization of JSON Web Keys (JWKs):

import io.jsonwebtoken.security.Jwks;
import io.jsonwebtoken.security.Jwk;

// Create or load a JWK
Jwk<?> jwk = Jwks.builder().build();

// Serialize JWK to JSON
byte[] jsonBytes = new JacksonSerializer<>().serialize(jwk);
String jwkJson = new String(jsonBytes, StandardCharsets.UTF_8);

// Parse JWK from JSON
Jwk<?> parsed = Jwks.parser().build().parse(jwkJson);

Error Handling

The Jackson extension integrates with JJWT's error handling and will throw appropriate JJWT exceptions:

  • SerializationException - When serialization fails
  • DeserializationException - When deserialization fails
  • MalformedJwtException - When JSON structure is invalid
try {
    Claims claims = Jwts.parser()
        .json(new JacksonDeserializer<>())
        .verifyWith(key)
        .build()
        .parseSignedClaims(invalidJwt)
        .getPayload();
} catch (MalformedJwtException e) {
    // Handle malformed JWT
} catch (io.jsonwebtoken.io.DeserializationException e) {
    // Handle JSON deserialization errors
}

Thread Safety

Both JacksonSerializer and JacksonDeserializer are thread-safe and can be shared across multiple threads. The underlying Jackson ObjectMapper and ObjectWriter/ObjectReader instances handle concurrent access safely.

Performance Considerations

  • Reuse instances: Create serializer/deserializer instances once and reuse them
  • Custom ObjectMapper: When using a custom ObjectMapper, ensure it's properly configured for your performance requirements
  • Claim type mapping: Using typed claims with JacksonDeserializer(Map<String, Class<?>>) provides better performance than generic Object deserialization

Types

// Key interfaces from jjwt-api (for reference)
interface io.jsonwebtoken.io.Serializer<T> {
    @Deprecated
    byte[] serialize(T t) throws io.jsonwebtoken.io.SerializationException;
    void serialize(T t, OutputStream out) throws io.jsonwebtoken.io.SerializationException;
}

interface io.jsonwebtoken.io.Deserializer<T> {
    @Deprecated
    T deserialize(byte[] bytes) throws io.jsonwebtoken.io.DeserializationException;
    T deserialize(Reader reader) throws io.jsonwebtoken.io.DeserializationException;
}

// Jackson types (from jackson-databind)
class com.fasterxml.jackson.databind.ObjectMapper {
    // Jackson's main configuration and processing class
}

class com.fasterxml.jackson.databind.Module {
    // Jackson module for extending functionality
}