Jersey Inject Weld管理bean进入ConstraintValidator

我一直在寻找几个小时来找到我的问题的解决方案,但我无法让它工作。 我想将我的Weld托管服务注入ConstraintValidator,该ConstraintValidator用于validation发布到我的JAX-RS Rest-Service的User-Object。 一切都部署到glassfish 4.1服务器。

我有这样的服务

@ApplicationScoped public class UserService { } 

我想把它注入像这样的ConstraintValidator

 public class UniqueUserNameValidator implements ConstraintValidator { @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用户对象时,我得到以下exception:

 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创建的,而InjectingConstraintValidatorFactory又使用ResourceContext。 由于HK2对我的WELD容器托管bean一无所知,因此在创建ConstraintValidator时无法注入正确的服务。

为了解决这个问题,我正在寻找

a)使用自定义ConstraintValidatorFactory提供JAX-RS(最好是纯粹的JAX-RS方式而不依赖于jersey)来创建validation器的方法。

或b)强制jersey使用WELD作为DI提供者或告诉hk2拾取所有容器管理bean而不手动将每个bean添加到hk2的方法。 我不知道如何使用这里提出的桥梁。

我感谢任何帮助。

干杯

我还遇到了Jersey 2.25.x,Weld 2.4.x和Tomcat 8.x这个问题,并且没有找到适合@Inject解决方案。

作为一种解决方法,我使用以下方式以编程方式查找bean实例:

 SomeSortOfBean bean = CDI.current().select(SomeSortOfBean.class).get(); 

您是否有可能为项目更改基础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给我带来的麻烦比尝试实施Jersey修复要少得多。