관리 메뉴

I LOVE EJ

JSP 커스텀 태그 라이브러리 본문

Web Development/JSP

JSP 커스텀 태그 라이브러리

BeOne 2007. 10. 15. 15:36

JSP 커스텀 태그란 무엇인가

 

 

HTML 파일을 파싱할 때는 브라우저가 일련의 표준에 기반해서 파일 내에 있는 태그들을 어떻게 처리하고 다룰지 결정한다. JSP 커스텀 태그의 목표는 개발자가 JSP 페이지 내에서 사용할 수 있는 태그들의 집합을 확장하여(자신에게 필요한 기능을 수행하는 태그를 만들어 사용할 수 있다) 사용할 수 있도록 해주는 것이다. 일반적인 HTML 태그들에서는 결과물을 출력하기 위해 태그들을 어떻게 처리해야 하는지에 대한 로직이 브라우저에 포함되어 있다. 반면 JSP 커스텀 태그들에서는 태그 핸들러(tag handler)라고 부르는 특별한 자바 클래스에 이 기능이 존재한다.

태그 핸들러는 태그에 설정된 구체적 동작(커스텀 액션)을 수행하는 자바 클래스다. 태그 핸들러는 개발하고자 하는 태그의 타입에 따라 여러 커스텀 태그 인터페이스 중에서 적절한 인터페이스를 구현하여 만든다. 핸들러 클래스는 PageContext 객체와 요청, 응답, 세션 객체 등과 같은 모든 JSP 자원에 접근할 수 있다. 또한 태그는 태그 핸들러 내의 여러 변수들을 속성을 통해 설정할 수 있기 때문에 속성을 통해 태그의 동작을 조절할 수 있다.

 

 


태그 라이브러리란 무엇인가

 

 

태그 라이브러리는 패키징의 관점으로 JSP 태그들을 모아놓은 JSP 태그들의 집합이다. 반드시 그런 것은 아니지만 일반적으로 같은 태그 라이브러리에 속한 태그들은 비슷한 문제를 해결한다. 태그 라이브러리는 다음과 같은 컴포넌트들로 구성된다.

 

 

1.태그 핸들러


태그 핸들러에 태그의 동작을 수행하기 위한 실제 구현 코드가 위치한다. 이는 자바 클래스로서 런타임 시 호출되어 미리 정의된 동작을 수행한다.

 

 

2.TLD 파일


태그 라이브러리 디스크립터(TLD, Tag Library Descriptor) 파일은 라이브러리 내의 태그에 대한 메타정보(데이터에 대한 데이터, 즉 무슨 데이터인지 나타내는 정보. 따라서 라이브러리 내의 태그에 대한 메타정보는 태그 라이브러리 태그들의 근원적인 정의나 설명을 나타낸다)를 담고 있는 XML파일이다. 태그의 이름, 필요한 속성, 태그 핸들러 클래스 이름들과 같은 정보가 모두 이 파일에 포함되어 있으며 이들은 JSP 컨테이너에 로딩하여 사용할 커스텀 태그에 대한 정보를 제공해준다.

 

 

3.web.xml


이 디스크립터 내에서 웹 애플리케이션이 어떤 태그 라이브러리를 사용하는지 그리고 각 태그 라이브러리를 설명하기 위해 어떤 TLD 파일들을 사용하는지 반드시 정의해야 한다.

 

...

<taglib>

  <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>

  <taglib-location>/WEB-INF/struts-html.tld</taglib-location>

</taglib>

<taglib>

  <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>

  <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>

</taglib>

<taglib>

  <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>

  <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>

</taglib>

<taglib>

  <taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri>

  <taglib-location>/WEB-INF/struts-nested.tld</taglib-location>

</taglib>

<taglib>

  <taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri>

  <taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>

</taglib>

...

 

4.JSP 페이지


JSP 페이지 내에는 태그 라이브러리 하나 이상을 위한 include 지시어(또는 taglib)와 필요한 태그 라이브러리의 호출들 즉 실제 커스텀 태그들이 포함된다. 이때 한 JSP 페이지에서 얼마나 많은 태그 라이브러리나 태그 참조를 포함할 수 있는지에 대한 제한은 없다.


※한 JSP 페이지에 태그 수가 40 ~ 50개에 이르는 경우 JSP 컨테이너에서 기능 저하가 발생한다는 몇몇 보고가 있다.

 

 

 

스트럿츠 태그와 함께 자바빈즈 사용하기

 

 

태그들과 같이 사용되는 자바빈즈는 HTML 폼의 입력 필드에 대응하는 프로퍼티들을 포함하는 ActionForm일 수도 있지만(스트럿츠 HTML 태그 라이브러리를 이용한다면 대부분 ActionForm을 쓴다) ActionForm이 아닌 경우 보통 모델 계층의 값 객체(value object)들이다. 이 빈들은 페이지, 요청, 세션 또는 애플리케이션 등 어느 스코프 안에도 존재할 수 있다(스트럿츠의 ActionForm은 요청과 세션 스코프에만 존재할 수 있다).

 

 

1.단순 프로퍼티 접근


단순 프로퍼티란 한 값을 포함하는 멤버 변수를 가리킨다고 생각하면 되며, 접근은 JSP의 <jsp:getProperty>액션과 비슷하게 수행된다. 'firstName'이라는 단순 프로퍼티 레퍼런스는 메소드 getFirstName()이나 setFirstName()의 호출로 변환된다. 이 변환은 빈 프로퍼티에 대한 표준 자바빈즈 스펙의 네이밍 규약을 따른다. 실제로 스트럿츠는 프로퍼티의 setter, getter 메소드의 이름을 실별하기 위해 인트로스펙션 API를 사용한다. 따라서 개발자는 BeanInfo 클래스를 사용하여 자신이 만드는 빈에서 메소드 이름을 마음대로 정해 사용할 수 있다. 자바빈즈 스펙에 관한 더 자세한 정보가 필요하다면 http://java.sun.com/products/javabeans/를 참고하라.

 

 

2.중첩된 프로퍼티 접근


중첩된 레퍼런스들은 마침표(.)로 구분되는 프로퍼티 이름의 계층 구조를 통해 프로퍼티에 접근한다. 이는 자바스크립트에서 중첩된 프로퍼티에 접근하기 위해 사용되는 방식과 비슷하다. 예를 들어, 다음과 같은 프로퍼티 레퍼런스가 있다고 하자.


...

property="user.address.city"

...


이 래퍼런스는 다음과 같은 자바 구문으로 변환된다.


...

getUser().getAddress().getCity();

...


만일 입력 폼 등에서 수행되는 setter에서 중첩된 레퍼런스를 사용했다면 중첩된 레퍼런스의 맨 마지막 프로퍼티에서는 setter가 호출된다. 이 경우 앞서 예로 든 프로퍼티 레퍼런스는 다음과 같은 자바 구문으로 변환된다.


...

getUser().getAddress().setCity();

...


중첩된 프로퍼티들은 거의 대부분 지원되는 태그들의 property 속성에서 사용된다.

 

 

3.인덱스가 있는 프로퍼티 접근


인덱스가 있는 프로퍼티에서는 첨자(subscripts)를 사용하여 프로퍼티에 속한 각 요소에 접근한다. 사실 빈에서 인덱스가 있는 프로퍼티란 배열을 값으로 포함하는 프로퍼티 또는 빈에서 이 프로퍼티를 위해 인덱스를 인자로 받는 getter, setter 메소드를 제공하는 경우다. 예를 들어, 다음과 같은 프로퍼티 레퍼런스가 있다고 하자.


...

property="address[2]"

...


이 레퍼런스는 다음과 같은 자바 구문으로 변환된다.


...

getAddress(2);

...


setter에서 같은 프로퍼티 레퍼런스를 사용했다면 다음과 같은 자바 구문이 호출될 것이다.


...

setAddress(2, address);

...

 

 

 

스트럿츠에 포함된 태그 라이브러리

 

 

1.HTML 태그


스트럿츠 HTML 태그 라이브러리는 HTML 입력 폼을 작성하는 데 사용되는 태그들과 함께 HTML 기반 사용자 인터페이스를 작성하는, 일반적인 태그들을 포함한다.

스트럿츠 HTML 태그 라이브러리에 있는 태그들은 ActionForm 등을 포함하여 스트럿츠 프레임워크에 있는 다른 컴포넌트들과 매우 밀접하게 동작할 수 있도록 설계되어 있다. 스트럿츠 프레임워크를 사용한다면 표준 HTML을 사용하기 보다는 가능한 항상 이 태그들을 우선적으로 사용해야 한다. HTML 태그 라이브러리 태그들은 특별히 다른 나머지 스트럿츠 컴포넌트들과 이용할 수 있도록(또는 연동될 수 있도록) 작성되었기 때문에 충분히 사용할만한 가치가 있다.

이 라이브러리에 있는 대부분의 태그는 스트럿츠 form 태그 내부에 중첩되어야 한다. 물론 적은 수지만 이 태그 라이브러리에는 폼 관련 이슈를 다루지 않는 태그들도 있다. 여기서 스트럿츠 프레임워크 내의 모든 태그를 다루지는 않는다. 모든 태그에 관한 레퍼런스가 필요하다면 http://jakarta.apache.org/struts/api/에서 스트럿츠 프레임워크 API 문서를 참고하라.

html 태그는 HTML의 html 요소(element)를 표시하며 locale 속성을 포함할 수 있다. locale 속성은 세션에 이미 사용자의 지역 정보가 저장되어 있는 경우 사용자의 지역을 출력해준다.


...

<!--Ex1: 'locale' 속성-->

<html:html locale="true">

  <!--JSP 페이지의 바디-->

</html:html>

...


[List1: 스트럿츠 HTML 태그 라이브러리의 커스텀 태그들]

base

HTML의 base 요소를 표시

button

button 입력 필드를 표시

cancel

cancel 버튼을 표시

checkbox

checkbox 입력 필드를 표시

errors

모은 일련의 에러 메시지를 조건적으로 표시

file

file 선택 입력 필드를 표시

form

HTML의 form 요소를 정의

frame

HTML의 frame 요소를 표시

hidden

hidden 필드를 표시

html

HTML의 html 요소를 표시

image

"image" 타입의 입력 태그를 표시

img

HTML의 img 태그를 표시

javascript

Validator 플러그인이 로딩한 검증 룰에 기반하는 JavaScript 검증을 표시

link

HTML의 앵커나 하이퍼링크를 표시

message

모여진 일련의 메시지들을 조건적으로 표시

multibox

멀티플 checkbox 입력 필드를 표시

option

select의 option을 표시

options

select의 option들의 집합을 표시

optionsSelection

select의 option들의 집합을 표시

password

"password" 타입의 입력 필드를 표시

radio

radio 버튼 입력 필드를 표시

reset

reset 버튼 입력 필드를 표시

rewrite

URI를 표시

select

select 요소를 표시

submit

submit 요소를 표시

text

"text" 타입의 입력 필드를 표시

textarea

textarea 입력 필드를 표시


ⅰ.base 태그:

이 태그는 href 속성이 현재 JSP 페이지의 절대 경로를 가리키는 HTML의 base 요소를 표시한다. 이 태그를 사용하는 경우 상대 URL을 사용할 때 기준을 가장 최근에 submit한 URL 대신 페이지 자체 URL로 할 수 있다(일반적으로 브라우저는 상대 경로 기준으로 가장 최근에 제출한 URL을 이용). 이 태그는 반드시 HTML의 head 요소 안에 위치해야 한다.


...

<!--Ex2: base 태그-->

<html:html locale="true">

  <head>

    <html:base />

    <title><bean:message key="title.login" /></title>

  </head>

</html:html>

...


여기에 나온 base 태그 예제가 출력되는 경우, 다음과 같은 형태로 변환된다.


...

<html lang="en">

  <head>

    <base href="http://localhost:8080/storefront/index.jsp">

    <title>Virtual Shopping with Struts</title>

  </head>

</html>

...


이 태그는 JSP 페이지 내에서 이미지를 사용하고 이미지 파일의 상대 URL을 표시할 때 중요하다. 이미지를 찾는 상대 경로의 기준이 JSP 페이지가 되는 것이다.

 

ⅱ.form 태그:

스트럿츠 form 태그는 HTML 태그 라이브러리에서 가장 중요한 태그 중 하나다. 이 태그의 용도는 표준 HTML의 form 태그를 표시하고 HTML의 폼과 애플리케이션에서 설정한 ActionForm을 연결하는 것이다.

HTML의 폼 내에 있는 각각의 필드는 ActionForm의 프로퍼티와 일치한다. HTML의 필드 이름과 프로퍼티 이름이 매치할 때 HTML의 필드가 ActionForm의 프로퍼티로 설정된다. 프레임워크는 HTML 폼이 제출될 때 다시 HTML의 필드 이름과 프로퍼티 이름을 짝지어서 해당 HTML 필드의 사용자 입력 값을 ActionForm의 프로퍼티에 저장한다.


[List2: form 태그의 속성]

action

폼을 제출할 URL

enctype

폼 제출 시 사용할 컨텐츠 인코딩

focus

페이지에서 처음 포커스를 받는 필드 이름

method

요청을 제출할 때 사용할 HTTP 메소드

name

입력 필드의 값들을 설정할 때 이용할 프로퍼티들을 포함하는 ActionForm의 이름

onreset

폼 초기화 시 실행할 자바스크립트 이벤트 핸들러

onsubmit

폼 제출 시 실행할 자바스크립트 이벤트 핸들러

scope

폼에 대한 ActionForm의 스코프

style

HTML 요소에 적용할 CSS

styleClass

HTML 요소에 적용할 CSS 스타일 시트 클래스

styleId

HTML 요소에 적용할 아이디

target

폼을 제출할 프레임 타겟

type

페이지에 대한 ActionForm의 FQCN


※FQCN(Fully Qualified Class Name): 클래스의 풀 네임.


_action 속성: action 속성의 값은 페이지 처리를 담당하는 ActionMapping을 선택하는 데 이용된다. form 태그는 action 속성으로 액션 매핑을 선택하며 이 form 태그와 관련 있는 ActionForm과 해당 ActionForm의 스코프를 확인할 수 있다. 만일 확장자 매핑(*.do)을 사용한다면 form 태그의 action 속성 값은 설정 파일에서 대응하는 action 요소의 path 속성 값과 같다. 여기에 선택적으로 확장자 매핑에 사용하는 확장자가 붙을 수 있다.


...

<html:form action="login.do" focus="accessNumber">

...


만일 확장자 매핑 대신 경로 매핑을 상용하는 경우 action 속성은 다음과 같이 설정 파일에서 대응하는 action 요소의 path 속성과 값이 정확히 일치해야 한다.


...

<html:form action="login" focus="accessNumber">

...


_enctype 속성: enctype 속성은 대체로 설정하지 않아도 된다. 하지만 폼이 파일 업로드를 수행하는 경우라면 반드시 enctype 속성을 "multipart/form-data"로 설정해야 한다. 또한 이 경우 method 속성이 POST로 설정되어 있는지도 확인해야 한다. method 속성을 명시하지 않은 경우 기본 값은 POST다.

 

_name 속성: name 속성은 form 태그 내의 입력 필드 값들을 설정하는 데 사용할 프로퍼티들을 포함하는 요청이나 세션 스코프의 ActionForm의 이름을 지정한다. 만일 세션이나 요청 등의 스코프에서 해당 빈을 찾지 못하면 새로운 빈을 생성하여 적절한 스코프에 추가한다. 이때 type 속성에 지정한 자바 클래스 이름을 사용한다.

name 속성에 값을 지저하지 않은 경우 action 속성의 값을 이용하여 해당 ActionMappingdyth를 찾는다. 그리고 찾은 ActionMapping 요소를 통해 폼 빈의 이름을 결정한다. 다른 말로 하면 form 태그에 name 속성을 명시하지 않은 경우 태그는 설정 파일로부터 대응하는 action 요소를 찾아 name 속성의 값을 얻어와 이를 대신 사용한다. 다음과 같이 설정된 action 요소가 있다고 하자.


...

<action name="loginForm"

  path="/signin"

  type="com.oreilly.struts.storefront.security.LoginAction"

  scope="request"

  validate="true"

  input="/security/signin.jsp">

    <forward name="Success" path="/index.jsp" redirect="true" />

    <forward name="Failure" path="/security/signin.jsp" redirect="true" />

</action>

...


그리고 JSP 페이지 내에서 다음과 같은 form 태그를 선언했다고 하자.


...

<html:form action="signin">

...


form 태그에서 name 속성을 명시하지 않았기 때문에 태그는 설정 파일에서 대응하는 signin 액션을 찾을 것이다. 그리고 찾은 action 요소로부터 name 속성의 값을 얻어내 ActionForm이 요청 스코프 또는 세션 스코프에 저장되어 있는지 체크하는 데 사용한다. 이 예제의 경우 action 요소의 name 속성이 loginForm이므로 이 loginForm을 선택할 것이다.


_scope 속성: scope 속성은 form 태그가 어디서 ActionForm을 찾아야 하는지 결정한다. 이 속성의 값은 request나 session 중 하나여야 한다. scope 속성을 명시하지 않은 경우 action 속성의 값을 이용해 ActionMapping 요소를 찾아 해당 요소를 통해 지정된 폼 빈의 스코프를 구한다.


_type 속성: type 속성은 ActionForm의 FQCN을 지정한다. 이는 ActionForm을 지정된 스코프에서 찾을 수 없을 때 이 빈을 새로 생성하는 데 사용한다. 이 속성을 명시하지 않은 경우 action 속성의 값을 이용해 ActionMapping 요소를 찾고 해당 요소를 통해 지정된 폼 빈의 타입을 구한다.


※여러 form 태그의 사용:

표준 HTML에서처럼 한 JSP 페이지 내에 form 태그를 하나 이상 포함할 수 있다. 분명 한 번에 한 폼만 제출할 수 있다고 해서 form 태그를 여러 개 선언할 수 없는 것은 아니다.


ⅲ.button과 cancel 태그:

두 태그는 button 타입의 HTML 입력 요소를 표시한다. HTML에서 보이는 버튼의 레이블은 value 속성이나 태그 바디의 컨텐츠로 설정된다. 이 태그들은 form 태그 바디 내에 중첩되어 존재해야 유효하다.

스타일 시트를 이 태그들과 같이 사용할 수 있다. 같이 사용하려는 스타일 시트를 이 태그들의 styleClass 속성 값으로 설정하면 된다. 기본적으로 button의 경우 레이블의 값이 'Click'이고 cancel의 경우 'Cancel'이다. value 속성을 오버라이드하면 이 값들을 변경할 수 있다(value 속성을 사용하지 않고 태그의 바디 컨텐츠에 레이블 값을 써도 된다).

cancel 태그를 통해 제공되는 버튼은 눌릴 때 validate() 메소드 호출을 생략한다는 특성이 있다. 즉 이 경우 RequestProcessor가 검증 루틴을 수행하지 않고 바로 execute() 메소드를 호출한다.


...

<html:button property="action">BUTTON</html:button>

<html:button property="cmdSearch" value="검색" onclick="codeConfirm('search');" />

<html:cancel>Cancel</html:cancel>

...


위 문장은 다음과 같은 HTML로 해석 되어 진다.


...

<input type="button" name="action" value="BUTTON">

<input type="button" name="cmdSearch" value="검색" onclick="codeConfirm('search');">

<input type="submit" name="org.apache.struts.taglib.html.CANCEL"

  value="Cancel" onclick="bCancel=true;">

...


다음은 바디 컨텐츠에 레이블 값을 메시지 키로 지정한 것이다.


...

<html:button property="list" onclick="boardList()">

  <bean:message key="button.list" />

</html:button>

...


ⅳ.checkbox 태그, radio 태그, select 태그:

이 태그는 checkbox 타입의 HTML 입력 요소를 표시하고 지정된 값이나 현재 폼에 대응하는 빈의 지정된 프로퍼티를 통해 설정된다(태그의 값을 지정하는 데 value 속성을 이용하면 된다. 여기에 지정된 값은 checkbox가 체크되어 제출될 때 값이다. 기본적으로 값을 지정하지 않으며 체크 시 true 값으로 제출된다). 이 태그는 form 태그 바디 내에 중첩되어 존재해야만 유효하다. 이 필드와 관련된 ActionForm 빈의 프로퍼티 값은 boolean 타입이어야 하며, 이 태그의 value 속성을 지정할 경우 true를 나타내는 문자열('true', 'yes', 'on') 중 하나로 지정해야 한다.

브라우저는 체크된 체크박스의 값만 요청으로 보낼 것이다. 체크되지 않은 체크박스들을 정확히 파악하려면 이 폼과 관련된 ActionForm 빈의 reset 메소드에서 체크박스에 대응하는 boolean 프로퍼티들을 false로 설정하도록 구현해야 한다.

radio버튼들은 하나만 선택하도록 해야 하는 경우, property 속성 값을 같게 한다. text 태그에서와 마찬가지로 name 속성은 빈의 이름을 나타내며, 페이지를 읽을 때 빈이 존재하고 property 속성과 이름이 같은 빈의 속성 값을 표시하게 된다.


...

<html:checkbox property="male" value="true" />

<html:radio name="detail" property="comment_yn" value="Y" />

<html:radio name="detail" property="comment_yn" value="N" />

<html:select name="detail" property="cboard_location" onchange="setLocationName(this.selectedIndex)">
  <html:option value="005001000">어울림마당</html:option>
  <html:option value="007001000">학습자료</html:option>
  <html:option value="009001000">경연대회참가부문</html:option>
  <html:hidden property="location_cd" value="005001000" />
</html:select>

...

 

ⅴ.message와 errors 태그:

두 태그는 사용자에게 일반적인 목적의 메시지나 에러들을 출력하는 역할을 담당한다. 메시지들은 ActionMessages에 대응하고 에러들은 ActionErrors에 대응한다. 메시지들/에러들은 validate() 메소드나 예외 처리 프레임워크에 의해 생성된다. 이 태그는 메시지나 에러가 없을 경우 아무 것도 표시하지 않는다.

errors 태그를 사용할 경우 메시지 번들은 반드시 다음과 같은 메시지 키를 포함하고 있어야 한다.


_errors.header: 에러 메시지들의 리스트 전에 표시되는 텍스트다. 이 메시지 텍스트들은 일반적으로 에러 메시지들의 리스트를 시작하기 위해서 <ul> 태그로 끝난다.


_errors.footer: 에러 메시지들의 리스트 후에 표시되는 텍스트다. 이 메시지 텍스트들은 일반적으로 에러 메시지들의 리스트를 끝내기 위해서 </ul> 태그로 시작한다.


...

errors.header=<h3><font color="red">Validation Error</font></h3>

  You must correct the following error(s) before proceeding:<ul>

errors.footer=</ul><hr>

...


위와 같이 설정한 경우 에러들이 HTML 페이지에 출력될 때 불릿(bullet) 리스트 내에 나타날 것이다(단, 에러 내용에 <li>와 </li>를 사용했을 경우). 현재 스트럿츠 프레임워크는 설정 파일 내에서 복수의 메시지 리소스들을 지원하기 때문에 어떤 메시지 리소스를 사용할 지 bundle 속성으로 지정할 수도 있다.

 

ⅵ.link 태그:

MVC Model2에서는 일반적으로 JSP 파일에서 다른 JSP 파일로의 링크를 이용하는 것은 올바른 방법이 아니다. Controller나 ActionServlet, Action등에서 처리할 view를 결정해 넘겨주는 것이 보통의 방법이다. 즉, 아래와 같이 <html:link />를 사용하는 것은 좋은 방법이 아니라는 이야기다.


...

<html:link page="/page.jsp">PAGE</html:link>

...


다음처럼 Action으로 보내거나 Forward를 이용해야한다.


...

<html:link action="someAction">ACTION</html:link>

<html:link forward="someForward">FORWARD</html:link>

...


아래는 매개변수를 넘기는 예이다.


...

<html:link action="/welcome" paramId="greetingType" paramName="manager">

  WELCOME

</html:link>

...


ⅶ.file 태그:

파일 업로드를 제공하기 위해 사용된다.


...

<html:form action="/UserUpdate" method="post" enctype="multipart/form-data">

...

<html:file property="userImage" />

...


ⅷ.text 태그와 hidden 태그:

HTML의 text와 hidden 필드를 나타낸다. 빈의 이름을 나타내는 name 속성과 태그의 이름을 나타내는 property 속성을 함께 사용할 경우, 페이지를 읽을 때 빈이 존재하면 해당 속성의 값을 value값으로 나타낸다.


...

<html:text name="detail" property="maxsize" isNull="N" dataType="integer" minValue="1" maxValue="100" dispName="최대 사이즈“ />

<html:hidden property="foo" value="2" />

...


[List3: 자바스크립트 이벤트 헨들러들을 위한 속성]

onblur

요소가 입력 포커스를 잃었을 때 실행

onchange

요소의 값이 변경된 경우 실행

onclick

마우스로 요소를 클릭한 경우 실행

ondblclick

마우스로 요소를 더블클릭한 경우 실행

onfocus

요소가 입력 포커스를 얻었을 때 실행

onkeydown

요소가 입력 포커스를 가지고 있고 사용자가 키를 눌렀을 때 실행

onkeypress

요소가 입력 포커스를 가지고 있고 사용자가 키를 눌렀다 놓았을 때 실행

onkeyup

요소가 입력 포커스를 가지고 있고 사용자가 키를 놓았을 때 실행

onmousedown

요소에 마우스 포인터가 놓여 있고 사용자가 마우스 버튼을 눌렀을 때 실행

onmousemove

요소에 마우스 포인터가 놓여 있고 사용자가 포인터를 움직였을 때 실행

onmouseout

요소에 마우스 포인터가 놓여 있다가 사용자가 포인터를 요소 밖으로 벗어나게 했을 때 실행

onmouseover

요소에 마우스 포인터가 놓여 있지 않다가 사용자가 포인터를 요소로 이동해온 경우 실행

onmouseup

요소에 마우스 포인터가 놓여 있고 사용자가 마우스 버튼을 놓았을 때 실행

onreset

부모 form이 초기화된 경우 실행

onsubmit

부모 form이 제출된 경우 실행


[List4: HTML 네비게이션 속성]

accesskey

포커스를 즉시 요소로 옮기는 키보드 문자(단축키)

tabindex

탭 순서(양수의 오름차순 숫자)


많은 태그들이 키보드 네비게이션을 지원한다. 이 기능을 사용하는 애플리케이션에서는 마우스 대신 키보드의 탭키나 단축키를 이용하여 각 페이지의 요소를 이동할 수 있다.

 

 

2.Logic 태그


Logic 태그 라이브러리는 출력 텍스트를 조건적으로 생성하는 경우나 객체 컬렉션을 돌면서 출력 텍스트를 반복적으로 생성하는 경우 그리고 애플리케이션의 흐름을 제어해야 하는 경우 등에 유용한 태그들을 포함하고 있다.


[List5: Logic 태그 라이브러리 내의 커스텀 태그들]

empty

요청한 변수가 null 또는 빈 문자열인 경우 이 태그의 바디 컨텐츠를 수행

equal

요청한 변수가 지정한 값고 동일한 경우 이 태그의 바디 컨텐츠를 수행

forward

ActionForward 엔트리를 통해 지정한 페이지로 포워드를 수행

greaterEqual

요청한 변수가 지정한 값보다 크거나 동일한 경우 이 태그의 바디 컨텐츠를 수행

greaterThan

요청한 변수가 지정한 값보다 큰 경우 이 태그의 바디 컨텐츠를 수행

iterate

지정한 컬렉션으로 이 태그 내의 바디 컨텐츠를 반복

lessEqual

요청한 변수가 지정한 값보다 작거나 동일한 경우 이 태그의 바디 컨텐츠를 수행

lessThan

요청한 변수가 지정한 값보다 작은 경우 이 태그의 바디 컨텐츠를 수행

match

지정한 값이 요청한 변수의 부분 문자열에 일치하는 경우 이 태그의 컨텐츠를 수행

messageNotPresent

지정한 메시지가 이 요청에 없는 경우 이 태그의 바디 컨텐츠를 생성

messagePresent

지정한 메시지가 이 요청에 있는 경우 이 태그의 바디 컨텐츠를 생성

notEmpty

요청한 변수가 null도, 빈 문자열도 아닌 경우 이 태그의 바디 컨텐츠를 수행

notEqual

요청한 변수가 지정한 값과 동일하지 않은 경우 이 태그의 바디 컨텐츠를 수행

notMatch

지정한 값이 요청한 변수의 부분 문자열에 일치하지 않는 경우 이 태그의 바디 컨텐츠를 수행

notPresent

지정한 값이 이 요청에 없는 경우 이 태그의 바디 컨텐츠를 수행

present

지정한 값이 이 요청에 있는 경우 이 태그의 바디 컨텐츠를 수행

redirect

HTTP 리다이렉트를 표시


ⅰ.값 비교:

값 비교 태그들은 비교 결과가 true로 나온 경우에만 태그의 바디 컨텐츠를 출력한다. 각 값 비교 태그들은 값을 취하여 value 속성의 값과 비교한다. 태그에 주어진 값이 숫자로 변환되는 경우 숫자 비교를 수행하고 숫자로 변환되지 못하는 경우 문자열 비교(알파벳 순)를 수행한다.


[List6: 비교 태그들이 공유하는 속성]

name

value 속성과 비교에 이용되는 빈의 이름. property 속성이 같이 지정되어 있는 경우 이 이름을 가지는 빈의 property 속성에 지정된 프로퍼티 값을 value 속성과 비교한다.

parameter

value 속성과 비교되는 요청 파라미터의 이름

property

이 속성을 통해 지정한 프로퍼티(name 속성에서 지정된 빈의 프로퍼티)가 비교에 사용되는 변수이다. 이 프로퍼티 레퍼런스는 단순 프로퍼티 형태일 수도 있으며 중첩된 프로퍼티 형태일 수도 있으며 인덱스를 가질 수도 있다.

scope

name 속성에 지정한 이름의 빈을 어느 스코프에서 찾을지 나타낸다. 명시하지 않을 경우 모든 스코프에서 찾는다.

value

이 태그의 다른 속성을 통해 지정한 변수와 비교할 상수 값


요청 파라미터의 존재 유무를 체크하기 위해 Logic 태그 라이브러리의 present 태그를 사용할 수 있다.


...

<logic:present parameter="id">

  <!--요청 파라미터 id가 존재하면 다음을 출력-->

  <tr>

    <td>ID exist.</td>

  </tr>

</logic:present>

...


컬렉션에서 반복을 수행하기 전에 컬렉션이 비었는지 여부를 체크하기 위해 notEmpty 태그를 사용할 수도 있다.


...

<logic:notEmpty name="userSummary" property="addresses">

  <!--사용자의 address 컬렉션의 모든 객체들을 돌며 반복 출력-->

  <logic:iterate id="address" name="userSummary" property="addresses">

    <tr>

      <td width=340 bgcolor="ffffff" style="padding-left:10">

        <bean:write name="address" />

      </td>

    </tr>

  </logic:iterate>

</logic:notEmpty>

...


다음은 ActionForm 내의 프로퍼티와 숫자 값을 어떻게 비교하는지 보여주는 예이다.


...

<logic:lessThan property="age" value="21">

  <td>Not adult.</td>

</logic:lessThan>

...

 

마지막으로, detail 빈의 location 속성 값이 value 값과 같을 때 바디의 문자를 출력하는 간단한 예이다.


...

<logic:equal name="detail" property="location" value="005001000">
  success.
</logic:equal>

...


ⅱ.부분 문자열 매칭:

부분 문자열 매칭 태그들도 값 비교 태그들과 같은 인자를 취한다. 즉 value 속성에 지정한 문자열과 다른 속성을 통해 주어진 값과 비교를 수행한다. 이때 주어지는 값은 cookie, header, parameter, property 또는 name 속성들 중 하나다. 매칭 태그에는 값 비교 태그엔 없는 추가적인 location 속성이 있는데, 이는 태그가 '문자열의 시작'에서 매칭을 수행할 지 아니면 '문자열의 끝'에서 수행할지 알려준다.

예를 들어, 다음은 요청 파라미터 action의 값이 문자열 "processLogin"으로 시작하는지 여부를 결정하는 matchTag를 보여준다.


...

<logic:match parameter="action" value="processLogin" location="start">

  Processing Login...

</logic:match>

...


만일 location 속성을 지정하지 않으면 변수와 value 속성 값 사이의 매칭은 변수 문자열의 아무 위치에서 시작한다. 다시 말해 location이 start인 경우 반드시 value 속성에 지정된 문자열로 시작해야 비교 결과가 true이고 end인 경우 반대다. 또한 location을 지정하지 않으면 value 속성에 지정된 문자열이 부분 문자열로 어디든지 포함되어 있으면 true다.


ⅲ.리다이렉팅과 포워딩:

Logic 태그 라이브러리 내의 forward와 redirect 태그는 HTML 태그 라이브러리에 속하는 것이 더 적합할 수도 있다. 그렇다고 해서 이 태그들이 Logic 태그 라이브러리에 속해 있기 때문에 가치가 떨어진다는 것은 아니다. 실제로 다른 Logic 태그들 중 하나와 결합하여 이 태그들을 사용하는 경우가 훨씬 많고 유용하게 쓰인다(forward와 redirect는 웹 애플리케이션의 흐름을 제어하는 데 이용되기 때문에 단독으로 쓰는 경우보다 로직 태그들과 같이 사용하는 경우가 더 많다).

redirect 태그는 컨테이너가 지원하는 경우 URL을 완전히 다시 써서 클라이언트의 브라우저에 리다이렉트를 보낸다. 이 태그의 속성은 스트럿츠 HTML 태그 라이브러리의 link 태그와 같다. 기본 URL은 다음과 같은 속성들에 근거하여 결정된다(이들 중 하나를 정확히 지정해야 한다).


_forwarding: 이 속성의 값을 찾아낼 전역 ActionForward의 이름으로 사용한다. 그리고 그곳에서 찾아낸 context-relative URI를 사용한다.


_href: 이 속성의 값은 변경하지 않고 사용한다.


_page: 이 속성의 값을 대상 자원의 context-relative URI로 사용하여 컨텍스트 경로를 포함하는 server-relative URI를 생성한다.


forward 태그는 지정된 전역 ActionForward로 리다이렉팅이나 포워딩을 수행한다. forward 태그는 name이라는 속성 하나를 포함하는데 이는 설정 파일에서 ActionForward의 논리적인 이름이다.


ⅳ.컬렉션 유틸리티:

스트럿츠 태그 라이브러리에서 가장 유용하고 널리 사용되는 태그 중 하나가 iterate 태그다. iterate 태그는 지정된 컬렉션 내에 있는 모든 요소에 대해 한 번씩 자신의 바디 컨텐츠를 반복한다. 반드시 필요한 속성은 id 하나다.


_id: 반복에 사용할 요소 등을 포함하는 페이지 스코프의 JSP 빈 이름.


...

<logic:iterate id="address" name="userSummary" property="addresses">

  <bean:write name="address" />

</logic:iterate>

...


여기서 iterate 태그는 userSummary 빈의 getAddresses() 메소드를 호출함으로써 addresses 컬렉션을 얻어낸다. 각 반복 동안 addresses 컬렉션에 포함된 각각의 주소가 address 변수에 차례로 할당된다. 이 변수는 addresses 컬렉션에서 주소 객체를 꺼내 직접 설정한 것처럼 iterate 태그의 바디 컨텐츠 내에서 사용할 수 있다.


[List7: iterate 태그의 속성들]

collection

반복할 컬렉션을 나타내는 런타임 표현식

id

null이 아닌 경우 각 반복마다 컬렉션의 현재 요소를 포함하는 페이지 스코프의 JSP 빈 이름

indexId

각 반복마다 컬렉션의 현재 인덱스를 포함하는 페이지 스코프의 JSP 빈 이름

length

이 페이지에서 반복하는 엔트리(원래의 컬렉션으로부터)의 최대 개수. 원하는 숫자를 직접 지정할 수도 있고, 원하는 숫자를 정의하는 java.lang.Integer 타입의 JSP 빈(임의의 스코프에 존재) 이름을 지정할 수도 있다. 지정하지 않는 경우 무한대.

name

반복할 컬렉션인 JSP 빈 이름(property 속성이 지정되어 있는 경우) 또는 getter 메소드를 통해 반복할 컬렉션을 반환하는 프로퍼티를 포함한 JSP 빈 이름(property 속성이 지정되어 있는 경우)

offset

컬렉션에서 반복을 어느 요소부터 수행할지 나타내는 시작 인덱스. 컬렉션 요소들의 인덱스는 0에서 시작하고 오름 차수가 적용된다. 원하는 숫자로 직접 지정할 수도 있고, 원하는 숫자를 정의하는 java.lang.Integer 타입의 JSP 빈(임의의 스코프에 존재) 이름을 지정할 수도 있다. 지정하지 않는 경우 0을 지정한 것으로 가정한다(즉 컬렉션을 처음 요소부터 반복한다는 의미).

property

name을 통해 지정한 JSP 빈의 프로퍼티 중 반복될 컬렉션을 얻기 위해 사용하는 프로퍼티(이 프로퍼티의 getter 메소드가 반복될 컬렉션을 반환).

scope

name 프로퍼티를 통해 지정한 빈을 찾기 위해 검색할 빈의 스코프. 지정하지 않는 경우 임의의 스코프를 값으로 한다.

type

id 속성에 지정한 이름을 갖는 JSP 빈의 이 속성에 지정한 타입으로 생성. 즉 id 속성에 지정한 이름의 변수 타입을 나타내는  FQCN이다. 이 속성을 지정하지 않은 경우 타입 변환이 일어나지 않는다. 지정한 경우 컬렉션 요소들은 이 type에 지정된 클래스와 대입 호환 가능해야 한다.

 

ⅴ.메시지와 에러:

messagePresent와 messageNotPresent 태그는 요청 스코프에 ActionMessage나 ActionErrors 객체가 존재하는지에 따라 바디 컨텐츠의 수행 여부를 결정한다.


[List8: messagePresent와 messageNotPresent 태그의 속성]

name

요청 스코프에서 메시지를 얻어오기 위한 파라미터 키

property

어떤 메시지들을 꺼낼지 나타내는 프로퍼티 이름. 명시하지 않은 경우 모든 메시지를 꺼낸다.

message

기본적으로 태그는 고정 문자열 Action.ERROR_KEY를 키로 하여 반복되는 요청 스코프 빈을 꺼낸다. 그러나 이 속성을 true로 설정한 경우 요청 스코프의 빈을 Action.MESSAGE_KEY에서 얻는다. 이 속성을 true로 설정한 경우 name 속성에 어떤 값을 할당했다 하더라도 무시한다.



3.Bean 태그


Bean 태그 라이브러리의 태그들은 자바빈과 관련 프로퍼티들에 접근하는 데 이용되며 페이지 스코프 속성들과 변수의 기술을 통해 페이지의 나머지 부분에 쉽게 접근할 수 있는 새 빈을 정의하는 데 이용된다. 이 외에도 Bean 태그 라이브러리의 태그들에서는 요청 쿠키, 헤더 그리고 파라미터 값을 기반으로 하는 새로운 빈을 생성해야 할 때 편리하게 이용할 수 있는 메커니즘도 제공한다.


[List9: Bean 태그 라이브러리의 커스텀 태그들]

cookie

지정한 요청 쿠키의 값에 근거해 변수를 정의

define

지정한 빈 프로퍼티의 값에 근거해 변수를 정의

header

지정한 요청 헤더의 값에 근거해 변수를 정의

include

동적인 애플리케이션 요청의 응답을 로드해 빈으로 이용할 수 있도록 한다.

message

응답이 되는 국제화된 메시지 문자열을 표시

page

지정한 아이템을 빈으로서 페이지 문맥에서 꺼낸다.

parameter

지정한 요청 파라미터 값에 근거해 변수를 정의

resource

웹 애플리케이션 자원을 로드해 빈으로 이용할 수 있도록 한다.

size

Collection 또는 Map의 요소 개수를 포함한 빈을 정의

struts

지정한 스트럿츠 내부 설정 객체를 빈으로 꺼낸다.

write

지정한 빈 프로퍼티의 값을 표시


※Bean 태그 라이브러리에 있는 많은 태그는 잘못 사용하는 경우 런타임 중 JspException을 던진다. JSP는 <%@ page %> 지시어의 errorPage 속성을 통해 에러 페이지를 지정할 수 있다. 이렇게 지정된 에러 페이지에서 문제를 일으킨 실제 예외를 처리할 수 있도록 이 태그에서 발생한 예외는 키가 org.apache.struts.action.EXCEPTION인 요청 속성으로 에러 페이지에 전달된다.


ⅰ.define 태그:

define 태그는 지정한 빈 프로퍼티의 값을 꺼내 현재 페이지의 나머지 부분에서 접근할 수 있는 속성으로 정의한다. 반환되는 프로퍼티 값이 자바 원시 데이터형인 경우를 제외하고 형 변환이 일어나지 않는다. 단, 반환되는 프로퍼티가 자바 원시 데이터형인 경우 이 원시 데이터형 프로퍼티들을 적절한 래퍼 클래스로 변환한다. 그리고 이 프로퍼티 값은 toScope 속성에 지정한 스코프에 저장된다.


...

<!--Ex3: define 태그-->

<td width="490px" style="padding-left:10">

<bean:define id="content” name="boardForm" property="boardValue.content" toScope="request" />

<%= BoardUtils.convertHtmlBr((String)content) %>

</td>

...


ⅱ.header 태그:

header 태그는 지정된 요청의 헤더 값을 꺼내 String 타입의 페이지 스코프 속성으로 정의한다. 지정한 이름의 헤더가 존재하지 않고 동시에 value 속성에 지정된 기본 값도 없는 경우 요청 타임 예외(request-time exception)를 던진다. 또한 이 태그의 multiple 속성에 null이 아닌 값을 설정한 경우 id 속성은 HttpServletRequest.getHeader() 대신 HttpServletRequest.getHeaders()를 호출하여 얻은 결과 값을 포함하게 된다.


<!--Ex4: header 태그(요청 헤더와 헤더 값 출력)-->

<%@ page pageEncoding="euc-kr" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<html>

<body>

<%

  java.util.Enumeration names = ((HttpServletRequest)request).getHeaderNames();

  while(names.hasMoreElements()) {

    String name = (String)names.nextElement();

%>

  <bean:header id="head" name="<%= name %>" />

  <br>Header Name : <%= name %> = <%= head %>

<%

  }

%>

</body>

</html>


ⅲ.include 태그:

include 태그는 지정한 애플리케이션 컴포넌트(또는 외부의 URL)에 내부적으로 요청을 보내어 수행하고 이때 얻은 응답 데이터를 String 타입 빈으로 만든다. 이때 생성된 빈은 id 속성의 값을 변수명으로 가지고 페이지 스코프에 저장된다. 이 태그는 표준 <jsp:include> 태그와 기능은 비슷하다. 그러나 표준 <jsp:include> 태그에서는 해당 컴포넌트를 수행해 얻은 응답 데이터를 직접 출력 스트림에 쓰는 반면 Bean 태그 라이브러리의 include 태그에서는 페이지 스코프 속성의 빈으로 저장한다는 차이점이 있다. 이처럼 지정한 컴포넌트의 응답 데이터가 페이지 스코프 속성 빈으로 저장되기 때문에 이 빈을 사용하여 필요한 어디에서든지 출력할 수 있다.

만일 현재 요청이 세션의 일부라면 include 수행을 위해 생성된 요청에서도 세션 ID를 포함하게 된다. 지정한 애플리케이션 컴포넌트에 접근하는 데 사용되는 URL의 값은 다음 속성을 어떻게 지정했는가에 따라 결정된다.


_forward: 이 속성의 값을 찾아낼 전역 ActionForward의 이름으로 이용한다. 이곳에서 찾아낸 application-relative 또는 context-relative URI를 사용한다.


_href: 이 속성의 값은 변경하지 않고 사용한다(외부 자원에 연결될 수도 있으므로 이 경우 세션 ID가 포함되지 않는다).


_page: 이 속성의 값을 대상 자원의 context-relative URI로 사용한다. 반드시 값이 '/'로 시작해야 한다.


...

<!--include 태그를 이용해서 페이지 범위의 빈에 저장-->

<bean:include id="footerSpacer" page="/long/path/footerSpacer.jsp" />

<!--이제 페이지의 적절한 곳에서 <bean:write>를  이용하여 출력 할 수 있다-->

<bean:write name="footerSpacer" />

...


<!--Ex5: include 태그-->

<%@ page pageEncoding="euc-kr" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<html>

<body>

  <bean:include id="inc" page="/include.jsp" />

  <br>

  원래 페이지 내용<br>

  <bean:write name="inc" />

  <br>========================<br>

  <bean:write name="inc" />

</body>

</html>

 

ⅳ.message 태그:

message 태그는 스트럿츠 태그 라이브러리에서 가장 널리 사용되는 태그 중 하나로서 지정된 메시지 키를 이용하여 지정된 지역의 국제화된 메시지를 꺼내와 출력 스트림에 출력한다. "{0}"과 같은 파라미터 치환을 5개까지 사용할 수 있다.

메시지를 꺼내오는 데 이용되는 메시지 키는 key 속성을 사용하여 직접적으로 지정할 수도 있고 name과 property 속성을 이용하여 빈에서 간접적으로 얻어올 수도 있다. 그리고 bundle 속성에는 MessageResources 객체를 얻어올 수 있는 애플리케이션 스코프 빈의 이름을 지정할 수도 있다. locale 속성을 지정하지 않은 경우 필요한 Locale은 세션에서 키 ActionLOCALE_KEY를 사용하여 얻는다.


...

<td><bean:message key="global.user.firstName" />:</td>

...


ⅴ.parameter 태그:

parameter 태그는 지정된 요청 파라미터의 값을 꺼내 String 타입의 페이지 스코프 속성으로 정의한다. 만일 mutiple 속성에 null이 아닌 값이 설정된 경우 getParameter() 대신 getParameters() 메소드를 호출하고 String[] 타입의 페이지 스코프 속성을 정의하게 된다.


...

<bean:parameter id="param1" name="param1" />

<bean:parameter id="param2" name="param2" multiple="true" />

<bean:parameter id="param3" name="param3" value="UNKNOWN VALUE" />

...


ⅵ.resource 태그:

resource 태그는 지정된 웹 애플리케이션 자원의 값을 꺼내어 input 속성의 값에 따라 InputStream이나 String 타입의 한 형태로 사용할 수 있게 한다. input 속성이 null이 아닌 값일 경우 InputStream을 생성한다. 그 외 경우 자원을 String으로 로딩한다.


<!--Ex6: resource 태그-->

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<html>

<body>

<bean:resource id="webxml" name="/WEB-INF/web.xml" />

<pre>

<!--얻어진 정보를 JSP 페이지에서 보기 위한 코드-->

<bean:write name="webxml" filter="true" />

</pre>

</body>

</html>


ⅶ.write 태그:

write 태그는 빈 태그 라이브러리에서 중요한 태그 중 하나로서 매우 많이 사용되는 태그다. write 태그는 지정된 빈 프로퍼티의 값을 꺼내 String 형태로 페이지에 출력한다. write 태그는 다음과 같은 규칙을 따른다.

  • format 속성을 지정하면 값을 포매팅 문자열과 기본 지역(Locale 인스턴스)에 따라 포매팅한다. 이때 formatKey 속성도 사용할 수 있는데 이는 메시지 리소스 번들의 포맷 문자열 이름을 지정한다.

  • formatKey 속성은 리소스 번들 포맷 문자열을 지정하는 데 사용된다. 사용할 리소스 번들과 지역도 지정할 수 있다. 만일 번들과 지역을 지정하지 않으면 기본 리소스 번들과 현재 사용자의 지역을 사용한다.

  • 그 외 경우 항상 toString() 메소드의 변환을 적용한다.


...

<!--detail 빈의 location 속성 값을 출력-->

<bean:write name="detail" property="location" />

...

 

※ignore 속성을 true로 설정하면 태그는 name과 scope 속성을 통해 지정한 빈이 존재하지 않는 경우에도 예외를 던지지 않고 아무 동작 없이 반환한다. 하지만 ignore 속성을 명시하지 않거나 false로 설정하면 런타임 예외를 던질 것이다.

'Web Development > JSP' 카테고리의 다른 글

Struts HTML 태그라이브러리  (0) 2007.10.15
struts의 bean태그와 html태그  (0) 2007.10.15
JSP태그라이브러리  (0) 2007.10.15
JSP + tomcat + mysql 한글깨짐 현상 완벽정리  (0) 2007.10.15
jsp에서 ms-sql연동  (0) 2007.10.15