【问题标题】:Weld exception when value for producer annotation is defined定义生产者注释值时的焊接异常
【发布时间】:2016-03-17 23:23:22
【问题描述】:

我尝试从另一个 SO 问题实施解决方案: https://stackoverflow.com/a/10059245/1943765 但并非在所有情况下都有效。

当我将此代码放入 CDI bean 时(bean 代码显示在底部):

@Inject @HttpParam
private String code; 

一切正常。但是当我尝试为 @HttpParam 注释定义值时(所以,不是默认值) Weld 无法启动:

@Inject @HttpParam(value="code")
private String token;

我得到了这个例外:

Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type String with qualifiers @HttpParam
  at injection point [BackedAnnotatedField] @Inject @HttpParam private org.test.site.jsf.beans.request.ActivationBean.token
  at org.test.site.jsf.beans.request.ActivationBean.token(ActivationBean.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
  - Producer Method [String] with qualifiers [@HttpParam @Any] declared as [[BackedAnnotatedMethod] @Produces @HttpParam public org.test.site.cdi.producer.HttpParamProducer.getHttpParameter(InjectionPoint)]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
    ... 4 more

我使用的代码类似于链接的 SO 问题。

自定义@HttpParam注解:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER})
public @interface HttpParam {
    public String value() default "";
}

注解值生产者:

public class HttpParamProducer {

    @Inject
    FacesContext facesContext;

    @Produces
    @HttpParam
    String getHttpParameter(InjectionPoint ip) {
        String name = ip.getAnnotated().getAnnotation(HttpParam.class).value();
        if ("".equals(name)) name = ip.getMember().getName();
        return facesContext.getExternalContext()
                .getRequestParameterMap()
                .get(name);
    }
}

使用它的 CDI bean 类似于:

@Named("activation")
@RequestScoped
public class ActivationBean implements Serializable{

    @Inject
    @HttpParam(value="code")
    private String token;

    // rest of valid class code
}

我也在使用带有 Weld Servlet 2.3.1.Final 的 Tomcat 8 服务器。

那么..我做错了什么? :-/

【问题讨论】:

    标签: jsf cdi http-request-parameters producer


    【解决方案1】:

    您需要将@Nonbinding 添加到您的value 属性中,这样它的值就不必选择调用哪个生产者方法,但允许单个工厂样式生产者检查您的注入点。

    您可能还想查看what is the purpose of @Nonbinding annotation in a Qualifier supposed to be in Java EE7?

    【讨论】:

      【解决方案2】:

      默认情况下,CDI Qualifier 中的属性也用于确定要注入的 bean。

      由于您注入了 @HttpParam(value="code") ,但您的生产者只产生了 @HttpParam(value="")。它们不匹配,CDI 不知道要注入什么。

      要让 CDI 在确定注入哪个 bean 时忽略 CDI Qualifier 中的属性,可以在这些属性上标记@Nonbinding

      @Qualifier
      @Retention(RUNTIME)
      @Target({METHOD, FIELD, PARAMETER})
      public @interface HttpParam {
          @Nonbinding
          public String value() default "";
      }
      

      【讨论】:

        【解决方案3】:

        我迟到了,但是为了其他可能使用这个问题来编写类似的基于参数的注入的人,让我添加这个。

        添加我在上面没有找到的特定内容。我遇到了同样的情况,但风格有所不同。我的 QualifierProducer 方法在一个模块中(比如 injector-module )与我进行注射的那个不同(比如 injected-module)。所有 NonBinding 注释均已给出。

        但是,我只有 injected-module 中的 beans.xml。

        注入失败。

        injector-module 的 META-INF 中添加 beans.xml 就可以了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-12
          • 2013-04-30
          • 1970-01-01
          • 2020-08-22
          • 2023-03-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多