2013-05-01 28 views
0

我使用以下数据结构,以在Servlet控制器JDBC结果存储在使用JSTL一个JSP视图中显示之前。更简洁的方式来迭代该树形图数据结构中JSTL

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查看JSTL片段

<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]}似乎只是太冗长了我。

+0

仅供参考:我已经在下面发布了一个更简单的方法。 – JTP 2013-05-01 17:24:46

回答

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> 
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> 
+0

不幸的是,我被JDK1.4卡住了,所以泛型是不可能的。字符串数组被用于大多数遗留代码,很遗憾没有足够的时间来扫描和执行大规模重构。 – JTP 2013-05-01 17:12:10

+0

JDK 1.4很好,只是删除了泛型。换句话说,Map categoryMap = new TreeMap ();'成为'Map categoryMap = new TreeMap();'。如果通过“大规模重构”,你的意思是你不能用对象替换包含字符串数组的地图的地图,那么你只限于如何干净你可以做到这一点,在某些时候你必须访问'map [key] [0]'。 – clav 2013-05-01 22:58:20