Java – use joda datetime as the Jersey parameter?
I want to use joda's datetime query parameter in Jersey, but it's not out of the box in Jersey I assume that implementing an injectableprovider is the right way to add datetime support
Can someone point out that I have a good implementation of the injectableprovider of datetime? Or is there a recommended alternative? I know I can convert dates or strings from my code, but this seems to be a smaller solution
thank you.
Solution:
I modified Gili's answer and used Jax - RS instead of Guice's @ context injection mechanism
Update: if uriinfo is not injected into your service method parameters, it may not work properly
import com.sun.jersey.core.spi.component.ComponentContext; import com.sun.jersey.spi.inject.Injectable; import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider; import java.util.List; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Provider; import org.joda.time.DateTime; /** * Enables DateTime to be used as a QueryParam. * <p/> * @author Gili Tzabari */ @Provider public class DateTimeInjector extends PerRequestTypeInjectableProvider<QueryParam,DateTime> { private final UriInfo uriInfo; /** * Creates a new DateTimeInjector. * <p/> * @param uriInfo an instance of {@link UriInfo} */ public DateTimeInjector( @Context UriInfo uriInfo) { super(DateTime.class); this.uriInfo = uriInfo; } @Override public Injectable<DateTime> getInjectable(final ComponentContext cc,final QueryParam a) { return new Injectable<DateTime>() { @Override public DateTime getValue() { final List<String> values = uriInfo.getQueryParameters().get(a.value()); if( values == null || values.isEmpty()) return null; if (values.size() > 1) { throw new WebApplicationException(Response.status(Status.BAD_REQUEST). entity(a.value() + " may only contain a single value").build()); } return new DateTime(values.get(0)); } }; } }
Solution
This is an implementation that depends on Guice You can make minor modifications using different Syringes:
import com.google.inject.Inject; import com.sun.jersey.core.spi.component.ComponentContext; import com.sun.jersey.spi.inject.Injectable; import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider; import java.util.List; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Provider; import org.joda.time.DateTime; /** * Enables DateTime to be used as a QueryParam. * <p/> * @author Gili Tzabari */ @Provider public class DateTimeInjector extends PerRequestTypeInjectableProvider<QueryParam,DateTime> { private final com.google.inject.Provider<UriInfo> uriInfo; /** * Creates a new DateTimeInjector. * <p/> * @param uriInfo an instance of {@link UriInfo} */ @Inject public DateTimeInjector(com.google.inject.Provider<UriInfo> uriInfo) { super(DateTime.class); this.uriInfo = uriInfo; } @Override public Injectable<DateTime> getInjectable(final ComponentContext cc,final QueryParam a) { return new Injectable<DateTime>() { @Override public DateTime getValue() { final List<String> values = uriInfo.get().getQueryParameters().get(a.value()); if (values.size() > 1) { throw new WebApplicationException(Response.status(Status.BAD_REQUEST). entity(a.value() + " may only contain a single value").build()); } if (values.isEmpty()) return null; return new DateTime(values.get(0)); } }; } }
No Guice binding@ Provider is a Jax - RS annotation Guice only needs to inject uriinfo and Jersey Guice to provide binding