Multipart_Form_Data: No Injection Source Found For a Parameter of Type Public Javax.Ws.Rs.Core.Response

MULTIPART_FORM_DATA: No injection source found for a parameter of type public javax.ws.rs.core.Response

Get rid of jersey-multipart-1.18.jar. That is for Jersey 1.x. Add these two

  • jersey-media-multipart-2.17
  • mimepull-1.9.3

For Maven you would use the following dependency (you don't need to explicitly add the mimepull dependency, as this one will pull it in).

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.17</version> <!-- Make sure the Jersey version matches
the one you are currently using -->
</dependency>

Then you need to register the MultiPartFeature. If you are using a ResourceConfig for configuration, you can simply do

register(MultiPartFeature.class);

If you are using web.xml, then you can add the class as an <init-param> to the Jersey servlet

<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>

Note that if you have multiple providers that you want to register, then you can delimit each provider class with a comma, semicolon, or space/newline. You cannot use this same param-name twice. See Suarabh's answer

UPDATE

Also, once you get rid of jersey-multipart-1.18.jar you will have compile errors for the missing imported classes. For the most part, the class names are still the same, just the packages have changed, i.e.

  • org.glassfish.jersey.media.multipart.FormDataParam
  • org.glassfish.jersey.media.multipart.FormDataContentDisposition


For Dropwizard

If you're using Dropwizard, instead of adding the jersey-media-multipart, they document for your to add dropwizard-forms instead. And instead of registering the MultiPartFeature, you should register the MultiPartBundle

@Override
public void initialize(Bootstrap<ExampleConfiguration> bootstrap) {
bootstrap.addBundle(new MultiPartBundle());
}

Really doesn't make much difference though as all the Dropwizard bundle does is register the MultiPartFeature with the ResourceConfig.



Aside

If you are here for a different ModelValidationException, here are some links for information on other causes of the exception.

  • 1
  • 2
  • 3

MULTIPART_FORM_DATA: No injection source found for a parameter of type Response

Once you don't have a ResourceConfig, try registering the MultiparFeature in the web.xml deployment descriptor:

<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>

If you have more provider class names in the <param-value>, use , to separate them.

No injection source found for a parameter of type public javax.ws.rs.core.Response - Jersey - MultiPartFeature

I See three different ResourceConfigs in your codebase, but none of them are actually used for the application. So the MultiPartFeature is never register, which is what is causing the error. You have a few options on how to use a ResourceConfig in your case.

  1. You can instantiate the ServletContainer, passing in the ResourceConfig instance. Unfortunately, there is no ServletContextHolder#addServlet(Servlet) method, but there is a ServletContextHolder#addServlet(ServletHolder) method, so we need to wrap the ServletContainer in a ServletHolder

    ServletHolder jerseyServlet = new ServletHolder(new ServletContainer(resourceConfig));
    servletContextHolder.addServlet(jerseyServlet, "/*");
  2. With the above option, you can use a local instance or a subclass, but if you only have a subclass, like your first bit of code, then you add a servlet init param, that specifies the ResourceConfig subclass.

    ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
    jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
    jerseyServlet.setInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, resourceConfig.class.getCanonicalName());

    Notice the last call where I set the application class name.

  3. Without using a ResourceConfig, you could just register the MulitPartFeature with an init param

    jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, MultiPartFeature.class.getCanonicalName());

No injection source found for Multipart feature

So here's the thing. You have two different application configurations: the web.xml and the ApplicationConfig class. These are to completely separate configurations, which are both valid all by themselves. The ApplicationConfig class is the one that registers the MultiPartFeature, but it seems like the configuration that is being used is the web.xml. I never really tested what happens when you have two different application configurations, but it seems like your web.xml is taking precedence. And in your web.xml, you are not configuring the MultiPartFeature.

If you want to just use the web.xml, then you can check out this answer for how out can configure it.

You can however just delete the entire web.xml. This will cause the ApplicationConfig to kick it. But notice the two differences: the @ApplicationPath on the ApplicationConfig acts like the url-mapping in the web.xml. So if you delete the web.xml, then the base path will just be / (or nothing) instead of the /webapi like you have in the web.xml

If you decide the delete the web.xml, I suggest you use ResourceConfig instead of Application. You can get some good information about this class and different configuration possibilities in this post from What exactly is the ResourceConfig class in Jersey 2?

OffsetDateTime yielding No injection source found for a parameter of type public javax.ws.rs.core.response in GET method


All other similar questions I have found had to do with MultiPart Data and file uploading

It's related. The error is a general error you get when Jersey can't validate the resource model. Part of the resource model is the method parameters. Jersey has a system for knowing which parameters it will be able to process and which ones it won't. In your case, it doesn't know how to process the OffsetDateTime.

There are a set of rules that you need to follow in order to able to use non basic types as @QueryParams (and all other @XxxParams such as @PathParam and @FormParam, etc.):

  1. Be a primitive type
  2. Have a constructor that accepts a single String argument
  3. Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String))
  4. Have a registered implementation of ParamConverterProvider JAX-RS extension SPI that returns a ParamConverter instance capable of a "from string" conversion for the type.
  5. Be List<T>, Set<T> or SortedSet<T>, where T satisfies 2, 3 or 4 above. The resulting collection is read-only.

So in this case of OffsetDateTime, going down the list; it's not a primitive; it doesn't have a String constructor; it doesn't have a static valueOf or fromString

So basically, the only option left is to implement a ParamConverter/ParamConverterProvider for it. The basic set up looks like

@Provider
public class OffsetDateTimeProvider implements ParamConverterProvider {

@Override
public <T> ParamConverter<T> getConverter(Class<T> clazz, Type type, Annotation[] annotations) {
if (clazz.getName().equals(OffsetDateTime.class.getName())) {

return new ParamConverter<T>() {

@SuppressWarnings("unchecked")
@Override
public T fromString(String value) {
OffsetDateTime time = ...
return (T) time;
}

@Override
public String toString(T time) {
return ...;
}
};
}
return null;
}
}

Jersey will pass you the String value of the query parameter, and it's your job to to create it and return it.

Then just register the OffsetDateTimeProvider with the application. If you're using package scanning, it should be picked up and registered automatically from the @Provider annotation.

I don't use Swagger, so I don't know if they already provide something like this already implemented, but it seems odd that they would generate this for you, and not have a way to make it work. I know Jersey 3 will have Java 8 support out the box, but who know when the heck that's gonna be released.

No injection source found for a parameter in rest-service with jaxrs

I found out that the problem was, that I imported the wrong @PathParam Annotation.

MULTIPART_FORM_DATA: No injection source found for a parameter of type public javax.ws.rs.core.Response

Get rid of jersey-multipart-1.18.jar. That is for Jersey 1.x. Add these two

  • jersey-media-multipart-2.17
  • mimepull-1.9.3

For Maven you would use the following dependency (you don't need to explicitly add the mimepull dependency, as this one will pull it in).

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.17</version> <!-- Make sure the Jersey version matches
the one you are currently using -->
</dependency>

Then you need to register the MultiPartFeature. If you are using a ResourceConfig for configuration, you can simply do

register(MultiPartFeature.class);

If you are using web.xml, then you can add the class as an <init-param> to the Jersey servlet

<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>

Note that if you have multiple providers that you want to register, then you can delimit each provider class with a comma, semicolon, or space/newline. You cannot use this same param-name twice. See Suarabh's answer

UPDATE

Also, once you get rid of jersey-multipart-1.18.jar you will have compile errors for the missing imported classes. For the most part, the class names are still the same, just the packages have changed, i.e.

  • org.glassfish.jersey.media.multipart.FormDataParam
  • org.glassfish.jersey.media.multipart.FormDataContentDisposition


For Dropwizard

If you're using Dropwizard, instead of adding the jersey-media-multipart, they document for your to add dropwizard-forms instead. And instead of registering the MultiPartFeature, you should register the MultiPartBundle

@Override
public void initialize(Bootstrap<ExampleConfiguration> bootstrap) {
bootstrap.addBundle(new MultiPartBundle());
}

Really doesn't make much difference though as all the Dropwizard bundle does is register the MultiPartFeature with the ResourceConfig.



Aside

If you are here for a different ModelValidationException, here are some links for information on other causes of the exception.

  • 1
  • 2
  • 3

Initialization failure on JAXRS Jersey SpringBoot REST API

The actual jersey multipart requires additional dependencies and configurations: https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/media.html#multipart

  1. Dependency of jersey-media-multipart
  2. Register the MultiPartFeature.class

See the above doc for more details



Related Topics



Leave a reply



Submit