在JSTL中迭代此树形图数据结构的更简洁方法

时间:2013-05-01 00:50:46

标签: java jstl treemap jdk1.4

我使用以下数据结构在使用JSTL在JSP视图中显示之前将JDBC结果存储在Servlet控制器中。

TreeMap
  - TreeMap
      - String[]

每行返回四列数据。

"CATEGORY","OSDIRECTORY","FILENAME","DESCRIPTION"
"CATEGORY","OSDIRECTORY","FILENAME","DESCRIPTION"
"CATEGORY","OSDIRECTORY","FILENAME","DESCRIPTION"
etc.

目标是将结果存储在数据结构中

Category
    - FILENAME
        - OSDIRECTORY
        - DESCRIPTION

并在视图中显示最终结果

Category A
    Hyperlink
    Hyperlink
    Hyperlink
Category B
    Hyperlink
    Hyperlink
etc.

相关的Servlet控制器代码段

...
TreeMap treeMap = new TreeMap();

rs = stmt.executeQuery(query); 

// Gather raw data
while(rs.next()){

    if(!treeMap.containsKey(rs.getString("CATEGORY"))){
        treeMap.put(rs.getString("CATEGORY"), new TreeMap());
    }

    String[] tmp = { rs.getString("OSDIRECTORY"), rs.getString("DESCRIPTION") };
    ((TreeMap)treeMap.get(rs.getString("CATEGORY"))).put(rs.getString("FILENAME"), tmp);
}

request.setAttribute("filemap", treeMap);

RequestDispatcher rd = request.getRequestDispatcher(VIEW_URL);

rd.forward(request, response);
...

相关的JSP View JSTL Snippet

<c:forEach var="f" items="${filemap}">
    <h1><c:out value="${f.key}"/></h1>
    <c:forEach var="g" items="${filemap[f.key]}">
      <a href="TBD">
        <c:out value="${filemap[f.key][g.key][0]}"/>
        <c:out value="${filemap[f.key][g.key][1]}"/>
      </a>
    </c:forEach>
</c:forEach>

我想知道有一种更简洁的方式来表达一些JSTL表达式。

例如$ {filemap [f.key] [g.key] [0]}对我来说似乎太啰嗦。

2 个答案:

答案 0 :(得分:1)

我会让对象代表你的数据,而不是使用地图的地图。由于您的类别包含文件,因此请创建一个类别和文件对象,如下所示:

public class Category {
    private String name;
    private List<DbFile> files = new ArrayList<DbFile>();
    // getters & setters for each property go here
}

public class DbFile {
    private String filename;
    private String osDirectory;
    private String description;
    // getters & setters for each property go here
}

然后在您的数据访问代码中,您可以迭代结果集并构建类别对象列表,如下所示:

Map<String, Category> categoryMap = new TreeMap<String, Category>();

while(rs.next()){
    String categoryName = rs.getString("CATEGORY");
    Category category = categoryMap.get(categoryName);

    if(!categoryMap.containsKey(categoryName)){
        category = new Category();
        category.setName(categoryName);
    }

    DbFile file = new DbFile();
    file.setFilename(rs.getString("FILENAME"));
    file.setOsDirectory(rs.getString("OSDIRECTORY"));
    file.setDescription(rs.getString("FILENAME"));

    category.getFiles().add(file);
    categoryMap.put(categoryName, category);
}

request.setAttribute("categories", Arrays.asList(categoryMap.values()));

然后页面上的代码更直接:

<c:forEach var="category" items="${categories}">
   <h1><c:out value="${category.name}"/></h1>
   <c:forEach var="file" items="${category.files}">
       <a href="TBD">
           <c:out value="${file.osDirectory}"/>
           <c:out value="${file.description}"/>
       </a>
    </c:forEach>
</c:forEach>

答案 1 :(得分:0)

经过一些后期的调查和实验,我发现这比问题中发布的JSTL更清晰。

<c:forEach var="f" items="${filemap}">
    <h1><c:out value="${f.key}"/></h1>
    <c:forEach var="g" items="${f.value}">
        <a href="TBD">
            <c:out value="${g.value[0]}"/>
            <c:out value="${g.value[1]}"/>
        </a>
    </c:forEach>
</c:forEach>