Blog
Wild & Free Tools

How to Decode a JWT in Java and Spring Boot (With and Without jjwt)

Last updated: March 2026 5 min read
Quick Answer

Table of Contents

  1. Manual Decode in Java
  2. Using jjwt Library
  3. Spring Boot Resource Server
  4. Common Java JWT Errors
  5. Frequently Asked Questions

Decoding a JWT in Java does not require a library — the standard Base64 class handles it. For production Spring Boot apps, jjwt or Spring Security OAuth2 resource server are the preferred choices. Here is how each approach works.

Decode JWT Payload in Plain Java — No Maven Dependency

import java.util.Base64;
import org.json.JSONObject;

public class JwtDecoder {

    public static JSONObject decodePayload(String token) {
        String[] parts = token.split("\.");
        if (parts.length != 3) {
            throw new IllegalArgumentException("Invalid JWT format");
        }

        String payload = parts[1];
        // base64url uses - and _ instead of + and /
        payload = payload.replace('-', '+').replace('_', '/');

        // Add padding
        int mod = payload.length() % 4;
        if (mod == 2) payload += "==";
        else if (mod == 3) payload += "=";

        byte[] decoded = Base64.getDecoder().decode(payload);
        return new JSONObject(new String(decoded, java.nio.charset.StandardCharsets.UTF_8));
    }

    public static void main(String[] args) {
        JSONObject claims = decodePayload(token);
        String sub = claims.getString("sub");
        long exp = claims.getLong("exp");
        System.out.println("User: " + sub);
        System.out.println("Expires: " + new java.util.Date(exp * 1000L));
    }
}

This approach uses only standard library classes. Add the org.json dependency for the JSONObject parser, or use Jackson's ObjectMapper if you already have it in your project.

Decode JWT with jjwt in Spring Boot

Add to pom.xml:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.12.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.12.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.12.5</version>
    <scope>runtime</scope>
</dependency>
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

// Parse and verify (HS256 with secret key)
Claims claims = Jwts.parser()
    .verifyWith(Keys.hmacShaKeyFor(secretKey.getBytes()))
    .build()
    .parseSignedClaims(token)
    .getPayload();

String sub = claims.getSubject();
String email = claims.get("email", String.class);
Date expiry = claims.getExpiration();
Sell Custom Apparel — We Handle Printing & Free Shipping

Reading JWT Claims in Spring Security

When using Spring Boot as an OAuth2 resource server, JWT claims are automatically decoded and available in the security context:

// application.properties
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://YOUR-ISSUER.com

// Controller — claims auto-decoded from Bearer token
@GetMapping("/user")
public ResponseEntity<?> getUser(
        @AuthenticationPrincipal Jwt jwt) {

    String userId = jwt.getSubject();
    String email = jwt.getClaimAsString("email");
    List<String> roles = jwt.getClaimAsStringList("roles");

    return ResponseEntity.ok(new UserResponse(userId, email));
}

Spring Security validates the signature against the issuer's JWKS endpoint automatically. You get decoded, verified claims without writing any JWT parsing code.

Common Java JWT Decoding Errors and Fixes

Check Your Token Claims Before Coding

Paste your JWT above to confirm claim names and structure — faster than running a Spring Boot app to debug.

Open Free JWT Decoder

Frequently Asked Questions

Can I use Base64.getUrlDecoder() instead of Base64.getDecoder() for JWTs?

Yes — Base64.getUrlDecoder() handles the - and _ character substitution automatically. You still need to add padding manually before passing to getUrlDecoder().decode().

What is the difference between jjwt and java-jwt (Auth0)?

Both are popular Java JWT libraries. jjwt is the most widely used. Auth0's java-jwt (com.auth0:java-jwt) has a slightly different API but similar capabilities. Either works for decode and verification.

How do I decode a JWT without verifying the signature in jjwt?

Use Jwts.parser().build().parseUnsecuredClaims(token) for tokens with "alg": "none", or manually decode the base64 payload as shown in the manual approach above. jjwt 0.12+ requires explicit steps to skip verification.

Andrew Walsh
Andrew Walsh Developer Tools & API Writer

Andrew worked as a developer advocate at two SaaS startups writing API documentation used by thousands of engineers.

More articles by Andrew →
Launch Your Own Clothing Brand — No Inventory, No Risk