依赖注入请求参数与CDI和JSF2

Kar*_*dén 7 cdi jsf-2 http-request-parameters

使用CDI和JSF2时如何将HTTP请求参数注入bean中?

Kar*_*dén 19

提示: 在阅读之前,请先查看http://showcase.omnifaces.org/cdi/Param.看看omnifaces今天是一个事实上的标准,你自己也可能已经过时了.如果omnifaces当时有这个,我可能不会写这个

CDI无法解决注入请求参数等特殊问题.这应该通过扩展来解决.

这已经由焊料提供.http://docs.jboss.org/seam/3/solder/latest/reference/en-US/html/injectablerefs.html

它可能包含在Deltaspike 0.4-incubating或类似的中.

也就是说,所需的代码实现起来相当简单.示例如下:

用于注入点的注释(例如private String myParam;)

import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;


@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER })
public @interface RequestParam {
    @Nonbinding
    public String value() default "";
}
Run Code Online (Sandbox Code Playgroud)

现在我们有了注释,但我们不能只是要求容器依赖注入@RequestParam- 我们显然需要一个实现.

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.faces.context.FacesContext;
import javax.inject.Inject;

public class RequestParamProducer implements Serializable {

    private static final long serialVersionUID = -4260202951977249652L;
    @Inject
    FacesContext facesContext;

    // Producer for @RequestParam
    @Produces
    @RequestParam
    String getRequestParameter(InjectionPoint ip) {
        String name = ip.getAnnotated().getAnnotation(RequestParam.class)
                .value();

        if ("".equals(name))
            name = ip.getMember().getName();

        return facesContext.getExternalContext().getRequestParameterMap()
                .get(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

那么它是怎样工作的?很简单,它首先检查你是否确实指定了你想要的参数@Requestparam("longAndTerribleFieldNameBestToSpecify");

如果没有,它将使用fieldName.因此,如果您注释了一个名为setMyInstance的setter,它将查找名为setMyInstance的参数.

正常的用例是拥有一个String变量,其名称与您想要的参数完全相同.

请注意,我们注入FacesContext,也必须生成.FacesContext生成器可能如下所示:

class FacesContextProducer {

   @Produces @RequestScoped FacesContext getFacesContext() {

      return FacesContext.getCurrentInstance();

   }

}
Run Code Online (Sandbox Code Playgroud)

最终用途:

@Inject
@RequestParam
private String session_secret;
Run Code Online (Sandbox Code Playgroud)

请注意,这不适用于Servlet或类似的,因为它需要访问FacesContext.在这些情况下,需要使用例如@RequesScoped的bean来包装注入.你注入了那个bean.