Параметр запроса внедрения зависимостей с CDI и JSF2
При использовании CDI и JSF2 Как можно ввести параметр запроса HTTP в bean-компонент?
1 ответ
ПОДСКАЗКА: прежде чем читать дальше, посмотрите на http://showcase.omnifaces.org/components/param. Сделай сам, вероятно, устарело, видя, как сегодня омнифас является стандартом де-факто. Я бы, наверное, не написал бы это, если бы в то время это было у omnifaces
CDI не решает специализированных проблем, таких как внедрение параметра запроса. Это должно быть решено с помощью расширений.
Это уже предусмотрено припоем. http://docs.jboss.org/seam/3/solder/latest/reference/en-US/html/injectablerefs.html
Вероятно, он будет включен в Deltaspike 0.4-инкубационный или аналогичный.
Тем не менее, требуемый код довольно прост для реализации самостоятельно. Пример ниже:
Аннотация для использования для точки впрыска (например, 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;
Обратите внимание, что это не будет работать для сервлета или аналогичного, так как требует доступа к FacesContext. В этих случаях нужно обернуть инъекцию, например, бобом @RequesScoped. Вместо этого вы вводите этот боб.