百里香叶HTML页面的表在刷新页面后停止工作



我对Spring boot和ThyemeLeaf很陌生,并且仍在学习它,所以也许我没有在互联网上正确搜索,但我在任何地方都没有看到这样的问题。

以下是关于我正在做的事情的规范:

1(我正在使用弹簧靴,用ThyemeLeaf加载一个寺庙。

2(我正在从DBF文件中提取数据

3(在HTML页面上,我只是将每一行及其元素加载到一个表中。

问题: 重新部署整个应用程序后,页面工作正常,可以正常加载所有内容。 刷新页面时,表格无法加载。

这是百里香叶还是我的HTML或春天的问题?

下面是正在运行的代码。

什么从 DBF 中提取数据

@Component("DBFInterface")
public class DBFInterface {
private String fileName;
private DBFReader reader;
// DBF reader is from a library to work with .dbf files, 
// I have tested it in pure java, it works fine
// https://github.com/albfernandez/javadbf
public DBFInterface(String fileName) {
// location of the .dbf file
this.fileName = fileName == null ? DATA.DATA_FILE_NAME : fileName;
init();
}
public DBFInterface() {
fileName = DATA.DATA_FILE_NAME;
init();
}
// starting the "reader" with lets me interface with the database
private void init() {
try {
reader = new DBFReader(new FileInputStream(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public List<DBFField> getFieldList() {
int count = reader.getFieldCount();
List<DBFField> list = new ArrayList<>(count);
for (int i = 0; i < count; i++) list.add(reader.getField(i));
return list;
}
// all of the records in the database, 
// each column in an element in the Object array
public List<Object[]> getRawData() {
int count = reader.getRecordCount();
List<Object[]> list = new ArrayList<>(count);
Object[] rowObjects;
while ((rowObjects = reader.nextRecord()) != null) {
list.add(rowObjects);
}
return list;
}
// getters and setters
}

控制器中允许 HTML 访问数据的部分

@RequestMapping(method = RequestMethod.GET)
public String getSimpleTable(Model model) {
List<Object[]> l = dbfInterface.getRawData();
model.addAttribute("rawData", l);
model.addAttribute("tableFields", dbfInterface.getFieldList());
if (l.size() > 0) System.out.println("RAW DATA NOT EMPTY");
return "simple_table";
}

HTML中用于加载数据的部分(稍后当我可以解决这个问题时,我将使其成为动态列(

<tr th:each="data:${rawData}">
<td th:text="${data[0]}"></td>
<td th:text="${data[1]}"></td>
<td th:text="${data[2]}"></td>
<td th:text="${data[3]}"></td>
<td th:text="${data[4]}"></td>
<td th:text="${data[5]}"></td>
<td th:text="${data[6]}"></td>
<td th:text="${data[7]}"></td>
<td th:text="${data[8]}"></td>
<td th:text="${data[9]}"></td>
<td th:text="${data[10]}"></td>
</tr>

我试图切换 Thymeleaf 的缓存以及摆弄 HTML,问题是我不知道问题出在哪里。

我可以告诉你,刷新不会再次执行这个位,它是在我第一次加载页面时执行的。

2017-08-05 16:09:43.837  INFO 10409 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-08-05 16:09:43.838  INFO 10409 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2017-08-05 16:09:43.860  INFO 10409 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 22 ms
RAW DATA NOT EMPTY

有什么建议吗?或关于我可以自己查看的资源的指导? 同样,它在重新部署后第一次加载它时工作正常,但在刷新页面后表没有加载。

编辑

当我在 chrome 中运行开发模式时,我发现了更多的东西,发布的 HTML 位被注释掉了。第一次不是,而是刷新后,逻辑被注释掉了?

根本原因分析

事实:

  1. Component注解在没有Scope注的情况下使用,因此DBFInterface类实例的生命周期是单一实例。

  2. 构造函数仅初始化一次DBFReader字段,读取器使用该流。

结论是第一个getRawData()方法调用工作正常。进行第一次调用后,流似乎到达了它的终点:在随后的getRawData()方法调用中没有可用的记录。

溶液

请考虑更新getRawData()方法的实现。选择:

  1. 直接在getRawData()方法中的每个方法调用中创建读取器(流(。因此,读取器成为局部变量。
  2. 将读取器(流(倒回开头。在多线程的情况下需要读取器状态同步。

第一种选择似乎比第二种更简单、更直接。

此外,请确保读取器(其流(已正确关闭。

  1. @Component("DBFInterface")注解仅创建DBFInterface的一个实例。
  2. 第一次加载页面时,while ((rowObjects = reader.nextRecord()) != null) {会检索数据,因为netxRecord()不为 null,但第二次加载页面时,没有更多的行要读取,因为与第一次reader对象相同。

一种可能的解决方案是:

  1. 转到DBFInterface
  2. 转到DBFInterface构造函数并从中删除init()方法调用

喜欢这个:

public  DBFInterface(){
fileName = DATA.DATA_FILE_NAME; 
}
  1. init方法更改为公共

init()方法

public void init(){
try {
reader = new DBFReader(new FileInputStream(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
  1. 转到getSimpleTable方法并在getRawData之前调用init()方法

喜欢这个:

@RequestMapping(method = RequestMethod.GET)
public String getSimpleTable(Model model){
dbfInterface.init();
List<Object[]> l = dbfInterface.getRawData();
model.addAttribute("rawData",l);
model.addAttribute("tableFields",dbfInterface.getFieldList());
if(l.size() > 0) System.out.println("RAW DATA NOT EMPTY");
return "simple_table";
}

这种替代方法的缺点是,每个请求都必须从头开始读取文件。

也请尝试在某个时候调用DBFUtils.close(reader);,也许如果您在DBFInterface上创建一个close()方法,如下所示:

public void close(){
try {
DBFUtils.close(reader);
} catch (Exception e) {
e.printStackTrace();
}
}

并在完成读取数据时调用它。

最新更新