次のように、別のビューから渡された 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>
ただし、GET パラメータが実際に送信されたとしても、Converter.getAsString(..., Object value)
メソッドのみが呼び出され、常に null になります。value
これに関するBalusCのブログ投稿を見つけたので、私の知る限り、その手紙をたどりました。それでも駄目。完全なコードは次のとおりです。
ソースビュー
<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>
ターゲット ビュー バッキング Bean
@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();
}
}