1

JSFプロジェクトに問題があります。

  • GlassFishサーバー3.1.2
  • クロサギ2.1.6

リクエストヘッダーフィールドを含むテーブルを表示しようとしています。そのため、私はこのマネージドBeanを作成しました。

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

@ManagedBean
@RequestScoped
public class RequestHeader extends LinkedHashMap<String, List<String>> {
    private List<String> keys;

    @PostConstruct
    public void init() {
        final HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        keys = Collections.list(request.getHeaderNames());
        for (final String key : keys) {
            final List<String> value = Collections.list(request.getHeaders(key));
            final List<String> oldValue = get(key);
            if (oldValue == null) {
                put(key, value);
            } else {
                oldValue.addAll(value);
            }
        }
    }

    public List<String> keys() {
        return keys;
    }
}

これは私のJSFページです:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:head>
        <title>HTTP request headers</title>
    </h:head>
    <h:body>
        <h:dataTable value="#{requestHeader.keys()}" var="k" border="1">
            <f:facet name="header">HTTP request headers</f:facet>
            <h:column>
                <f:facet name="header">Key</f:facet>
                <h:outputText value="#{k}" />
            </h:column>
            <h:column>
                <f:facet name="header">Value</f:facet>
                <!-- This forEach seems to be ignored. -->
                <c:forEach items="#{requestHeader[k]}" var="v">
                    <h:outputText value="#{v}" /><br />
                </c:forEach>
            </h:column>
        </h:dataTable>
    </h:body>
</html>

表の2番目の列に値がある代わりに、セルは空です。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>HTTP request headers</title>
    </head>
    <body>
        <table border="1">
            <thead>
                <tr><th colspan="2" scope="colgroup">HTTP request headers</th></tr>
                <tr>
                    <th scope="col">Key</th>
                    <th scope="col">Value</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>user-agent</td>
                    <td></td>
                </tr>
                <tr>
                    <td>host</td>
                    <td></td>
                </tr>
                <tr>
                    <td>accept</td>
                    <td></td>
                </tr>
                <tr>
                    <td>accept-language</td>
                    <td></td>
                </tr>
                <tr>
                    <td>accept-encoding</td>
                    <td></td>
                </tr>
                <tr>
                    <td>cache-control</td>
                    <td></td>
                </tr>
                <tr>
                    <td>connection</td>
                    <td></td>
                </tr>
            </tbody>
        </table>
    </body>
</html>

私はいくつかのテストを行いました。<h:outputText value="#{requestHeader[k]}" />c:forEach他のリストで動作します。

なぜこのように機能しないのですか?

4

2 に答える 2

6

JSTLタグのようなタグハンドラーはビューのビルド時に実行されますが、JSF<h:xxx>タグのようなUIコンポーネントはビューのレンダリング時に実行されます。したがって、コーディングから期待されるように、それらは同期して実行されません。コードでは、<c:forEach>実行の時点で、<h:dataTable>はまったく実行されていないため、そのvar属性は設定されてい#{k}ないため、実行時に使用できず<c:forEach>、空の/存在しないコレクションを取得します。

別のUIコンポーネント内にネストされた反復が必要な場合は、代わりにUIコンポーネントが必要です。それらの1つはFacelets<ui:repeat>です。

<ui:repeat value="#{requestHeader[k]}" var="v">
    <h:outputText value="#{v}" /><br />
</ui:repeat>

まだJSF1.xを使用している場合は、<t:dataList>代わりにTomahawkを使用するか、単に別のを使用してください<h:dataTable>

参照:


具体的な問題とは関係ありません。ここではバッキングBeanはまったく必要ありません。すべてのリクエストヘッダーは、暗黙のELオブジェクトによってすでに利用可能になっています。Map#{header}

結局のところ、バッキングBeanを使用せずに、アプローチを次のように簡略化できます。

<h:dataTable value="#{header.keySet().toArray()}" var="headerName" border="1">
    <f:facet name="header">HTTP request headers</f:facet>
    <h:column>
        <f:facet name="header">Name</f:facet>
        <h:outputText value="#{headerName}" />
    </h:column>
    <h:column>
        <f:facet name="header">Value</f:facet>
        <ui:repeat value="#{header[headerName]}" var="headerValue">
            <h:outputText value="#{headerValue}" /><br />
        </ui:repeat>
    </h:column>
</h:dataTable>

参照:

于 2012-08-20T12:57:33.110 に答える
1

c:forEachの代わりにui:repeatタグを使用してみてください。c:forEachの代わりにui:repeatを使用する理由については、このリンクを参照してください。

于 2012-08-20T03:33:54.700 に答える