我对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 位被注释掉了。第一次不是,而是刷新后,逻辑被注释掉了?
根本原因分析
事实:
-
Component
注解在没有Scope
注的情况下使用,因此DBFInterface
类实例的生命周期是单一实例。 -
构造函数仅初始化一次
DBFReader
字段,读取器使用该流。
结论是第一个getRawData()
方法调用工作正常。进行第一次调用后,流似乎到达了它的终点:在随后的getRawData()
方法调用中没有可用的记录。
溶液
请考虑更新getRawData()
方法的实现。选择:
- 直接在
getRawData()
方法中的每个方法调用中创建读取器(流(。因此,读取器成为局部变量。 - 将读取器(流(倒回开头。在多线程的情况下需要读取器状态同步。
第一种选择似乎比第二种更简单、更直接。
此外,请确保读取器(其流(已正确关闭。
@Component("DBFInterface")
注解仅创建DBFInterface
的一个实例。- 第一次加载页面时,
while ((rowObjects = reader.nextRecord()) != null) {
会检索数据,因为netxRecord()
不为 null,但第二次加载页面时,没有更多的行要读取,因为与第一次reader
对象相同。
一种可能的解决方案是:
- 转到
DBFInterface
类 - 转到
DBFInterface
构造函数并从中删除init()
方法调用
喜欢这个:
public DBFInterface(){
fileName = DATA.DATA_FILE_NAME;
}
- 将
init
方法更改为公共
init()
方法
public void init(){
try {
reader = new DBFReader(new FileInputStream(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
- 转到
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();
}
}
并在完成读取数据时调用它。