java - 为什么 java.io.File 对象集合的数据不会显示在 JSP forEach 标记中?
问题描述
我遇到了 JSP 不显示数据的常见问题。但是,我正在关注文档,并且还尝试了针对该站点上提出的许多问题的解决方案,但均未成功。
如何在 JSP 中显示 java.io.File 数据?如果我这样做正确,是否需要任何其他配置?
我有一个使用 java.io.File 的 File[],它是在 javax.servlet.http.HttpServlet 中创建的。然后我获取 File[] 并将其作为属性添加到我的 HttpSession。然后将其转发到 JSP 文件,传递到 forEach 标记,并填充到表中。(见这篇文章)
这是我的 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");
}
}
这是我从这里和这里尝试的两个解决方案的 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 答案中看到的两种解决方案。我也尝试<% out.print(file.getName()); %>
在 td 标记内部但没有运气(请参阅无法在表中显示 jsp 数据)
这是我得到的例外:
在第 [51]__48 行处理 [/LogManagement.jsp] 时发生异常:________ 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>
给出一个表,其行数等于我正在查看的文件数:
"fileName fileSize lastEdited"
这表明我的 forEach 正在工作,但对特定数据的引用却没有。
解决方案
问题是 JSTL 期望在搜索对象的属性时找到 getter 函数。具体来说,它意味着有一些方法以“get”作为方法名称的前三个字符。
由于 java.io.File 有一个名为“getName()”的方法,因此在示例<td>${file.name}</td>
中可以自行工作。但是,length 和 lastModified 都没有“get”作为前缀(.length() 和 .lastModified()),尽管它们只是检索一个值。
有很多方法可以解决这个问题(扩展对象、添加“get”方法等),但我认为最简单的方法是为新对象使用类。
我在上述 .java 文件的末尾添加了一个类,并使用它代替了 java.io.File 对象。它工作得很好:
新班级:
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);
附带说明:据我所知,两者都在 jst 中工作${file.name}
。<c:out value="${file.name}" />
推荐阅读
- postgresql - 来自 Postman 的 Express 错误:列不存在(在 Node、Postgres、Express 中)
- python - 我正在尝试删除前面或后面有空格的数字,但在这种情况下?
- docker - 不运行新的 docker 镜像
- php - WooCommerce 购物车运费计算器仅限于特定州
- c++ - 使用条件编译指令编写一个程序,将数字 56 舍入到最接近的 50
- c - 带指针的复合文字
- flutter - 如何在颤动中将动态文本字段限制为 4?
- sass - 我想在 VS2019 中使用 Web 编译器编译位于文件夹中的所有 *.scss 文件
- scala - 将 Mozilla Rhino 与 SBT 一起使用 - 未知工件
- python - 如何让我的 python 程序运行得更快?