Jsf @#{param}上的ManagedProperty在@ViewScoped中不起作用

Jsf @#{param}上的ManagedProperty在@ViewScoped中不起作用,jsf,jsf-2,view-scope,http-request-parameters,Jsf,Jsf 2,View Scope,Http Request Parameters,我的豆豆有这样一个: @ManagedBean @ViewScoped public class BookBean implements Serializable { @ManagedProperty(value = "#{param.id}") // does not work with @ViewScoped private String id; public void init() { id = FacesContext.ge

我的豆豆有这样一个:

@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;
    }
}
<f:metadata>
    <f:viewParam name="id" value="#{bookBean.id}">
        <f:event type="preRenderView" listener="#{bookBean.init}" />
    </f:viewParam>
</f:metadata> 
目标Facelet具有以下特性:

@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;
    }
}
<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
bean,我发现我必须这样做
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(“id”)
才能获取
id
参数的值

这是使用
@ViewScoped
获取请求参数值的唯一方法吗


有什么想法吗?

视图范围比请求范围更广。只能设置与托管bean的范围相同或更广的属性

只要继续使用。你不应该把它们放在一起


将设置请求参数,
将在设置这些参数后执行侦听器方法


@PostConstruct
在视图范围的bean上也可以正常工作,但它只在bean的构造和所有依赖注入都设置好之后才直接运行(例如
@ManagedProperty
@EJB
@Inject
@Resource
,等等)。但是,
会在此后设置属性,因此它在
@PostConstruct

中不可用。下面是另一种在可视范围bean中获取请求参数的方法。这将是#{param.device}在请求作用域bean中得到的。这样做的优点是在表示层中不需要任何标记

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

@巴卢斯克:那对我不起作用。
id
的值返回null。在这里可以正常工作。什么JSF impl/版本?什么应用服务器?我在Tomcat 7.0.11上用Mojarra 2.0.4创建了一个快速测试用例,通过调用Glassfish 3.1附带的
test.xhtml?id=123
.Mojarra 2.1.0,它可以正常工作。我的getter/setter是为
id
字段=创建的,因此从技术上讲,它应该拾取
f:viewParam>
标记设置的值。您确定已修复错误的嵌套吗?如果嵌套它,那么将在
f:viewParam
之前调用
f:event
@BalusC:Yes,我忘了在
标记之后移动f:event标记。我的错。今天我学到了一些新东西。我可以建议未来的JSF规范由您编写吗,Bauke。您有一项天赋技能,可以将复杂的文档转换为易于理解的演示代码示例。我已经去过很多JSF2站点,包括Sun的同事编写的站点,但是我不能完全理解他们对新JSF2特性的一些解释,比如
。另一方面,你让它看起来很简单。因为你的这种能力,我尊敬你。。。