2017-08-05 220 views
0

我对Spring引导和ThyemeLeaf很新,但仍然在学习它,所以也许我在Internet上没有正确地搜索它,但我没有在任何地方看到这样的问题。Thymeleaf HTML页面的表格在刷新页面后停止工作

这里是关于我在做什么规格:

1)我使用的春天开机,与ThyemeLeaf加载一个寺庙。

2)我从一个DBF文件

3)在HTML页面中提取数据,我只加载每个行和表中的元素。

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

这是thymeleaf或我的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浏览器的开发者模式,张贴的HTML位被注释掉。第一次不是刷新后,逻辑被注释掉了?

回答

0

根本原因分析

事实:

  1. Component注释被使用而无需Scope注释,所以DBFInterface类的实例的生命周期是单元素。

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

结论是,第一个getRawData()方法调用工作得很好。在第一次调用之后,该流似乎达到了结尾:在后续的方法调用getRawData()中不会有记录可用。

解决方案

考虑更新getRawData()方法的实现。替代品:

  1. 在每个方法调用中,在getRawData()方法中创建读取器(流)。所以,读者变成了一个局部变量。
  2. 将读取器(流)倒回到开头。多线程时需要阅读器状态同步。

第一个选择似乎比第二个选择更简单,更直接。

此外,请确保阅读器(其流)适当关闭。

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

一个可能的解决方案是:

  1. 转到DBFInterface
  2. 转到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方法和之前调用init()方法getRawData
  • 像这样:

    @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(); 
         } 
        } 
    

    ,并调用它,当你完成读取数据。