@ManagedProperty (value = "# {param.id}") в компоненте Scope без запроса - PullRequest
17 голосов
/ 02 января 2011

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

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

А область применения Боба - ViewScope

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

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

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

Арджан взглянул:

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

<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>

Ответы [ 2 ]

38 голосов
/ 02 января 2011

Два способа:

  1. Сделайте запрос bean-объекта ограниченным и добавьте представление, ограниченное одним другим как * @ManagedProperty.

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

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

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

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

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

6 голосов
/ 02 января 2011

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

Они должны быть объявлены в 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>

    <!-- Rest of Facelet here -->   

    </h:body>
</html>

Если вы сейчас запросите эту страницу, будет вызван установщик базового компонента со значением запроса, предоставленным для параметра id.Это работает как для запросов GET, так и (без лиц) 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 также работает.

...