I am very new to Spring boot and ThyemeLeaf and still learning it, so maybe I am not searching this correctly on the internet, but I don't see such problem anywhere.
Here is the specification about what I am doing:
1) I am using Spring boot, with ThyemeLeaf to load a temple.
2) I am pulling data from a DBF file
3) On the HTML page, I just load each of the row and its elements in a table.
Problem: After redeploying the whole app, the page works fine, it loads everything just fine. when I refresh the page the table does not load.
Is this a problem with thymeleaf or my HTML or the Spring?
Here is the code that is being run.
What pulls the data from the 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
}
The Part of the Controller that lets the HTML access the data
@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";
}
The part of HTML that is to load the data (I will make it the columns dynamic later when I can solve this first)
<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>
I have tried to toggle Thymeleaf's cache as well as fiddle with the HTML, the thing is I don't know where the problem is originating.
I can tell you this, refreshing does not execute this bit again, It is executed the very first time I load the page.
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
Any suggestion? or guidance on resources where I can look myself? Again, it works fine the first time I load it after redeploying but the table does not load after I refresh the page.
edit
Some more stuff I found out when I ran the dev mode in chrome, the HTML bit posted was commented out. The first time it is not but the after refreshing, the logic is commented out?
Facts:
The Component
annotation is being used without the Scope
annotation, so the lifecycle of the instance of the DBFInterface
class is the singleton.
The DBFReader
field is initialised only once by constructor and the reader uses the stream.
The conclusion is that the first getRawData()
method call works just fine. After the first call is made, the stream seems to reach its end: no records would be available at the consequent getRawData()
method calls.
Consider updating the implementation of the getRawData()
method. Alternatives:
getRawData()
method, on the every method call. So, the reader becomes a local variable.The first alternative seems to be simpler and more straightforward than the second one.
Also, make sure that the reader (its stream) is closed appropriately.