生成器注释的值定义时的焊接异常

时间:2015-12-11 22:50:58

标签: jsf cdi http-request-parameters producer

我尝试从另一个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服务器。

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

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

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

由于您注入@HttpParam(value="code"),但您的制作人只生成@HttpParam(value="")。它们不匹配,CDI不知道注射什么。

要在确定要注入的bean时在CDI限定符中生成CDI忽略属性,可以在这些属性上标记@Nonbinding

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

答案 2 :(得分:0)

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

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

但是,我只在 injector-module 中有 beans.xml。

注入失败。

import time from urllib.parse import urlencode import requests from bs4 import BeautifulSoup query_string = { "p_p_id": "petSearch2016_WAR_ptlPetRehomingPortlets", "p_p_lifecycle": 1, "p_p_state": "normal", "p_p_mode": "view", "_petSearch2016_WAR_ptlPetRehomingPortlets_action": "search", } payload = { 'noPageView': 'false', 'animalType': 'DOG', 'freshSearch': 'false', 'arrivalSort': 'false', 'previousAnimalType': '', 'location': 'WC2N5DU', 'previousLocation': '', 'prevSearchedPostcode': '', 'postcode': 'WC2N5DU', 'searchedLongitude': '-0.1282688', 'searchedLatitude': '51.5072106', } def make_cookies(cookie_dict: dict) -> str: return "; ".join(f"{k}={v}" for k, v in cookie_dict.items()) with requests.Session() as connection: main_url = "https://www.rspca.org.uk" connection.headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) " \ "AppleWebKit/537.36 (KHTML, like Gecko) " \ "Chrome/90.0.4430.212 Safari/537.36" r = connection.get(main_url) cookies = make_cookies(r.cookies.get_dict()) additional_string = f"; cb-enabled=enabled; " \ f"LFR_SESSION_STATE_10110={int(time.time())}" post_url = f"https://www.rspca.org.uk/findapet?{urlencode(query_string)}" connection.headers.update( { "cookie": cookies + additional_string, "referer": post_url, "content-type": "application/x-www-form-urlencoded", } ) response = connection.post(post_url, data=urlencode(payload)).text dogs = BeautifulSoup(response, "lxml").find_all("a", class_="detailLink") print("\n".join(f"{main_url}{dog['href']}" for dog in dogs)) 的 META-INF 中添加 beans.xml 就成功了。