Swagger Jersey JAX-RS extension for handling form data parameters in REST APIs
npx @tessl/cli install tessl/maven-io-swagger--swagger-jersey-jaxrs@1.6.0Swagger Jersey JAX-RS is a specialized extension for the Swagger Core library that adds support for Jersey's multipart form data parameters in REST API documentation generation. It automatically processes @FormDataParam annotations and converts them into appropriate Swagger parameter definitions, enabling comprehensive OpenAPI documentation for file upload endpoints and form-based APIs.
pom.xml:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey-jaxrs</artifactId>
<version>1.6.15</version>
</dependency>import io.swagger.jersey.SwaggerJerseyJaxrs;
import io.swagger.jaxrs.ext.SwaggerExtension;
import com.sun.jersey.multipart.FormDataParam;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.List;This library works automatically through Java's Service Provider Interface (SPI). Once added to your classpath, it will be automatically discovered and used by the Swagger JAX-RS library to process Jersey multipart form parameters.
// No explicit setup required - the extension is auto-discovered
// Your Jersey resource methods with @FormDataParam will be automatically documented
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@ApiOperation(value = "Upload a file with metadata")
public Response uploadFile(
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("filename") String filename,
@FormDataParam("description") String description
) {
// Implementation
return Response.ok().build();
}Generated OpenAPI Documentation:
The above endpoint will automatically generate the following Swagger/OpenAPI parameter definitions:
parameters:
- name: file
in: formData
type: file
required: false
- name: filename
in: formData
type: string
required: false
- name: description
in: formData
type: string
required: falseAdvanced Example with Mixed Types:
@POST
@Path("/document/{documentName}.json")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@ApiOperation(value = "Upload document with metadata")
public String processDocument(
@PathParam("documentName") String documentName,
@FormDataParam("document") InputStream documentStream,
@FormDataParam("userId") Integer userId,
@FormDataParam("tags") List<String> tags,
@FormDataParam("metadata") FormDataContentDisposition metadata // This will be ignored
) {
return "processed";
}This generates:
parameters:
- name: documentName
in: path
type: string
required: true
- name: document
in: formData
type: file
required: false
- name: userId
in: formData
type: integer
format: int32
required: false
- name: tags
in: formData
type: array
items:
type: string
required: false
# Note: metadata parameter is automatically excludedThe library extends the Swagger JAX-RS extension mechanism:
SwaggerExtension interfaceMETA-INF/services configuration@FormDataParam annotationsProcesses Jersey @FormDataParam annotations and converts them to Swagger parameter definitions.
/**
* Extracts parameters from method annotations, specifically handling FormDataParam
*
* This method is the core of the Jersey multipart form data processing. It examines
* each annotation on a method parameter and if it finds a @FormDataParam annotation,
* it creates the appropriate Swagger Parameter object.
*
* @param annotations List of annotations to process - typically from a JAX-RS method parameter
* @param type The Java type of the parameter (e.g., InputStream.class, String.class, Integer.class)
* @param typesToSkip Set of types that should be ignored during processing (inherited from parent)
* @param chain Chain of SwaggerExtension processors for delegation to other extensions
* @return List containing a single FormParameter if @FormDataParam found, empty list if type should be ignored,
* or delegates to parent class for other annotation types
* @throws IllegalArgumentException if annotation processing fails
*/
public List<Parameter> extractParameters(
List<Annotation> annotations,
Type type,
Set<Type> typesToSkip,
Iterator<SwaggerExtension> chain
);Behavior:
@FormDataParam annotationsFormParameter with type "file" for InputStream parameters (file uploads)FormParameter with property schema for other types (regular form fields)Determines which classes should be ignored during parameter processing.
/**
* Determines if a class should be ignored during parameter extraction
*
* This method filters out Jersey-specific multipart classes that should not appear
* in the generated Swagger documentation as they are implementation details rather
* than API parameters that clients need to know about.
*
* @param cls The class to check for filtering - typically a parameter type from a JAX-RS method
* @return true if the class should be ignored (filtered out), false if it should be processed
*/
protected boolean shouldIgnoreClass(Class<?> cls);Behavior:
true for com.sun.jersey.core.header.FormDataContentDispositiontrue for com.sun.jersey.multipart.FormDataBodyPartfalse for all other classes// Main extension class from io.swagger.jersey package
class SwaggerJerseyJaxrs extends AbstractSwaggerExtension {
public List<Parameter> extractParameters(List<Annotation> annotations, Type type, Set<Type> typesToSkip, Iterator<SwaggerExtension> chain);
protected boolean shouldIgnoreClass(Class<?> cls);
}
// Parent class from io.swagger.jaxrs.ext package
abstract class AbstractSwaggerExtension implements SwaggerExtension {
public List<Parameter> extractParameters(List<Annotation> annotations, Type type, Set<Type> typesToSkip, Iterator<SwaggerExtension> chain);
protected boolean shouldIgnoreType(Type type, Set<Type> typesToSkip);
protected boolean shouldIgnoreClass(Class<?> cls);
}
// Extension interface from io.swagger.jaxrs.ext package
interface SwaggerExtension {
List<Parameter> extractParameters(List<Annotation> annotations, Type type, Set<Type> typesToSkip, Iterator<SwaggerExtension> chain);
boolean shouldIgnoreType(Type type, Set<Type> typesToSkip);
}
// From io.swagger.models.parameters package
class FormParameter extends AbstractSerializableParameter<FormParameter> {
FormParameter type(String type);
FormParameter name(String name);
void setProperty(Property property);
FormParameter description(String description);
FormParameter required(boolean required);
}
// From io.swagger.models.parameters package
interface Parameter {
String getName();
void setName(String name);
String getDescription();
void setDescription(String description);
boolean getRequired();
void setRequired(boolean required);
}
// From io.swagger.models.properties package
interface Property {
String getType();
String getFormat();
Object getExample();
}
// From com.sun.jersey.multipart package
@interface FormDataParam {
String value();
}
// From com.sun.jersey.core.header package (ignored by extension)
class FormDataContentDisposition {
String getName();
String getFileName();
long getSize();
}
// From com.sun.jersey.multipart package (ignored by extension)
class FormDataBodyPart {
FormDataContentDisposition getFormDataContentDisposition();
MediaType getMediaType();
<T> T getValueAs(Class<T> clazz);
}The extension is automatically registered through Java's Service Provider Interface:
META-INF/services/io.swagger.jaxrs.ext.SwaggerExtensionio.swagger.jersey.SwaggerJerseyJaxrsThis library requires the following dependencies to be present:
@FormDataParam annotationThe library gracefully handles edge cases: