我一直在寻找解决问题的方法,但我无法让它发挥作用。我想将我的Weld托管服务注入ConstraintValidator,该ConstraintValidator用于验证发布到我的JAX-RS Rest-Service的User-Object。一切都部署到glassfish 4.1服务器上。
我有这样的服务
@ApplicationScoped
public class UserService {
}
我希望将它注入像这样的
这样的ConstraintValidatorpublic class UniqueUserNameValidator implements ConstraintValidator<UniqueUserName, ApiUser> {
@Inject
private UserService service;
@Override
public void initialize(UniqueUserName constraintAnnotation) {
}
@Override
public boolean isValid(ApiUser value, ConstraintValidatorContext context) {
return service.getByUserName(value.getUserName()) == null;
}
}
REST资源看起来像这样
@Path("users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {
@Inject
UserService userService;
@POST
public Response createUser(@Valid ApiUser apiUser) {
ApiRepresentation created = userService.create(apiUser);
return Response.created(createURL(created)).build();
}
}
当我发布json用户对象时,我得到以下异常:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=UserService,parent=UniqueUserNameValidator,qualifiers={},position=-1,optional=false,self=false,unqualified=null,173822971)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:947)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:902)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:977)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:968)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:173)
我知道jersey使用hk2作为DI提供程序,而ConstraintValidator是使用InjectingConstraintValidatorFactory创建的,而here反过来使用ResourceContext。由于HK2对我的WELD容器托管bean一无所知,因此在创建ConstraintValidator时无法注入正确的服务。
为了解决这个问题,我正在寻找
a)使用自定义ConstraintValidatorFactory提供JAX-RS(最好是没有依赖于jersey的纯JAX-RS方式)来创建验证器的方法。
或 b)强制球衣使用WELD作为DI提供者或告诉hk2拾取所有容器管理bean而不手动将每个bean添加到hk2的方法。 我不知道如何使用建议的桥http://lib.stat.cmu.edu/R/CRAN/src/contrib。
我感谢任何帮助。
干杯
答案 0 :(得分:1)
我还遇到过Jersey 2.25.x,Weld 2.4.x和Tomcat 8.x这个问题,并且没有找到@Inject
的正确解决方案。
作为一种解决方法,我使用以下方式以编程方式查找bean实例:
SomeSortOfBean bean = CDI.current().select(SomeSortOfBean.class).get();
答案 1 :(得分:0)
您是否有可能更改项目的基础JAX-RS实施?
当我遇到同样的问题时,我只是从Jersey切换到RestEasy(完全认证的JAX-RS实现)。 http://resteasy.jboss.org/
更改实现非常简单:只需通过您最喜欢的构建自动化工具(我使用gradle)包含dependy:
compile 'org.jboss.resteasy:resteasy-servlet-initializer:3.0.11.Final'
此外,要使CDI工作,请包括resteasy-cdi JAX-RS CDI桥:
compile 'org.jboss.resteasy:resteasy-cdi:3.0.11.
最后,如果您想要相同的JSON格式,请包含resteasy-jackson-provider:
compile 'org.jboss.resteasy:resteasy-jackson-provider:3.0.11.Final'
最后,改用resteasy让我比尝试实施泽西修复要少得多。