Java framework for developing ops-friendly, high-performance, RESTful web applications
—
Jersey (JAX-RS) integration for building RESTful web services with automatic JSON serialization, validation, and metrics collection.
The Jersey environment provides methods for registering JAX-RS resources, providers, filters, and other components.
package io.dropwizard.jersey.setup;
public class JerseyEnvironment {
/**
* Registers a JAX-RS component (resource, provider, filter, etc.).
*/
public void register(Object component);
/**
* Registers a JAX-RS component class.
*/
public void register(Class<?> componentClass);
/**
* Registers all JAX-RS components in the given packages.
*/
public void packages(String... packages);
/**
* Registers all JAX-RS components in the given packages recursively.
*/
public void packages(boolean recursive, String... packages);
/**
* Returns the Jersey resource configuration.
*/
public DropwizardResourceConfig getResourceConfig();
/**
* Sets the URL pattern for Jersey servlet.
*/
public void setUrlPattern(String urlPattern);
}Usage Example:
@Override
public void run(MyConfiguration configuration, Environment environment) {
// Register individual resources
environment.jersey().register(new HelloWorldResource());
environment.jersey().register(new UserResource());
// Register all resources in a package
environment.jersey().packages("com.example.resources");
// Register providers and filters
environment.jersey().register(new CORSFilter());
environment.jersey().register(new LoggingFilter());
}Standard JAX-RS annotations and patterns for building REST endpoints with Dropwizard enhancements.
// Path and HTTP method annotations
@Path("/users")
@GET @POST @PUT @DELETE @HEAD @OPTIONS
// Content type annotations
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
// Parameter annotations
@PathParam("id") @QueryParam("name") @FormParam("value")
@HeaderParam("X-Custom") @CookieParam("session")
// Validation annotations
@Valid @NotNull @NotEmpty
// Dropwizard metric annotations
@Timed @Metered @Counted @ExceptionMetered
// Caching annotations
@CacheControl(maxAge = 300, maxAgeUnit = TimeUnit.SECONDS)Usage Example:
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {
private final UserService userService;
public UserResource(UserService userService) {
this.userService = userService;
}
@GET
@Timed(name = "get-users")
@CacheControl(maxAge = 5, maxAgeUnit = TimeUnit.MINUTES)
public List<User> getUsers(@QueryParam("active") @DefaultValue("true") boolean active,
@QueryParam("limit") @DefaultValue("100") @Range(min = 1, max = 1000) int limit) {
return userService.findUsers(active, limit);
}
@GET
@Path("/{id}")
@Timed(name = "get-user-by-id")
public Optional<User> getUser(@PathParam("id") @NotNull Long id) {
return userService.findById(id);
}
@POST
@Timed(name = "create-user")
public Response createUser(@Valid @NotNull User user, @Context UriInfo uriInfo) {
User created = userService.create(user);
URI location = uriInfo.getAbsolutePathBuilder()
.path(created.getId().toString())
.build();
return Response.created(location).entity(created).build();
}
@PUT
@Path("/{id}")
@Timed(name = "update-user")
public User updateUser(@PathParam("id") @NotNull Long id,
@Valid @NotNull User user) {
return userService.update(id, user);
}
@DELETE
@Path("/{id}")
@Timed(name = "delete-user")
public Response deleteUser(@PathParam("id") @NotNull Long id) {
userService.delete(id);
return Response.noContent().build();
}
}Custom exception mappers for converting exceptions to HTTP responses with proper status codes and error messages.
package javax.ws.rs.ext;
@Provider
public interface ExceptionMapper<T extends Throwable> {
/**
* Maps an exception to a Response.
*/
Response toResponse(T exception);
}Usage Example:
@Provider
public class ValidationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
@Override
public Response toResponse(ConstraintViolationException exception) {
List<String> errors = exception.getConstraintViolations()
.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toList());
return Response.status(Response.Status.BAD_REQUEST)
.entity(new ErrorResponse("Validation failed", errors))
.build();
}
}
// Register the exception mapper
environment.jersey().register(new ValidationExceptionMapper());JAX-RS providers for custom request/response processing including filters, interceptors, and message body readers/writers.
package javax.ws.rs.container;
@Provider
public interface ContainerRequestFilter {
void filter(ContainerRequestContext requestContext) throws IOException;
}
@Provider
public interface ContainerResponseFilter {
void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException;
}Usage Example:
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS");
responseContext.getHeaders().add("Access-Control-Allow-Headers",
"Content-Type, Authorization");
}
}
@Provider
@PreMatching
public class LoggingFilter implements ContainerRequestFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
LOGGER.info("Processing {} request to {}",
requestContext.getMethod(),
requestContext.getUriInfo().getPath());
}
}Customize Jackson ObjectMapper configuration for JSON serialization and deserialization.
package io.dropwizard.jackson;
public class ObjectMapperFactory {
/**
* Builds a new ObjectMapper with the configured settings.
*/
public ObjectMapper build();
/**
* Configures property naming strategy.
*/
public void setPropertyNamingStrategy(PropertyNamingStrategy strategy);
/**
* Configures serialization inclusion.
*/
public void setSerializationInclusion(JsonInclude.Include inclusion);
}Usage Example:
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
// Configure JSON serialization
bootstrap.getObjectMapper()
.registerModule(new JavaTimeModule())
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
// Custom JSON views
public class Views {
public static class Public {}
public static class Internal extends Public {}
}
public class User {
@JsonView(Views.Public.class)
private String name;
@JsonView(Views.Internal.class)
private String email;
// getters and setters
}
@GET
@JsonView(Views.Public.class)
public List<User> getPublicUsers() {
return userService.findAll();
}Implement custom message body readers and writers for handling specific content types or data formats.
package javax.ws.rs.ext;
@Provider
@Consumes("text/csv")
public interface MessageBodyReader<T> {
boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType);
T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException, WebApplicationException;
}
@Provider
@Produces("text/csv")
public interface MessageBodyWriter<T> {
boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType);
void writeTo(T t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException;
}Standard JAX-RS response patterns for different HTTP scenarios.
// Simple entity response
return user;
// Response with status code
return Response.ok(user).build();
return Response.status(201).entity(user).build();
// Created resource with location header
URI location = uriInfo.getAbsolutePathBuilder().path("123").build();
return Response.created(location).entity(user).build();
// No content response
return Response.noContent().build();
// Error responses
return Response.status(400).entity(errorMessage).build();
return Response.status(404).build();
// Optional responses
Optional<User> user = userService.findById(id);
return user.map(Response::ok)
.orElse(Response.status(404))
.build();Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard--dropwizard-project