0

在使用 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 视图 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]} 对我来说似乎太冗长了。

4

2 回答 2

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>
于 2013-05-01T02:45:51.300 回答
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>
于 2013-05-01T17:22:57.020 回答