Jersey 将 Weld 托管 bean 注入 ConstraintValidator

2024-05-10

我已经花了几个小时寻找解决方案来解决我的问题,但我无法让它发挥作用。我想将 Weld 管理的服务注入 ConstraintValidator 中,该 ConstraintValidator 用于验证发布到 JAX-RS Rest-Service 的用户对象。一切都部署到 glassfish 4.1 服务器上。

我有这样的服务

@ApplicationScoped
public class UserService {

}

我想将它注入到像这样的 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;
    }

}

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 是使用注入ConstraintValidatorFactory https://github.com/jersey/jersey/blob/master/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/InjectingConstraintValidatorFactory.java作为回报,它使用 ResourceContext。由于 HK2 对我的 WELD 容器托管 bean 一无所知,因此在创建 ConstraintValidator 时无法注入正确的服务。

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

a) 一种通过自定义 ConstraintValidatorFactory 提供 JAX-RS(最好是不依赖于 jersey 的纯 JAX-RS 方式)来创建验证器的方法。

或者 b) 强制 jersey 使用 WELD 作为 DI 提供程序或告诉 hk2 拾取所有容器管理的 Bean 的方法,而无需手动将每个 Bean 添加到 hk2。 我不知道如何使用建议的桥here https://stackoverflow.com/questions/21295589/cdi-interceptor-injected-into-a-jersey-rs-serviceresource-not-working .

我很感激任何帮助。

Cheers


我在 Jersey 2.25.x、Weld 2.4.x 和 Tomcat 8.x 中也遇到了这个问题,但尚未找到正确的解决方案@Inject.

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

SomeSortOfBean bean = CDI.current().select(SomeSortOfBean.class).get();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jersey 将 Weld 托管 bean 注入 ConstraintValidator 的相关文章

随机推荐