【问题标题】:JSF 2.0 view parameters to pass objectsJSF 2.0 视图参数传递对象
【发布时间】:2012-01-26 10:03:56
【问题描述】:

我正在尝试将一个对象从一个页面传递到另一个页面,其中每个页面都处于不同的视图中。

在第一页我有一个输入文本,其中 myBean 是一个 ViewScoped Bean,而 name 是一个对象。 <h:inputText value="#{myBean.name}"/>

第二页包含,
<f:metadata>
<f:viewParam name="userId" value="#{myBean.name}"/>
</f:metadata>

我收到错误 Conversion Error setting value mypackage.myBean@257100b' for 'null Converter'。 我们可以传递字符串值以外的对象来查看参数吗?

【问题讨论】:

  • 顺便说一句,在没有转换器的情况下在<h:inputText> 中拥有该值是非常令人困惑的。提交带有该字段的 POST 表单时,您会遇到完全相同的问题。

标签: jsf-2 viewparams


【解决方案1】:

是的,你可以。您只需要提供一个转换器,它可以在#{myBean.name} 后面的对象类型的字符串表示形式和真实对象之间进行转换。字符串表示通常是所讨论对象的唯一技术/自然标识符。比如表的PK。它必须是字符串,因为 HTTP 请求参数只能是字符串。您不能在 URL 中传递复杂的 Java 对象。 URL 只是字符串。

这是一个启动示例:

例如初始视图中的以下内容:

<h:link value="Edit" outcome="edit">
    <f:param name="id" value="#{personViewer.person.id}" />
</h:link>

(生成&lt;a href="edit.xhtml?id=123"&gt;Edit&lt;/a&gt;

以及链接视图中的以下内容:

<f:metadata>
    <f:viewParam name="id" value="#{personEditor.person}"
        converter="#{personConverter}" converterMessage="Bad request. Unknown person."
        required="true" requiredMessage="Bad request. Please use a link from within the system."
    />
</f:metadata>
<h:messages />

使用此转换器

@ManagedBean
@RequestScoped
public class PersonConverter implements Converter {

    @EJB
    private PersonService personService;

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return String.valueOf(((Person) value).getId());
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return personService.find(Long.valueOf(value));
    }

}

(过于简单;省略了所有空/数字检查,但你明白了)

另见:


Update 根据 cmets,您实际上想要触发 POST 请求。你根本不需要&lt;f:viewParam&gt;。它仅用于设置/验证/转换 GET 请求参数。尝试序列化整个对象也毫无意义。只需使用@ManagedProperty

例如

@ManagedBean
@ViewScoped
public class PersonEditor implements Serializable {

    @ManagedProperty("#{personViewer.person}")
    private Person person;

    // ...
}

它不再是可收藏的,而且对 SEO 不友好(但这就是 POST 的本质,您可能早就意识到了这一点)。请注意,#{personViewer} bean 本身也必须是 @ViewScoped(因此不是 @ReqestScoped)。您还需要确保不要通过重定向返回,而只是向前导航。

【讨论】:

  • 感谢 BaluCs 的快速回复。我们可以将接收到的值设置为 managedProperty(另一个视图范围 bean)
  • 只能通过来自另一个视图范围 bean 的 POST。您不能通过@ManagedProperty 在视图范围的 bean 中设置请求参数。另请参阅答案底部的“另请参阅”文章链接。
  • 我们正在尝试序列化和反序列化 viewParam 中传递的对象。但问题是正在调用 getAsObject 而不是 getAsString。因此,我们为 myBean 添加了一个单独的 toString 方法。并且参数值也显示在 URL 中。有没有办法隐藏这个参数?
  • 所以你只想要一个POST?那么你根本不需要&lt;f:viewParam&gt;。序列化绝对没有意义。 &lt;f:viewParam&gt; 用于设置 GET 请求参数。对于 POST,只需使用 @ManagedProperty 在其中引用初始 bean。另请参阅更新的答案。
  • 我们需要将第一页中的值用于第二页。如果我们只是发布一个帖子,并且如上所述为初始 bean 设置了 ManagedProperty,则人员 ID 为空。如果我在第二页添加 f:metadata 标记和相应的代码并添加转换器,我们可以在第二页中看到值。如果我们不将类转换为 toString ,则会发生错误,说明无法将 person 设置为 personEditor bean。那么,有没有办法在转换器中调用 toString 方法或者其他更好的方法呢?
猜你喜欢
  • 2014-02-09
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 2011-06-01
相关资源
最近更新 更多