I am implementing a REST API in a Glassfish servlet with Jersey (2.22.2) and OpenAPI (1.1.2). I would like to allow for sending an Excel file as multipart form data to the following endpoint using the @FormDataParam
annotation:
@PUT
@Path("/upload")
@Parameter(description = "Import XML file", required = true, name = "file")
@Parameter(required = true, name = "isABC")
@Parameter(required = true, name = "type")
@Parameter(required = true, name = "year")
@Operation(description = "Imports an Excel file")
@APIResponse(responseCode = "200", description = "Success")
@APIResponse(responseCode = "401", description = "Authentication failed")
@APIResponse(responseCode = "500", description = "Unexpected exception")
@Consumes({MediaType.MULTIPART_FORM_DATA})
@RolesAllowed(UserRoles.ADMIN)
public Response importExcel(@FormDataParam("file") File file, @FormDataParam("isABC") boolean isABC, @FormDataParam("type") String type, @FormDataParam("year") int year) throws MyException {
importHandler.import(file, isABC, type, year);
return Response.status(Response.Status.OK).build();
}
When I run the Glassfish servlet I get the following exceptions:
WARNING: No injection source found for a parameter of type public javax.ws.rs.core.Response com.mypackage.importExcel(java.io.File,boolean,java.lang.String,int) throws com.mypackage.MyException at index 0.
org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public javax.ws.rs.core.Response com.mypackage.MyResource.importExcel
Configure MultipartFeature with web.xml
According to this Stackoverflow thread I need to use the jersey-media-multipart
dependency rather than jersey-multipart
and make sure I am using the same version as the Jersey core dependency (2.22.2). I also need to register the MultiPartFeature
, which I did in my web.xml
as follows:
<servlet>
<servlet-name>My Servlet</servlet-name>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
</servlet>
After these changes I still got the same error.
Configure MultipartFeature with ResourceConfig
I tried registering the MultipartFeature in a ResourceConfig
instead:
@ApplicationPath("/api")
@DeclareRoles({ UserRoles.USER, UserRoles.ADMIN })
@OpenAPIDefinition(info = @Info(title = "Backend service", version = "1.0.0"), servers = {
@Server(url = "/backend", description = "localhost") })
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
register(MultiPartFeature.class);
register(MyExceptionMapper.class);
// ... other ExceptionMappers
register(AdminResource.class);
register(UserResource.class);
// ... other Resource classes
}
}
I still need to do some configuration in my web.xml
. According to this Stackoverflow thread I need to define the ResourceConfig
in web.xml
to use both of them together:
<servlet>
<servlet-name>Backend</servlet-name>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mypackage.ApplicationConfig</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.mypackage.business.api</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
</servlet>
Now the application runs, but I cannot reach any of the API endpoints because the automatically generated OpenAPI configuration is empty:
paths: {}
components: {}