我正在尝试转换从另一个视图传递的GET请求参数,如下所示:
<f:metadata>
<f:viewParam name="id"
value="#{targetViewBean.fooFromSourceView}"
converter="fooConverter"
converterMessage="Foo converter message"
required="true" requiredMessage="Foo required message"/>
<f:viewAction action="#{targetViewBean.doSomethingWithFoo()}"/>
</f:metadata>
但只有Converter.getAsString(..., Object value)
方法被调用且value
始终为空,即使您真正发送了GET参数。
我发现了BalusC blog post about this和AFAIK,我跟着它来了。仍然没有好处。这是完整的代码:
<h:head>
<title>Source view</title>
</h:head>
<h:body>
<ul>
<ui:repeat value="#{sourceViewBean.foos}" var="foo">
<li>
<h:link value="Foo \##{foo.id}" outcome="target-view">
<f:param name="id" value="#{foo.id}" />
</h:link>
</li>
</ui:repeat>
</ul>
</h:body>
@Named @ViewScoped
public class SourceViewBean implements Serializable {
public Collection<Foo> getFoos() {
return Db.INSTANCE.getFoos();
}
private static final long serialVersionUID = 1L;
}
<f:metadata>
<f:viewParam name="id"
value="#{targetViewBean.fooFromSourceView}"
converter="fooConverter"
converterMessage="Foo converter message"
required="true" requiredMessage="Foo required message"/>
<f:viewAction action="#{targetViewBean.doSomethingWithFoo()}"/>
</f:metadata>
<h:head>
<title>Target view</title>
</h:head>
<h:body>
<h:outputText value="ID: #{targetViewBean.fooFromSourceView.id}" />
</h:body>
@Named
@ViewScoped
public class TargetViewBean implements Serializable {
private Foo fooFromSourceView;
public void doSomethingWithFoo() {
System.out.println("Foo is here? " + fooFromSourceView != null);
}
public Foo getFooFromSourceView() {
return fooFromSourceView;
}
public void setFooFromSourceView(Foo fooFromSourceView) {
this.fooFromSourceView = fooFromSourceView;
}
private static final long serialVersionUID = 1L;
}
@FacesConverter(value = "fooConverter")
public class FooConverter implements Converter {
@Override
public Object getAsObject(
FacesContext context, UIComponent component, String value) {
if (value == null || !value.matches("\\d+")) {
return null;
}
for (Foo foo : Db.INSTANCE.getFoos()) {
if (foo.getId().equals(Integer.parseInt(value))) {
return foo;
}
}
throw new ConverterException(new FacesMessage("No Foo found!"));
}
@Override
public String getAsString(
FacesContext context, UIComponent component, Object value) {
if (!(value instanceof Foo) || ((Foo) value).getId() == null) {
return null;
}
return ((Foo) value).getId().toString();
}
}
答案 0 :(得分:3)
在查看您发送的实际代码后,我能够找到问题。问题不在于转换器。它位于项目顶部的xml命名空间中。例如,在source-view.xml
中你有
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
但他们应该
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
target-view.xhtml
应该是
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
GlassFish似乎出于某种原因改变了命名空间。我并没有试图找出它为什么会这样,但请记住这一点。无论如何,一旦我改变它,在GlassFish的输出窗口输出正确的阶段。所以,在需要的地方进行必要的改变。
注意:如果您想知道为什么会出现以下错误
The metadata component needs to be nested within a f:metadata tag. Suggestion: enclose the necessary components within <f:metadata>
这似乎是reported issue with JSF 2.2
另外,我不确定为什么h:link
嵌套在h:form
内。这不是必需的。
<强>更新强> 好像有些taglib没有完全正常运行或者我读错了吗?