JAX-RS and Jersey

Last update: 2024-07-01 19:46:18 +0800 +0800
tags: Java | Jax-Rs | Jersey | Web
Available translations: 日本語 / 中文(简体) / 中文(繁體)

JAX-RS is the Jakarta standard API and specification for HTTP resources in the jakarta.ws.rs packages. It defines annotations, request and response types, client APIs, providers, and server-sent event support. Jersey is a conforming JAX-RS implementation.

JAX-RS is distinct from JAX-WS, which concerns XML web services.

Define Resources #

Add the Jakarta REST API at compile time and a JAX-RS implementation at runtime. A resource class uses @Path; methods use an HTTP method annotation and may add a relative path:

java
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {
    @GET
    @Path("/{id}")
    public User get(@PathParam("id") long id) {
        return service.find(id);
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response create(User input) {
        User created = service.create(input);
        return Response.created(
                URI.create("/users/" + created.id())).entity(created).build();
    }
}

An Application subclass can be annotated with @ApplicationPath("/api"). The surrounding container or implementation determines how a request reaches the JAX-RS runtime.

Bind Requests #

Annotate non-body method parameters with their source:

  • @PathParam, @QueryParam, and @MatrixParam read URI components.
  • @HeaderParam, @CookieParam, and @FormParam read headers, cookies, and form data.
  • @Context injects contextual JAX-RS objects.
java
@GET
public Response search(
        @QueryParam("q") String query,
        @QueryParam("limit") @DefaultValue("20") int limit) {
    return Response.ok(service.search(query, limit)).build();
}

An unannotated resource-method parameter is normally the request entity. Its Java type must be supported by a MessageBodyReader; JSON-to-object binding, for example, requires an installed JSON provider. Declare @Consumes so the contract is unambiguous. An InputStream can accept a raw entity, but core JAX-RS alone does not parse multipart/form-data; use a supported multipart provider such as Jersey’s multipart module.

Group several parameter bindings in a bean with @BeanParam:

java
public class PageRequest {
    @QueryParam("offset") @DefaultValue("0") int offset;
    @QueryParam("limit") @DefaultValue("20") int limit;
}

Use it as @BeanParam PageRequest page. Validate input explicitly or through the Jakarta Validation integration supplied by the runtime.

Produce Responses and Errors #

A method may return an entity directly or a Response for explicit status, headers, and entity control. @Produces participates in content negotiation. Return an appropriate status and a stable error representation; do not expose stack traces to clients.

Throwing a WebApplicationException (such as NotFoundException or BadRequestException) supplies an HTTP response. For application exceptions, write an ExceptionMapper<T> and annotate it @Provider:

java
@Provider
public class IllegalArgumentMapper
        implements ExceptionMapper<IllegalArgumentException> {
    public Response toResponse(IllegalArgumentException error) {
        return Response.status(Response.Status.BAD_REQUEST)
                .entity(Map.of("error", error.getMessage())).build();
    }
}

The runtime chooses the applicable mapper whose exception type is the closest supertype of the thrown exception. If none applies, it produces a server error response according to its container integration.

Deploy With Jersey #

Jersey implements the JAX-RS contracts but does not by itself accept TCP connections. In a servlet container, add org.glassfish.jersey.containers:jersey-container-servlet, register org.glassfish.jersey.servlet.ServletContainer, and configure either a resource-package scan or a ResourceConfig.

For an embedded server, create a ResourceConfig and pass it to a supported Jersey container. Keep application code dependent on jakarta.ws.rs where possible, and isolate Jersey-specific configuration at the deployment edge.

Comments

Read or comment on GitHub (sign-in required to comment)