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

后端 未结 1 1127
闹比i
闹比i 2020-12-11 03:01

I have the following GET REST method:

import java.time.OffsetDateTime;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.         


        
相关标签:
1条回答
  • 2020-12-11 03:49

    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.

    0 讨论(0)
提交回复
热议问题