Dropwizard Jersey Support - Jersey integration module for the Dropwizard Java framework
—
Type-safe parameter converters for common data types with automatic parsing, validation, and error handling for JAX-RS resource methods. These parameter wrappers provide consistent error handling and HTTP 400 responses for invalid input.
Base class for all parameter types providing common parsing, validation, and error handling functionality.
/**
* Abstract base class for Jersey parameter types with error handling
* @param <T> the type of value wrapped by the parameter
*/
public abstract class AbstractParam<T> {
/** Creates parameter with input value using default parameter name */
protected AbstractParam(String input);
/** Creates parameter with input value and custom parameter name */
protected AbstractParam(String input, String parameterName);
/** Gets the parsed and validated value */
public T get();
/** Parses the string input into the target type */
protected abstract T parse(String input) throws Exception;
/** Generates error message for parsing failures */
protected String errorMessage(Exception e);
/** Gets HTTP status code for parsing errors (default: BAD_REQUEST) */
protected Response.Status getErrorStatus();
/** Generates ErrorMessage for client response */
protected ErrorMessage generateErrorMessage(String input, Exception e);
}Parameter wrapper for UUID values with automatic parsing and validation.
/**
* Parameter wrapper for UUID values
* Throws 400 Bad Request for invalid UUID strings
*/
public class UUIDParam extends AbstractParam<UUID> {
/** Creates UUIDParam from string input */
public UUIDParam(String input);
/** Creates UUIDParam with custom parameter name for error messages */
public UUIDParam(String input, String parameterName);
}Usage Examples:
import io.dropwizard.jersey.params.UUIDParam;
import jakarta.ws.rs.*;
import java.util.UUID;
@Path("/users")
public class UserResource {
@GET
@Path("/{id}")
public User getUser(@PathParam("id") UUIDParam userId) {
UUID id = userId.get(); // Automatic UUID parsing
return userService.findById(id);
}
@GET
public List<User> getUsers(@QueryParam("organizationId") UUIDParam orgId) {
if (orgId != null) {
return userService.findByOrganization(orgId.get());
}
return userService.findAll();
}
}Parameter wrapper for integer values with validation.
/**
* Parameter wrapper for integer values
* Returns 400 Bad Request for non-decimal values
* @deprecated Use OptionalInt instead
*/
@Deprecated
public class IntParam extends AbstractParam<Integer> {
/** Creates IntParam from string input */
public IntParam(String input);
/** Creates IntParam with custom parameter name */
public IntParam(String input, String parameterName);
}Parameter wrapper for long values with validation.
/**
* Parameter wrapper for long values
* Returns 400 Bad Request for non-decimal values
* @deprecated Use OptionalLong instead
*/
@Deprecated
public class LongParam extends AbstractParam<Long> {
/** Creates LongParam from string input */
public LongParam(String input);
/** Creates LongParam with custom parameter name */
public LongParam(String input, String parameterName);
}Parameter wrapper for non-empty string values with validation.
/**
* Parameter wrapper for non-empty strings
* Returns 400 Bad Request for null, empty, or whitespace-only strings
*/
public class NonEmptyStringParam extends AbstractParam<String> {
/** Creates NonEmptyStringParam from string input */
public NonEmptyStringParam(String input);
/** Creates NonEmptyStringParam with custom parameter name */
public NonEmptyStringParam(String input, String parameterName);
}Usage Examples:
import io.dropwizard.jersey.params.*;
import jakarta.ws.rs.*;
@Path("/api")
public class ApiResource {
@GET
@Path("/search")
public SearchResults search(@QueryParam("q") NonEmptyStringParam query,
@QueryParam("limit") IntParam limit) {
String searchTerm = query.get(); // Guaranteed non-empty
int resultLimit = limit != null ? limit.get() : 10;
return searchService.search(searchTerm, resultLimit);
}
@GET
@Path("/items/{id}")
public Item getItem(@PathParam("id") LongParam itemId) {
Long id = itemId.get(); // Automatic long parsing
return itemService.findById(id);
}
}Provider classes that enable automatic conversion of string parameters to AbstractParam types.
/**
* Abstract parameter converter for AbstractParam types
*/
public abstract class AbstractParamConverter<T> implements ParamConverter<T> {
public T fromString(String value);
public String toString(T value);
}
/**
* Parameter converter provider for AbstractParam types
* Automatically registers converters for all AbstractParam subclasses
*/
public class AbstractParamConverterProvider implements ParamConverterProvider {
public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations);
}All parameter types provide consistent error handling:
When parameter parsing fails, a WebApplicationException is thrown with:
ErrorMessagepublic class CustomUUIDParam extends AbstractParam<UUID> {
public CustomUUIDParam(String input) {
super(input, "User ID");
}
@Override
protected String errorMessage(Exception e) {
return "User ID must be a valid UUID format";
}
@Override
protected UUID parse(String input) throws Exception {
return UUID.fromString(input);
}
}Parameter types work seamlessly with Bean Validation:
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import io.dropwizard.jersey.params.UUIDParam;
@Path("/users")
public class UserResource {
@POST
public User createUser(@Valid @NotNull CreateUserRequest request,
@QueryParam("organizationId") UUIDParam orgId) {
// Both parameter validation and bean validation are applied
UUID organizationId = orgId.get(); // Parameter parsing validated
// request object validated by Bean Validation
return userService.create(request, organizationId);
}
}
public class CreateUserRequest {
@NotBlank
@Size(min = 2, max = 50)
private String name;
@Email
private String email;
// getters and setters
}// Good - use UUIDParam for UUID path/query parameters
@Path("/{userId}")
public User getUser(@PathParam("userId") UUIDParam userId) {
return userService.findById(userId.get());
}
// Good - use NonEmptyStringParam for required string parameters
@GET
public List<Item> search(@QueryParam("q") NonEmptyStringParam query) {
return searchService.search(query.get());
}
// Consider Optional types for new code instead of deprecated IntParam/LongParam
@GET
public List<Item> getItems(@QueryParam("limit") OptionalInt limit) {
int actualLimit = limit.orElse(10);
return itemService.getItems(actualLimit);
}@GET
@Path("/users")
public List<User> getUsers(@QueryParam("organizationId") UUIDParam orgId) {
if (orgId != null) {
// orgId.get() is safe here - parsing already validated
return userService.findByOrganization(orgId.get());
}
return userService.findAll();
}public class EmailParam extends AbstractParam<String> {
public EmailParam(String input) {
super(input, "Email");
}
@Override
protected String parse(String input) throws Exception {
if (input == null || !input.contains("@")) {
throw new IllegalArgumentException("Invalid email format");
}
return input.toLowerCase().trim();
}
@Override
protected String errorMessage(Exception e) {
return "Email must be a valid email address";
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard--dropwizard-jersey