1

次のように、別のビューから渡された 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();
    }
}
4

1 に答える 1

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> 

これは、JSF 2.2 で報告された問題のようです。

h:linkまた、なぜ yourが の中にネストされているのかわかりませんh:form。必要ありません。

UPDATE 一部の taglibs が完全に機能していないように見えますか、それとも間違って読んでいるのでしょうか?

https://java.net/jira/browse/JAVASERVERFACES-2868

于 2013-06-27T02:51:07.390 に答える