简体   繁体   English

Jersey Inject Weld管理bean进入ConstraintValidator

[英]Jersey Inject Weld managed bean into ConstraintValidator

I've been searching for hours to find a solution for my problem but I can't get it to work. 我一直在寻找几个小时来找到我的问题的解决方案,但我无法让它工作。 I want to inject my Weld-managed service into a ConstraintValidator that is used to validate a User-Object that is posted to my JAX-RS Rest-Service. 我想将我的Weld托管服务注入ConstraintValidator,该ConstraintValidator用于验证发布到我的JAX-RS Rest-Service的User-Object。 Everything is deployed to a glassfish 4.1 server. 一切都部署到glassfish 4.1服务器。

I have a Service like this 我有这样的服务

@ApplicationScoped
public class UserService {

}

and I want to inject it into a ConstraintValidator like this 我想把它注入像这样的ConstraintValidator

public 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;
    }

}

the REST resource looks like this 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();
    }
}

When I Post a json user object i get the following exception: 当我发布一个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)

I'm aware that jersey uses hk2 as DI provider and the ConstraintValidator is created using the InjectingConstraintValidatorFactory which in return uses the ResourceContext. 我知道jersey使用hk2作为DI提供程序,而ConstraintValidator是使用InjectingConstraintValidatorFactory创建的,而InjectingConstraintValidatorFactory又使用ResourceContext。 Since HK2 doe know nothing about my WELD container managed beans it can not inject the proper service when creating the ConstraintValidator. 由于HK2对我的WELD容器托管bean一无所知,因此在创建ConstraintValidator时无法注入正确的服务。

To fix this I am searching for 为了解决这个问题,我正在寻找

a) A way to provide JAX-RS (preferable a pure JAX-RS way without a dependency to jersey) with a custom ConstraintValidatorFactory to create the validator. a)使用自定义ConstraintValidatorFactory提供JAX-RS(最好是纯粹的JAX-RS方式而不依赖于jersey)来创建验证器的方法。

or b) A way to force jersey to use WELD as the DI provider or tell hk2 to pickup all container managed beans WITHOUT manually adding every single bean to hk2. 或b)强制球衣使用WELD作为DI提供者或告诉hk2拾取所有容器管理的bean而不手动将每个bean添加到hk2的方法。 I have no Idea how to use the bridge proposed here . 我不知道如何使用这里提出的桥梁。

I appreciate any help. 我感谢任何帮助。

Cheers 干杯

I also faced this issue with Jersey 2.25.x, Weld 2.4.x and Tomcat 8.x and haven't found a proper solution with @Inject . 我还遇到了Jersey 2.25.x,Weld 2.4.x和Tomcat 8.x这个问题,并且没有找到适合@Inject解决方案。

As a workaround, I programmatically looked up for the bean instance using: 作为一种解决方法,我使用以下方式以编程方式查找bean实例:

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

Do you have the possibility to change the underlying JAX-RS implementation for your project? 您是否有可能为项目更改基础JAX-RS实施?

When I had the same problem, I just switched from Jersey to RestEasy (fully certified JAX-RS implementation). 当我遇到同样的问题时,我只是从Jersey切换到RestEasy(完全认证的JAX-RS实现)。 http://resteasy.jboss.org/ http://resteasy.jboss.org/

Changing the implementation was easy enough: Just include the dependy through your favorite build automation tool (I use gradle): 更改实现很简单:只需通过您最喜欢的构建自动化工具(我使用gradle)包含dependy:

compile 'org.jboss.resteasy:resteasy-servlet-initializer:3.0.11.Final'

Additionally, to make CDI work, include the resteasy-cdi JAX-RS CDI bridge: 此外,要使CDI工作,请包括resteasy-cdi JAX-RS CDI桥:

compile 'org.jboss.resteasy:resteasy-cdi:3.0.11.

Lastly if you want the same JSON format, include the resteasy-jackson-provider: 最后,如果您想要相同的JSON格式,请包含resteasy-jackson-provider:

compile 'org.jboss.resteasy:resteasy-jackson-provider:3.0.11.Final'

In the end, switching to resteasy gave me a lot less headache than trying to implement a Jersey fix. 最后,切换到resteasy给我带来的麻烦比尝试实施Jersey修复要少得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM