@ManagedProperty(value = "# {param.id}" ) в области без запроса Scope Bean

Мне нужно передать параметр (POST) в @managedBean, я использовал управляемые свойства следующим образом:

@ManagedProperty(value = "#{param.id}")
private int id;

И масштабом Bean является ViewScope

Я получаю эту ошибку:

Невозможно создать управляемый Bean квитанцию. Были обнаружены следующие проблемы: - область действия объекта, на который ссылается выражение # {param.id}, запрос, короче, чем область видимости beans, с которой ссылается

Что я могу сделать?

arjan посмотрите:

Моя страница:   Название фонаря

<form method="post" action="faces/index.xhtml">
  <input name="id" value="4" />
  <input type="submit" value="submit" />
</form>

<h:form>
  <h:commandLink value="click" action="index">
    <f:param id="id" name="id" value="20"/>
  </h:commandLink>
</h:form>

Ответ 1

Два способа:

  • Сделайте запрос bean областью видимости и добавьте видимый вид в качестве другого @ManagedProperty.

    @ManagedBean
    @RequestScoped
    public class RequestBean {
    
        @ManagedProperty(value="#{param.id}")
        private Integer id;
    
        @ManagedProperty(value="#{viewBean}")
        private ViewBean viewBean;
    }
    

    Область видимости bean доступна во время @PostConstruct и методов действия с запросом bean. Вам нужно только иметь в виду, что id может потеряться, если вы выполняете обратную передачу в том же представлении без параметра.

  • Или возьмите его вручную из карты параметров запроса во время инициализации bean.

    @ManagedBean
    @ViewScoped
    public class ViewBean {
    
        private Integer id;
    
        @PostConstruct
        public void init() {
            id = Integer.valueOf(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"));       
        }
    }
    

    Таким образом, начальная id доступна во всей области обзора.

Ответ 2

В качестве альтернативы захвату параметров непосредственно из запроса в вашем bean вы можете использовать view parameters.

Они должны быть объявлены на Facelet, где вы используете управляемый bean следующим образом:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
    <h:body>

    <f:metadata>
        <f:viewParam id="id" name="id" value="#{myBean.id}" />        
    </f:metadata>

    <!-- Rest of Facelet here -->   

    </h:body>
</html>

Если вы сейчас запросите эту страницу, будет вызван установщик резервной копии bean со значением запроса, предоставленным для параметра id. Это работает для запросов GET и (non-faces) POST.

Преимущество состоит в том, что здесь вы можете использовать стандартные JSF-преобразователи и валидаторы. Конечно, если ваш управляемый bean не привязан к определенному виду, это решение менее идеально.

Небольшая особенность, о которой следует помнить, заключается в том, что при выполнении обратной передачи нормального лица после первоначального запроса, который предоставил параметр вида, установщик в вашем bean будет вызываться снова, даже если отображается bean область и никакое новое значение явно не предусмотрено.

Чтобы проверить, что это работает, я использовал следующие управляемые bean:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;

@ManagedBean
@ViewScoped
public class MyBean {

    Long id;

    @PostConstruct
    public void test() {
        System.out.println("post construct called");
    }

    public void actionMethod(ActionEvent event) {       
        System.out.println("action called");        
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

И следующий Facelet:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
    <h:body>

        <f:metadata>
            <f:viewParam id="id" name="id" value="#{myBean.id}" />        
        </f:metadata>

        <h:outputText value="#{myBean.id}"/>

        <h:form>
            <h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
        </h:form>

        <form method="post">
            <input name="id" value="4" />
            <input type="submit" value="submit" />
        </form>

    </h:body>
</html>

Введите номер в поле ввода и нажмите кнопку отправки. Если номер напечатан на экране, тест прошел успешно. Обратите внимание, что вторая форма является регулярной формой и не публикует какое-либо состояние JSF. Я тестировал это на JBoss AS 6, и он работает. Также работает проверка параметра id как параметра GET.