2013-05-01 7 views
0

JSTL을 사용하여 JSP보기에 표시하기 전에 다음 데이터 구조를 사용하여 Servlet 컨트롤러에 JDBC 결과를 저장합니다.JSTL에서이 트리 맵 데이터 구조를 반복하는보다 간결한 방법

TreeMap 
    - TreeMap 
     - String[] 

행당 4 개의 데이터 열이 반환됩니다.

"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. 

관련 서블릿 컨트롤러 코드로보기 최종 결과를 표시하는 코드 조각입니다

... 
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

FYI : 아래에서 좀 더 간단한 방법을 게시했습니다. – JTP

답변

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가 붙어있어서 Generics가 불가능합니다. 문자열 배열은 대부분의 레거시 코드에 사용되었으며 불행히도 대규모 리팩터를 스윕하고 수행 할 충분한 시간이 없습니다. – JTP

+0

JDK 1.4는 괜찮습니다. 제네릭을 제거하십시오. 즉, Map categoryMap = new TreeMap ();는'Map categoryMap = new treeMap();'이됩니다. "대규모 리팩터링"을 사용하면 문자열 배열이 포함 된지도의지도를 객체로 대체 할 수 없다는 것을 의미합니다. 그러면지도를 깨끗하게 할 수있는 방법으로 제한됩니다. 어떤 시점에서는'map [key] [0]'. – clav