使用 CDI 和 JSF2 时如何将 HTTP 请求参数注入到 bean 中?
1 回答
提示: 在进一步阅读之前,请先查看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 "";
}
现在我们有了注解,但我们不能只要求容器依赖注入@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);
}
}
那么它是怎样工作的?很简单,它首先检查您是否指定了您想要的参数,如@Requestparam("longAndTerribleFieldNameBestToSpecify")
;
如果您不这样做,它将使用 fieldName。因此,如果您注释了一个名为 setMyInstance 的设置器,它将寻找一个名为 setMyInstance 的参数。
正常的用例是有一个字符串变量,其名称与您想要的参数完全一样。
请注意,我们注入 FacesContext,它也必须产生。FacesContext 生产者可能如下所示:
class FacesContextProducer {
@Produces @RequestScoped FacesContext getFacesContext() {
return FacesContext.getCurrentInstance();
}
}
最终用途:
@Inject
@RequestParam
private String session_secret;
请注意,这不适用于 Servlet 或类似的,因为它需要访问 FacesContext。在这些情况下,需要使用例如 @RequesScoped 的 bean 来包装注入。你注入那个bean。