Параметр запроса внедрения зависимостей с 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. Вместо этого вы вводите этот боб.

Другие вопросы по тегам