@ManagedProperty на # {param} не работает в @ViewScoped - PullRequest
2 голосов
/ 16 апреля 2011

У моего бина есть это:

@ManagedBean
@ViewScoped
public class BookBean implements Serializable
{       
    @ManagedProperty(value = "#{param.id}") // does not work with @ViewScoped
    private String id;

    public void init()
    {
        id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
        if (id != null) {
            System.out.println("ID: " + id);
            currentBook = bookService.find(id);
        }
    }

    @PostConstruct
    public void post()
    {   
        // does not work with @ViewScoped
        System.out.println("ID: " + id);
        currentBook = bookService.find(id);    
    }

    public String getId() {
        return id;
    } 

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

И у Facelet получателя есть это:

<f:metadata>
    <f:viewParam name="id" value="#{bookBean.id}">
        <f:event type="preRenderView" listener="#{bookBean.init}" />
    </f:viewParam>
</f:metadata> 

При тестировании я заметил, что @ManagedProperty и @PostConstruct работают толькос @RequestScoped бобом.

Для bean-компонента @ViewScoped я обнаружил, что мне нужно сделать это FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"), чтобы получить значение параметра id.

Это единственный способ получить параметр запросазначение с @ViewScoped?

Есть мысли?

Ответы [ 2 ]

5 голосов
/ 16 апреля 2011

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

Просто продолжайте использовать <f:viewParam> с <f:event>.Вы не должны только вкладывать их друг в друга.

<f:metadata>
    <f:viewParam name="id" value="#{bookBean.id}" />
    <f:event type="preRenderView" listener="#{bookBean.init}" />
</f:metadata> 

с

@ManagedBean
@ViewScoped
public class BookBean implements Serializable {

    private String id;

    public void init() {
        if (id != null) {
            currentBook = bookService.find(id);
        }
    }

    // ...
}

<f:viewParam> установит параметр запроса, а <f:event> выполнит метод слушателя после установкииз этих параметров.

@PostConstruct прекрасно работает и на bean-объектах видимости, но он запускается только после построения bean-компонента и установки всех зависимостей (например, @ManagedProperty, @EJB, @Inject, @Resource и т. Д.).Однако <f:viewParam> устанавливает свойство после этого, поэтому оно не доступно в @PostConstruct.

1 голос
/ 16 мая 2011

Вот еще один метод для получения параметра запроса внутри bean-компонента ViewScoped. Это будет то, что # {param.device} получит в бине RequestScoped. Преимущество этого состоит в том, что на уровне представления не требуется никаких тегов.

private int deviceID;
public int getDeviceID() {
    if (deviceID == 0) {
        String s = FacesContext.getCurrentInstance().getExternalContext().
                getRequestParameterMap().get("device");
        try {
            deviceID = Integer.parseInt(s);
        } catch (NumberFormatException nfe) {
        }
    }
    return deviceID;
}
...