OffsetDateTime gives "There is no injection source found for a parameter of type public javax.ws.rs.core.response" in the GET method

I have the following GET REST method:

 import java.time.OffsetDateTime; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import com.product.rest.api.TransactionsApi; import com.product.rest.model.Transaction; @Path("/transactions") @Api(description = "the transactions API") @Consumes({ "application/json" }) @Produces({ "application/json" }) public class TransactionsApiImpl extends TransactionsApi { @GET @Consumes({ "application/json" }) @Produces({ "application/json" }) @ApiOperation(value = "", notes = "Get all transactions", response = Transaction.class, responseContainer = "List", tags = {}) @ApiResponses( value = { @ApiResponse(code = 200, message = "OK", response = Transaction.class, responseContainer = "List"), @ApiResponse(code = 400, message = "Bad Request", response = Transaction.class, responseContainer = "List"), @ApiResponse(code = 404, message = "Not Found", response = Transaction.class, responseContainer = "List"), @ApiResponse(code = 500, message = "Internal Server Error", response = Transaction.class, responseContainer = "List") }) @Override public Response transactionsGet( @HeaderParam("tok") String tok, @QueryParam("param1") Integer param1, @QueryParam("param2") String param2, @QueryParam("param3") OffsetDateTime param3, @QueryParam("param4") OffsetDateTime param4, @QueryParam("param5") Integer param5, @QueryParam("param6") Integer param6, @QueryParam("param7") String param7) { return Response.ok().entity("Success!").build(); } 

TransactionsApi is a generated implementation using the Swagger Codegen, just like the Transaction model class. I have a few other functions in this class, but whenever I leave the GET /transactions function without commenting, I get the following error:

 WARN [Thread-1] (ContextHandler.java:2175) - unavailable 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.product.rest.impl.v1.TransactionsApiImpl.transactionsGet(java.lang.String,java.lang.Integer,java.lang.String,java.time.OffsetDateTime,java.time.OffsetDateTime,java.lang.Integer,java.lang.Integer,java.lang.String) at index 3.; source='ResourceMethod{httpMethod=GET, consumedTypes=[application/json], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.product.rest.impl.v1.TransactionsApiImpl, handlerConstructors=[ org.glassfish.jersey.server.model.HandlerConstructor@7df78e88 ]}, definitionMethod=public javax.ws.rs.core.Response 

All other similar questions I found relate to MultiPart Data and file MultiPart Data , while I make a simple GET request. Other functions that also use the javax.ws.rs.code.Response class javax.ws.rs.code.Response not have this problem, and the server starts normally.

I noticed that the problem occurs when the OffsetDateTime class is in the parameters (i.e. param3 and param4 ), but I could not figure out why. Moreover, the OffsetDateTime was chosen by Swagger Codegen, and I do not want to change it, seeing how I will have to change each derived file after each recovery of my sources.

Has anyone had this problem before with REST and OffsetDateTime ?

+7
source share
1 answer

All other similar questions I found are related to MultiPart Data and file upload

It's related. Error - A common error you get when Jersey cannot validate the resource model. Part of the resource model is the method parameters. Jersey has a system for determining which parameters it can handle and which ones it cannot. In your case, it does not know how to handle OffsetDateTime .

There are a number of rules that you must follow in order to use non-basic types as @QueryParam (and all other @XxxParams such as @PathParam and @FormParam , etc.):

  1. Be a primitive type
  2. Create a constructor that takes a single String argument
  3. Have a static method called valueOf or fromString that takes a single String argument (see, for example, Integer.valueOf(String) )
  4. Have a registered ParamConverterProvider JAX-RS implementation that returns an instance of ParamConverter capable of converting "from string" to 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, OffsetDateTime , dropping the list; it is not primitive; it does not have a String constructor; it does not have a static valueOf or fromString

Thus, in principle, the only option is to implement ParamConverter/ParamConverterProvider for it. The main setup looks like this:

 @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 give you the String value of the query parameter, and your task is to create it and return it.

Then just register the OffsetDateTimeProvider app with the app. If you use packet scanning, you must obtain and register it automatically from the @Provider annotation.

I don’t use Swagger, so I don’t know if they already offer something similar, but it seems strange that they will generate it for you, and have no way to make it work. I know that Jersey 3 will have Java 8 support, but who knows when it will be released.

+9
source

All Articles