JSP 템플릿

웹 개발 도구는 빠르게 발전하고 있지만 Swing 또는 VisualWorks Smalltalk와 같은 대부분의 GUI (그래픽 사용자 인터페이스) 도구 키트보다 여전히 뒤쳐져 있습니다. 예를 들어, 전통적인 GUI 툴킷은 레이아웃 알고리즘을 캡슐화하고 재사용 할 수있는 레이아웃 관리자를 한 형태 또는 다른 형태로 제공합니다. 이 기사에서는 레이아웃 관리자처럼 레이아웃을 캡슐화하여 복제 대신 재사용 할 수있는 JSP (JavaServer Pages)의 템플릿 메커니즘을 살펴 봅니다.

레이아웃은 개발 과정에서 많은 변경을 거치므로 나머지 애플리케이션에 미치는 영향을 최소화하면서 수정할 수 있도록 해당 기능을 캡슐화하는 것이 중요합니다. 실제로 레이아웃 관리자는 객체 지향 디자인의 신조 중 하나의 예를 보여줍니다 . 다양한 디자인 패턴의 기본 테마이기도 한 다양한 개념을 캡슐화합니다 .

JSP는 레이아웃 캡슐화에 대한 직접적인 지원을 제공하지 않으므로 동일한 형식의 웹 페이지는 일반적으로 레이아웃 코드를 복제합니다. 예를 들어, 그림 1은 머리글, 바닥 글, 사이드 바 및 기본 콘텐츠 섹션이 포함 된 웹 페이지를 보여줍니다.

그림 1에 표시된 페이지의 레이아웃은 HTML 테이블 태그로 구현됩니다.

예 1. 콘텐츠 포함

JSP 템플릿  
   
<% @ include file = "sidebar.html"%>
<% @ include file = "header.html"%>
<% @ include file = "introduction.html"%>
<% @ include file = "footer.html"%>

위에 나열된 예에서 콘텐츠는 JSP include지시문에 포함되어 페이지 자체를 수정하지 않고 포함 된 파일을 변경하여 페이지의 콘텐츠를 변경할 수 있습니다. 그러나 레이아웃은 하드 코딩되어 있으므로 레이아웃을 변경하려면 페이지를 수정해야합니다. 일반적으로 웹 사이트에 동일한 형식의 여러 페이지가있는 경우 단순한 레이아웃 변경이라도 모든 페이지를 수정해야합니다.

레이아웃 변경의 영향을 최소화하려면 콘텐츠 외에 레이아웃을 포함하는 메커니즘이 필요합니다. 이렇게하면 레이아웃과 콘텐츠를 사용하는 파일을 수정하지 않고도 변경 될 수 있습니다. 그 메커니즘은 JSP 템플릿입니다.

템플릿 사용

템플릿은 매개 변수화 된 콘텐츠를 포함하는 JSP 파일입니다. 이 문서에서 설명하는 템플릿은 사용자 정의 태그의 집합으로 구현됩니다 : template:get, template:put,와 template:insert. template:get도 1에 도시 된 포맷으로 웹 페이지를 생성하는 실시 예 2.A에 도시 된 바와 같이 태그는 컨텐츠 파라미터를 액세스한다.

예 2.a. 템플릿

< 템플릿 : get name = "title" />
   
< 템플릿 : get name = "header"/>

예제 2.a는 지시문 template:get대신 사용한다는 점을 제외하면 예제 1과 거의 동일합니다 include. template:get작동 방식을 살펴 보겠습니다 .

template:get요청 범위에서 지정된 이름을 가진 Java Bean을 검색합니다. 빈은에 포함 된 웹 구성 요소의 URI (Uniform Resource Identifier)를 포함합니다 template:get. 예를 들어, 예제 2.a에 나열된 템플릿 에서 요청 범위에 이름이 지정된 빈에서 template:getURI를 가져옵니다 . 이후 에는 .header.htmlheadertemplate:getheader.html

template:put다음에 의해 검색되는 요청 범위에 Bean을 넣습니다 template:get. 템플릿은에 포함되어 있습니다 template:insert. 예제 2.b는 putinsert태그 의 사용을 보여줍니다 .

예제 2.b. 예제 2.a의 템플릿 사용

   
    insert template = "/ articleTemplate.jsp">
    
     put name = "title"content = "템플릿"direct = "true"/>
     
      put name = "header"content = "/ header.html"/>
      
       put name = "sidebar"content = "/ sidebar.jsp"/>
       
        put name = "content"content = "/ introduction.html"/>
        
         put name = "footer"content = "/ footer.html"/>
        
       
      
     
    
   

insert템플릿을 포함하는 시작 태그를 지정,이 경우의 템플릿 예 2.a. 나열 각 put태그는 요청 범위에 빈을 저장하고 insert종료 태그에는 템플릿이 포함됩니다. 이후에 템플릿은 위에서 설명한대로 빈에 액세스합니다.

에 대한 direct속성을 지정할 수 있습니다 template:put. 가로 direct설정 true되면 태그와 관련된 콘텐츠가에 포함되지 template:get않지만 암시 적 out변수에 직접 인쇄됩니다 . 예를 들어 Example 2.b에서는 제목 콘텐츠 (JSP 템플릿)가 창 제목으로 사용됩니다.

동일한 형식의 여러 페이지를 포함하는 웹 사이트에는 예제 2.a에 나열된 것과 같은 하나의 템플릿과 해당 템플릿을 사용하는 여러 JSP 페이지 (예 : Example 2.b)가 있습니다. 형식이 수정되면 변경 사항이 템플릿으로 제한됩니다.

일반적으로 콘텐츠를 포함하는 템플릿의 또 다른 이점은 모듈 식 디자인입니다. 예를 들어, 예제 2.b에 나열된 JSP 파일은 궁극적으로 header.html예제 2.c에 나열된를 포함합니다.

예제 2.c. header.html

   

Because header.html is included content, it does not have to be replicated among pages that display a header. Also, although header.html is an HTML file, it does not contain the usual preamble of HTML tags such as or because those tags are defined by the template. That is, because the template includes header.html, those tags should not be repeated in header.html.

Note: JSP provides two ways to include content: statically, with the include directive, and dynamically, with the include action. The include directive includes the source of the target page at compile time and is equivalent to C's #include or Java's import. The include action includes the target's response generated at runtime.

Like the JSP include action, templates include content dynamically. So, although the JSP pages in Example 1 and Example 2.b are functionally identical, the former statically includes content, whereas the latter dynamically includes it.

Optional content

All template content is optional, which makes a single template useful to more Webpages. For example, Figure 2.a and Figure 2.b show two pages -- login and inventory -- that use the same template. Both pages have a header, footer, and main content. The inventory page has an edit panel (which the login page lacks) for making inventory changes.

Below, you'll find the template shared by the login and inventory pages:

 ... 
   
name='editPanel'/>
...

The inventory page uses the template listed above and specifies content for the edit panel:

   ... 
    ...  

In contrast, the login page does not specify content for the edit panel:


  

Because the login page does not specify content for the edit panel, it's not included.

Role-based content

Web applications often discriminate content based on a user's role. For example, the same JSP template, which includes the edit panel only when the user's role is curator, produces the two pages shown in Figures 3.a and 3.b.

The template used in Figures 3.a and 3.b uses template:get's role attribute:

 ... 
   
     ... 
     ... 
    
role='curator'/>
...

The get tag includes content only if the user's role matches the role attribute. Let's look at how the tag handler for template:get uses the role attribute:

public class GetTag extends TagSupport { private String name = null, role = null; ... public void setRole(String role) { this.role = role; } ... public int doStartTag() throws JspException { ... if(param != null) { if(roleIsValid()) { // include or print content ... } } ... } private boolean roleIsValid()  } 

Implementing templates

The templates discussed in this article are implemented with three custom tags:

  • template:insert
  • template:put
  • template:get

The insert tag includes a template, but before it does, put tags store information -- a name, URI, and Boolean value specifying whether content should be included or printed directly -- about the content the template includes. template:get, which includes (or prints) the specified content, subsequently accesses the information.

template:put stores beans in request scope but not directly because if two templates use the same content names, a nested template could overwrite the enclosing template's content.

To ensure that each template has access only to its own information, template:insert maintains a stack of hashtables. Each insert start tag creates a hashtable and pushes it on the stack. The enclosed put tags create beans and store them in the newly created hashtable. Subsequently, get tags in the included template access the beans in the hashtable. Figure 4 shows how the stack is maintained for nested templates.

Each template in Figure 4 accesses the correct footer; footer.html for template_1.jsp and footer_2.html for template_2.jsp. If the beans were stored directly in request scope, step 5 in Figure 4 would overwrite the footer bean specified in step 2.

Template tag implementations

The remainder of this article examines the implementation of the three template tags: insert, put, and get. We begin with sequence diagrams, starting with Figure 5. It illustrates the sequence of events for the insert and put tags when a template is used.

If a template stack does not already exist, the insert start tag creates one and places it in request scope. A hashtable is subsequently created and pushed on the stack.

put시작 태그 PageParameter는 엔 클로징 insert태그에 의해 생성 된 해시 테이블에 저장된 빈을 생성합니다 .

삽입 end태그에는 템플릿이 포함됩니다. 템플릿은 get태그를 사용하여 태그로 생성 된 빈에 액세스합니다 put. 템플릿이 처리 된 후 insert시작 태그로 생성 된 해시 테이블 이 스택에서 팝됩니다.

그림 6은의 시퀀스 다이어그램을 보여줍니다 template:get.

템플릿 태그 목록

템플릿 태그에 대한 태그 핸들러 구현은 간단합니다. Example 3.a에는 InsertTag클래스- template:insert.

예제 3.a. InsertTag.java