xeh*_*puk 1 datatable foreach jsf jstl
我有一个JSF项目的问题.
我正在尝试显示包含请求标头字段的表.因此我写了这个托管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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的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>
Run Code Online (Sandbox Code Playgroud)
单元格为空,而不是在表格的第二列中具有值:
<?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>
Run Code Online (Sandbox Code Playgroud)
我做了几次测试.<h:outputText value="#{requestHeader[k]}" />
并c:forEach
在其他列表上工作.
为什么它不会这样工作?
像JSTL标记这样的标记处理程序在视图构建期间运行,而像JSF <h:xxx>
标记这样的UI组件在视图渲染时运行.因此,它们不会像您对编码所期望的那样同步运行.在你的代码中,在<c:forEach>
运行的那一刻,它<h:dataTable>
根本没有运行,因此它的var
属性没有被设置,因此#{k}
在<c:forEach>
运行时不可用,因此它检索一个空的/不存在的集合.
如果您希望在另一个UI组件中嵌套迭代,则需要一个UI组件.其中一个是Facelets <ui:repeat>
.
<ui:repeat value="#{requestHeader[k]}" var="v">
<h:outputText value="#{v}" /><br />
</ui:repeat>
Run Code Online (Sandbox Code Playgroud)
如果你还在使用JSF 1.x,请使用Tomahawk <t:dataList>
,或者只使用另一个<h:dataTable>
.
与具体问题无关:你根本不需要支持bean.所有的请求头都已经作为一个Map
可用由隐EL对象#{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>
Run Code Online (Sandbox Code Playgroud)