What it is
Jersey is the reference implementation of JAX-RS (Java API for RESTful Web Services) for building RESTful web services in Java. It simplifies creating web services with annotations, dependency injection, and automatic JSON/XML support.
Jersey allows you to define REST endpoints using annotations such as @Path, @GET, @POST, @PUT, @DELETE, and @Produces/@Consumes for content negotiation. It supports JSON/XML serialization, request/response filtering, exception mapping, dependency injection via CDI, asynchronous endpoints, and client-side APIs for consuming other REST services.
Installation
Add the following dependencies in your pom.xml:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>3.2.0</version>
</dependency>Getting started
The smallest useful thing you can do with it, and what each part means.
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class HelloResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello Jersey!";
}
}import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/users")
public class UserResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public User createUser(User user) {
// save user to database or service
return user;
}
}Advanced usage
Where the library earns its place over a simpler alternative.
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@Path("/service")
public class ServiceResource {
@Inject
MyService myService;
@GET
public String getMessage() {
return myService.getMessage();
}
}import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.core.Response;
@Provider
public class GenericExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception exception) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(exception.getMessage())
.build();
}
}import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.ext.Provider;
@Provider
public class LoggingFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) {
System.out.println("Incoming request: " + requestContext.getUriInfo().getRequestUri());
}
}import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.container.AsyncResponse;
import jakarta.ws.rs.container.Suspended;
import java.util.concurrent.CompletableFuture;
@Path("/async")
public class AsyncResource {
@GET
public void asyncHello(@Suspended AsyncResponse response) {
CompletableFuture.supplyAsync(() -> "Hello Async Jersey!")
.thenAccept(response::resume);
}
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- WebApplicationException
- Thrown when you want to return a specific HTTP status code. Use proper response codes and messages.
- BadRequestException
- Thrown when the request cannot be processed due to client error (400). Validate inputs before processing.
- ProcessingException
- Occurs during client-side API calls. Check network connectivity and request configuration.
Best practices
- Use standard JAX-RS annotations for REST endpoints to maintain portability.
- Leverage CDI for dependency injection and modular design.
- Use ExceptionMappers to handle errors consistently.
- Use Filters and Interceptors for cross-cutting concerns like logging, authentication, and metrics.
- Separate resource classes, services, and domain models for maintainable architecture.
Background
Why it exists, and what it was reacting to.
Jersey was developed by Oracle (originally as part of GlassFish) to provide a standard, annotation-driven framework for creating RESTful web services on the Java platform. It supports both client-side and server-side APIs, integrates with CDI (Contexts and Dependency Injection), and provides filters, exception handling, and advanced features such as asynchronous processing. Over the years, Jersey has become a widely used framework in enterprise and microservice applications due to its adherence to standards and ease of integration.
