为什么 java.io.File 对象集合的数据不会显示在 JSP forEach 标记中?
Why won't data for a collection of java.io.File objects display in a JSP forEach tag?
我 运行 陷入 JSP 不显示数据的常见问题。但是,我正在关注文档,并且还尝试了该站点上提出的许多问题的解决方案,但均未成功。
如何在 JSP 中显示 java.io.File 数据?如果我这样做是正确的,是否需要任何额外的配置?
我有一个使用 java.io.File 的文件[],它是在 javax.servlet.http.HttpServlet 中创建的。然后我获取 File[] 并将其作为属性添加到我的 HttpSession 中。然后将其转发到 JSP 文件,传递给 forEach 标记,并填充到 table 中。 (参见 this article)
这是我的 java servlet:
public class LogManagement extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(LogManagement.class);
private static final String BASE_DIRECTORY = System.getProperty("catalina.base");
private static final File CURRENT_LOGS_FOLDER = new File(BASE_DIRECTORY + "/logs");
private static final File CAPTURED_LOGS_FOLDER = new File(BASE_DIRECTORY + "/logs/captured");
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info("GET called on LogManagement servlet");
try {
getLogs(request);
getServletContext().getRequestDispatcher("/LogManagement.jsp").forward(request, response);
} catch (Exception e) {
logger.info("ERROR unable to GET log data");
logger.info(e.getMessage());
}
}
private void getLogs(HttpServletRequest request) {
logger.info("Getting logs");
File[] currentLogs = CURRENT_LOGS_FOLDER.listFiles();
File[] capturedLogs = CAPTURED_LOGS_FOLDER.listFiles();
HttpSession session = request.getSession();
session.setAttribute("currentLogs", currentLogs);
session.setAttribute("capturedLogs", capturedLogs);
logger.info("Got logs");
}
}
这是我从 here and here 尝试的两个解决方案的 jsp(是的,我知道它使用了一些已弃用的标签属性,但我无法更改这些属性)
解决方案 1:
<table style="margin-top: 5px; width: 600px;" align="left">
<tr>
<td align="left">
Current Logs:
</td>
</tr>
<tr>
<td>
<div class="file-viewer">
<table>
<c:forEach var="file" items="${currentLogs}">
<tr>
<td><c:out value="${file.name}"/></td>
<td><c:out value="${file.length}"/></td>
<td><c:out value="${file.lastModified}"/></td>
</tr>
</c:forEach>
</table>
</div>
</td>
</tr>
</table>
解决方案 2:
<table style="margin-top: 5px; width: 600px;" align="left">
<tr>
<td align="left">
Captured Logs:
</td>
</tr>
<tr>
<td>
<div class="file-viewer">
<table>
<c:forEach var="file" items="${capturedLogs}">
<tr>
<td>${file.name}</td>
<td>${file.length}</td>
<td>${file.lastModified}</td>
</tr>
</c:forEach>
</table>
</div>
</td>
</tr>
</table>
这是我在文档和各种 SO 答案中看到的两种解决方案。我也在 td 标签内尝试了 <% out.print(file.getName()); %>
但没有成功(参见 )
这是我得到的异常:
An exception occurred processing [/LogManagement.jsp] at line
[51]__48: ________c:forEach var=file items=${currentLogs}49:
_____tr__50: ___________td__c:out value=${file.name}//td__51: ___________td__c:out value=${file.length}//td__52: _________td__c:out value=${file.lastModified}//td__53: __________/tr__54: _________/c:forEach____Stacktrace:
如果我用虚拟数据替换我正在寻找的数据,我会打印出每一项。
<td>fileName</td>
<td>fileSize</td>
<td>lastEdited</td>
给出 table 行数等于我正在查看的文件数显示:
"fileName fileSize lastEdited"
这表明我的 forEach 正在工作,但对特定数据的引用没有。
您似乎缺少 c:out
标记,就像您在循环遍历 currentLogs
时在上面插入的标记一样。
附带说明一下,除非是大学课程或遗留项目的要求,否则在 2021 年学习 JSP 真的不值得。
问题是 JSTL 希望在搜索对象的 属性 时找到 getter 函数。具体是指有一些方法名的前三个字符是“get”。
在示例中,<td>${file.name}</td>
可以独立运行,因为 java.io.File 有一个名为“getName()”的方法。但是,length 和 lastModified 都没有“get”作为前缀(.length() 和 .lastModified()),尽管它们只是检索一个值。
有很多方法可以解决这个问题(扩展对象、添加“获取”方法等),但我认为最简单的方法是对新对象使用 class。
我在上面的 .java 文件的末尾添加了一个 class 并使用它来代替 java.io.File 对象。它工作得很好:
新 Class:
public class LogFile {
private String name;
private long length;
private String lastModified;
public LogFile(File file) {
this.name = file.getName();
this.length = file.length() / 1024;
this.lastModified = timeStampFormat.format(file.lastModified());
}
public String getName() {
return this.name;
}
public long getLength() {
return this.length;
}
public String getLastModified() {
return this.lastModified;
}
}
使用对象:
File[] currentLogFiles = CURRENT_LOGS_FOLDER.listFiles();
File[] capturedLogFiles = CAPTURED_LOGS_FOLDER.listFiles();
List<LogFile> currentLogs = new ArrayList<>();
List<LogFile> capturedLogs = new ArrayList<>();
if (currentLogFiles != null) {
for (File file : currentLogFiles) {
currentLogs.add(new LogFile(file));
}
}
if (capturedLogFiles != null) {
for (File file : capturedLogFiles) {
currentLogs.add(new LogFile(file));
}
}
HttpSession session = request.getSession();
session.setAttribute("currentLogs", currentLogs);
session.setAttribute("capturedLogs", capturedLogs);
附带说明:据我所知,${file.name}
和 <c:out value="${file.name}" />
都在 jst 中工作。
我 运行 陷入 JSP 不显示数据的常见问题。但是,我正在关注文档,并且还尝试了该站点上提出的许多问题的解决方案,但均未成功。
如何在 JSP 中显示 java.io.File 数据?如果我这样做是正确的,是否需要任何额外的配置?
我有一个使用 java.io.File 的文件[],它是在 javax.servlet.http.HttpServlet 中创建的。然后我获取 File[] 并将其作为属性添加到我的 HttpSession 中。然后将其转发到 JSP 文件,传递给 forEach 标记,并填充到 table 中。 (参见 this article)
这是我的 java servlet:
public class LogManagement extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(LogManagement.class);
private static final String BASE_DIRECTORY = System.getProperty("catalina.base");
private static final File CURRENT_LOGS_FOLDER = new File(BASE_DIRECTORY + "/logs");
private static final File CAPTURED_LOGS_FOLDER = new File(BASE_DIRECTORY + "/logs/captured");
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info("GET called on LogManagement servlet");
try {
getLogs(request);
getServletContext().getRequestDispatcher("/LogManagement.jsp").forward(request, response);
} catch (Exception e) {
logger.info("ERROR unable to GET log data");
logger.info(e.getMessage());
}
}
private void getLogs(HttpServletRequest request) {
logger.info("Getting logs");
File[] currentLogs = CURRENT_LOGS_FOLDER.listFiles();
File[] capturedLogs = CAPTURED_LOGS_FOLDER.listFiles();
HttpSession session = request.getSession();
session.setAttribute("currentLogs", currentLogs);
session.setAttribute("capturedLogs", capturedLogs);
logger.info("Got logs");
}
}
这是我从 here and here 尝试的两个解决方案的 jsp(是的,我知道它使用了一些已弃用的标签属性,但我无法更改这些属性)
解决方案 1:
<table style="margin-top: 5px; width: 600px;" align="left">
<tr>
<td align="left">
Current Logs:
</td>
</tr>
<tr>
<td>
<div class="file-viewer">
<table>
<c:forEach var="file" items="${currentLogs}">
<tr>
<td><c:out value="${file.name}"/></td>
<td><c:out value="${file.length}"/></td>
<td><c:out value="${file.lastModified}"/></td>
</tr>
</c:forEach>
</table>
</div>
</td>
</tr>
</table>
解决方案 2:
<table style="margin-top: 5px; width: 600px;" align="left">
<tr>
<td align="left">
Captured Logs:
</td>
</tr>
<tr>
<td>
<div class="file-viewer">
<table>
<c:forEach var="file" items="${capturedLogs}">
<tr>
<td>${file.name}</td>
<td>${file.length}</td>
<td>${file.lastModified}</td>
</tr>
</c:forEach>
</table>
</div>
</td>
</tr>
</table>
这是我在文档和各种 SO 答案中看到的两种解决方案。我也在 td 标签内尝试了 <% out.print(file.getName()); %>
但没有成功(参见
这是我得到的异常:
An exception occurred processing [/LogManagement.jsp] at line [51]__48: ________c:forEach var=file items=${currentLogs}49: _____tr__50: ___________td__c:out value=${file.name}//td__51: ___________td__c:out value=${file.length}//td__52: _________td__c:out value=${file.lastModified}//td__53: __________/tr__54: _________/c:forEach____Stacktrace:
如果我用虚拟数据替换我正在寻找的数据,我会打印出每一项。
<td>fileName</td>
<td>fileSize</td>
<td>lastEdited</td>
给出 table 行数等于我正在查看的文件数显示:
"fileName fileSize lastEdited"
这表明我的 forEach 正在工作,但对特定数据的引用没有。
您似乎缺少 c:out
标记,就像您在循环遍历 currentLogs
时在上面插入的标记一样。
附带说明一下,除非是大学课程或遗留项目的要求,否则在 2021 年学习 JSP 真的不值得。
问题是 JSTL 希望在搜索对象的 属性 时找到 getter 函数。具体是指有一些方法名的前三个字符是“get”。
在示例中,<td>${file.name}</td>
可以独立运行,因为 java.io.File 有一个名为“getName()”的方法。但是,length 和 lastModified 都没有“get”作为前缀(.length() 和 .lastModified()),尽管它们只是检索一个值。
有很多方法可以解决这个问题(扩展对象、添加“获取”方法等),但我认为最简单的方法是对新对象使用 class。
我在上面的 .java 文件的末尾添加了一个 class 并使用它来代替 java.io.File 对象。它工作得很好:
新 Class:
public class LogFile {
private String name;
private long length;
private String lastModified;
public LogFile(File file) {
this.name = file.getName();
this.length = file.length() / 1024;
this.lastModified = timeStampFormat.format(file.lastModified());
}
public String getName() {
return this.name;
}
public long getLength() {
return this.length;
}
public String getLastModified() {
return this.lastModified;
}
}
使用对象:
File[] currentLogFiles = CURRENT_LOGS_FOLDER.listFiles();
File[] capturedLogFiles = CAPTURED_LOGS_FOLDER.listFiles();
List<LogFile> currentLogs = new ArrayList<>();
List<LogFile> capturedLogs = new ArrayList<>();
if (currentLogFiles != null) {
for (File file : currentLogFiles) {
currentLogs.add(new LogFile(file));
}
}
if (capturedLogFiles != null) {
for (File file : capturedLogFiles) {
currentLogs.add(new LogFile(file));
}
}
HttpSession session = request.getSession();
session.setAttribute("currentLogs", currentLogs);
session.setAttribute("capturedLogs", capturedLogs);
附带说明:据我所知,${file.name}
和 <c:out value="${file.name}" />
都在 jst 中工作。