@Queryparam - Type Date

Asked

Viewed 847 times

1

I’m having trouble sending a Date, it’s always null on my Rest controller. I’ve tried it without $.param as well and it didn’t roll.

My $Scope.filter.Begin is already going in Date format on request and the value is correct.

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

I am 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 that way:

@GET
@Path("/loadEntriesByFilter")
public Collection<EntryPojo> loadEntriesByFilter(@QueryParam("filterBegin")
       Date data){
  • you want to send the current date?

  • I have two date inputs the user chooses the date he wants to filter. In the case there only has a date parameter that is filterBegin, because I’m only testing with a parameter first. ?

  • Take a look at this response from the gringos, it might help you: http://stackoverflow.com/a/9522619/2570426

  • Perhaps the problem is related to the date format.

  • I think the link you gave me wouldn’t help my situation. So the format I’m sending is Sun Oct 10 2010 01:00:00 GMT-0200

  • You will have to pass the date as a String and do the conversion in the back-end, ie, change your service to receive a String instead of a Date.

  • I suggest you abandon the Date and migrate to the LocalDate, LocalDateTime or OffsetDateTime, depending on which is more appropriate. See this: http://answall.com/q/177129/132

Show 2 more comments

1 answer

1

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

  1. To be a primitive kind;
  2. Has a builder that accepts only one String as an argument;
  3. Have a static method named fromString or valueOf and accept only one String as an argument;
  4. Have an interface implementation javax.ws.rs.ext.ParamConverterProvider that returns an instance of the interfacejavax.ws.rs.ext.ParamConverter, or;
  5. Be a List<T>, Set<T> or SortedSet<T>, where T satisfy options 2 or 3.

The only criterion that class Date satisfied was the 2, however, as the builder Date(String) was marked as @Deprecated (obsolete), Jersey developers opted for stop supporting him from the Jersey 2.x.

Therefore, 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 (it will depend on how you set up your project. Ex: 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 receive the parameter as a String and, within the method itself, make the conversion to Date.

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

  • I loved your answer, there is a lot of information in it that I didn’t know and that will be very useful to me. + 1

  • @Victorstafusa Thank you so much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.