@吉利,对不起,我没有必要的信誉直接评论你的帖子,但请您:
- 添加用于您的实现import语句?
- 添加一个如何将所有与Guice绑定的例子?
非常感谢您提前。
M.
问题:
我有兴趣做同样的HolySamosa,我用Guice的为好,但我面对的下方的问题。
如果我添加:
bind(DateTimeInjector.class);
在我
GuiceServletContextListener
,我得到:
java.lang.RuntimeException:
The scope of the component class com.foo.mapping.DateTimeInjector must be a singleton
,如果我在DateTimeInjector
类添加@Singleton
,我得到:
GRAVE: The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: Missing dependency for method public java.util.List com.foo.ThingService.getThingByIdAndDate(java.lang.String,org.joda.time.DateTime) at parameter at index 1
SEVERE: Method, public java.util.List com.foo.ThingService.getThingByIdAndDate(java.lang.String,org.joda.time.DateTime), annotated with GET of resource, class com.foo.ThingService, is not recognized as valid resource method.
个装运通知/ SOLUTIONS:
- 注意你用什么注解(不像我)!例如,我实际上使用
@PathParam
而不是@QueryParam
。
- 在您的服务中,您不需要在方法的签名中有
UriInfo uriInfo
。只是功能参数应该足够,它应该工作,无论是否存在UriInfo
。
- Guice需要配置下面才能拿起注射器。
实施例:
// Configure Jersey with Guice:
Map<String, String> settings = new HashMap<String, String>();
settings.put(PackagesResourceConfig.PROPERTY_PACKAGES, "com.foo.mapping");
serve("/*").with(GuiceContainer.class, settings);
完整的解决方案:
import java.util.List;
import javax.ws.rs.PathParam;
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;
import com.google.inject.Inject;
import com.foo.utils.DateTimeAdapter;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
/**
* Enables DateTime to be used as a PathParam.
*/
@Provider
public class DateTimeInjector extends PerRequestTypeInjectableProvider<PathParam, DateTime> {
private final com.google.inject.Provider<UriInfo> uriInfo;
/**
* Creates a new DateTimeInjector.
*
* @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 context, final PathParam annotation) {
return new Injectable<DateTime>() {
@Override
public DateTime getValue() {
final List<String> values = uriInfo.get().getPathParameters().get(annotation.value());
if (values == null) {
throwInternalServerError(annotation);
}
if (values.size() > 1) {
throwBadRequestTooManyValues(annotation);
}
if (values.isEmpty()) {
throwBadRequestMissingValue(annotation);
}
return parseDate(annotation, values);
}
private void throwInternalServerError(final PathParam annotation) {
String errorMessage = String.format("Failed to extract parameter [%s] using [%s]. This is likely to be an implementation error.",
annotation.value(), annotation.annotationType().getName());
throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build());
}
private void throwBadRequestTooManyValues(final PathParam annotation) {
String errorMessage = String.format("Parameter [%s] must only contain one single value.", annotation.value());
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(errorMessage).build());
}
private void throwBadRequestMissingValue(final PathParam annotation) {
String errorMessage = String.format("Parameter [%s] must be provided.", annotation.value());
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(errorMessage).build());
}
private DateTime parseDate(final PathParam annotation, final List<String> values) {
try {
return DateTimeAdapter.parse(values.get(0));
} catch (Exception e) {
String errorMessage = String.format("Parameter [%s] is formatted incorrectly: %s", annotation.value(), e.getMessage());
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(errorMessage).build());
}
}
};
}
}
谢谢,吉利。我没有使用Guice,但我不知道UriInfo是否可以注入JAX-RS的@Context注入? – HolySamosa
是的,@Context适用于注入UriInfo。我还稍微修改了您的代码以处理空日期时间查询参数的情况。我的改编作为对我的问题的编辑发布。谢谢!! – HolySamosa