获取GET请求参数到@ViewScoped bean [英] Getting a GET request param into an @ViewScoped bean
问题描述
我有一个(请求范围的)列表,用户可以从中选择PQ(链接列表)。单击或以其他方式输入浏览器时,将显示每个PQ的主页面。每个PQ页面的格式为
I have a (request-scoped) list from which the user may select a "PQ" (list of links). When clicked or otherwise entered into the browser the main page for each PQ shall be displayed. Each PQ's page is of the form
http:// localhost:8080 / projectname / main.jsf?id = 2
首先是PQ bean:
Here's the PQ bean first:
@Named
@ViewScoped
public class PqHome implements Serializable
{
@PersistenceContext(unitName="...")
private EntityManager em;
private Integer id;
private PQ instance;
@PostConstruct
public void init()
{
System.out.println("ID is " + id); // ID from URL param
instance = em.find(PQ.class, id);
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public PQ getInstance()
{
return instance;
}
}
这是main.xhtml:
Here's the main.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
...>
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="id" value="#{pqHome.id}">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<!--f:event type="preRenderView" listener="#{pqHome.init}" /-->
</f:metadata>
</ui:define>
<ui:define name="title">
<h:outputText value="Main" />
</ui:define>
...
</ui:composition>
每当我选择或以其他方式刷新页面/ URL时,我都会得到 NullPointerException
来自 EntityManager
:
Any time I select or otherwise refresh the page/URL I get a NullPointerException
from the EntityManager
:
org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public de.mycomp.myproj.beans.PqHome.init() on de.mycomp.myproj.beans.PqHome@4f0ea68f
at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:595)
...
Caused by: java.lang.IllegalArgumentException: id to load is required for loading
at org.hibernate.event.spi.LoadEvent.<init>(LoadEvent.java:87)
at org.hibernate.event.spi.LoadEvent.<init>(LoadEvent.java:59)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:961)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:957)
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:787)
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:762)
at org.jboss.as.jpa.container.AbstractEntityManager.find(AbstractEntityManager.java:221)
at de.mycomp.myproj.beans.PqHome.init(PqHome.java:47)
... 56 more
[第47行是em。查找(...)]
[Line 47 is em.find(...)]
该行
<f:event type="preRenderView" listener="#{pqHome.init}" />
不会让事情变得更好。我现在非常绝望。
doesn't make things any better. I'm pretty desparate now.
如何将URL GET请求参数传入 @ViewScoped
bean?
How do you get URL GET request params into an @ViewScoped
bean?
注意:我敢打赌这不是一件小事。有可能我在概念上做错了,所以欢迎任何有关如何改进的提示。我觉得我需要选择 @ViewScoped
,因为在该页面上会有更复杂的基于AJAX的GUI,我真的希望通过URL GET参数来访问它。
Note: I bet it's not a trivial thing to do. Chances are I'm doing something wrong here conceptually, so any tips on how to improve are welcome. I felt that I needed to choose @ViewScoped
because there will be more complex AJAX-based GUI on that page which I'd really like to keep accessible via URL GET params.
谢谢
推荐答案
@PostConstruct <在bean构造和所有依赖注入(例如
@PersistenceContext
, @EJB)之后,直接调用
, @ManagedProperty
, @Inject
,etc..etc ..)。
The @PostConstruct
is invoked directly after bean's construction and all dependency injection (such as @PersistenceContext
, @EJB
, @ManagedProperty
, @Inject
, etc..etc..).
< f:viewParam>
在更新模型值阶段设置其值,该阶段远远超过(post)建造豆子。因此,在 @PostConstruct
内,尚未设置< f:viewParam>
值。那时它仍然是 null
。
The <f:viewParam>
sets its value during the update model values phase, which is far after (post)construction of the bean. So inside the @PostConstruct
the <f:viewParam>
value is simply not yet been set. It'll be still null
at that point.
你已经接近< ; f:event type =preRenderView>
,但您必须删除 @PostConstruct
注释。
You're close with <f:event type="preRenderView">
, but you have to remove the @PostConstruct
annotation.
所以:
<f:viewParam name="pq" value="#{pqHome.id}">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<f:event type="preRenderView" listener="#{pqHome.init}" />
with
private Integer id;
public void init() {
instance = em.find(PQ.class, id);
}
不相关对于具体问题,我建议使用转换器
代替。另请参见 JSF 2.0中的通信 - 转换和验证GET请求参数。
Unrelated to the concrete problem, I'd suggest to use a Converter
for this instead. See also Communication in JSF 2.0 - Converting and validating GET request parameters.
此外,组合 @Named @ViewScoped
将无法按预期工作。特定于JSF的 @ViewScoped
仅与JSF特定的 @ManagedBean
组合使用。您的CDI特定 @Named
的行为类似于 @RequestScoped
。使用 @ManagedBean
而不是 @Named
或使用CDI特定的 @ConversationScoped
而不是 @ViewScoped
。
Also the combination @Named @ViewScoped
won't work as intended. The JSF-specific @ViewScoped
works in combination with JSF-specific @ManagedBean
only. Your CDI-specific @Named
will behave like @RequestScoped
this way. Either use @ManagedBean
instead of @Named
or use CDI-specific @ConversationScoped
instead of @ViewScoped
.
这篇关于获取GET请求参数到@ViewScoped bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!