@QueryParam - Date Type

1

I'm having trouble sending a Date, it's always null in my controller rest. I've tried it without $ .param too and it has not rolled.

My $ scope.filter.begin is already going in Date format in the request and the value is correct.

How do I send my data of type Date correctly? Should I use another annotation other than @QueryParam?

I'm sending a date to REST as follows:

$scope.doFilter = function(){
    $http({
        method: "GET",
        url: "rest/entry/loadEntriesByFilter",
        data: $.param({filterBegin: $scope.filter.begin}, true)
    }).then(function sucessCallback(response){
        console.log(response);
    }),
    function error(response){
        console.log(response);
    }       
}

And in my Controller I'm getting this way:

@GET
@Path("/loadEntriesByFilter")
public Collection<EntryPojo> loadEntriesByFilter(@QueryParam("filterBegin")
       Date data){
    
asked by anonymous 24.02.2017 / 13:58

1 answer

1

According to the Jersey documentation , for a class to be supported as a @QueryParam , it must meet the following requirements:

  • Being a primitive type;
  • Has a constructor that accepts only String as an argument;
  • Have a static method whose name is fromString or valueOf and accept only String as argument;
  • Have an implementation of the javax.ws.rs.ext.ParamConverterProvider interface that returns an instance of the javax.ws.rs.ext.ParamConverter interface, or;
  • Be a List<T> , Set<T> or SortedSet<T> , where T satisfies options 2 or 3.
  • The only criterion that the Date class satisfied was 2, but since the Date(String) constructor was marked as @Deprecated (obsolete), the Jersey developers opted for stop supporting it from Jersey 2.x.

    So the only option left is to implement a javax.ws.rs.ext.ParamConverterProvider and register it. Example:

    public class DateParamProvider implements ParamConverterProvider {
    
        @SuppressWarnings("unchecked")
        @Override
        public <T> ParamConverter<T> getConverter(final Class<T> rawType, final Type genericType,
                                                  final Annotation[] annotations) {
            if (rawType != Date.class) {
                return null;
            }
            //TODO teste se esse é realmente o formato utilizado pelas suas datas
            final DateFormat format = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z");
    
            return (ParamConverter<T>) new ParamConverter<Date>() {
                @Override
                public Date fromString(final String value) {
                    try {
                        return format.parse(value);
                    } catch (final ParseException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
    
                @Override
                public String toString(final Date value) {
                    return format.format(value);
                }
            };
        }
    }
    

    And register it (this will depend on how you configured your project, eg via javax.ws.rs.core.Application , web.xml or org.glassfish.jersey.server.ResourceConfig ):

    javax.ws.rs.core.Application

    //TODO ajuste para o caminho da sua aplicação
    @ApplicationPath("/")
    public class InitApp extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<>();
            classes.add(SuaClasseAnotadoComPath.class);      //Sua classe anotado com @Path
            classes.add(DateParamProvider.class);
            return classes;
        }
    }
    

    org.glassfish.jersey.server.ResourceConfig

    //TODO ajuste para o caminho da sua aplicação
    @ApplicationPath("/")
    public class InitApp extends ResourceConfig {
    
        public InitApp() {
            register(SuaClasseAnotadoComPath.class);        //Sua classe anotado com @Path
            register(DateParamProvider.class);
        }
    }
    

    Another simpler solution would be to get the parameter as a String and, within the method itself, to convert to Date .

    Note: If there is no obligation to use the Date class, take a look at new classes inserted in Java 8 from the java.time package, in this case in particular, in the ZonedDateTime class (even with this class, use of an implementation of javax.ws.rs.ext.ParamConverterProvider is still required).

        
    24.02.2017 / 20:44