刷新页面后,Thymeleaf HTML页面的表停止工作

时间:2017-08-05 20:18:16

标签: java html spring spring-boot thymeleaf

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

以下是我正在做的事情的说明:

1)我正在使用Spring引导,使用ThyemeLeaf加载一个太阳穴。

2)我从DBF文件中提取数据

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

问题: 重新部署整个应用程序后,页面工作正常,它加载一切就好了。 当我刷新页面时,表格不会加载。

这是百万美元或我的HTML还是Spring的问题?

以下是正在运行的代码。

什么从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中运行dev模式时发现了更多的东西,发布的HTML位被注释掉了。第一次不是,但经过刷新,逻辑被注释掉了吗?

2 个答案:

答案 0 :(得分:0)

根本原因分析

事实:

  1. 正在使用Component注释而没有Scope注释,因此DBFInterface类实例的生命周期是单例。

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

  3. 结论是第一个getRawData()方法调用工作得很好。在第一次调用之后,流似乎达到了结束:在随后的getRawData()方法调用中没有可用的记录。

    解决方案

    考虑更新getRawData()方法的实现。备选方案:

    1. 在每个方法调用的getRawData()方法中创建阅读器(流)。因此,读者成为一个局部变量。
    2. 将阅读器(流)倒回到开头。在多线程的情况下需要读取器状态同步。
    3. 第一种选择似乎比第二种选择更简单,更直接。

      另外,请确保阅读器(其流)已正确关闭。

答案 1 :(得分:0)

  1. @Component("DBFInterface")注释仅创建DBFInterface
  2. 的一个实例
  3. 首次加载页面时,while ((rowObjects = reader.nextRecord()) != null) {会检索数据,因为netxRecord()不为空,但第二次加载页面时,不再有要读取的行,因为它们是相同的{{ 1}}第一次的对象。
  4. 一种可能的解决方案是:

    1. 转到reader班级
    2. 转到DBFInterface构造函数并从中删除DBFInterface方法调用
    3. 像这样:

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

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

          像这样:

          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);上创建close()方法,请执行以下操作:

          DBFInterface

          完成阅读数据后调用它。