Transcript jsp

JSP 정리
레퍼런스:
JSP 2.1 웹 프로그래밍 (최범균, 가메출판사)
목차
1. Directive
- 인코딩
- 오류처리
2. Implicit Object
- 쿠키/세션
3. Action Tag
4. JDBC/DBCP 프로그래밍, 파일업로드
5. Expression Language
6. JSTL
7. 커스텀태그
8. Tiles
9. Filter
10. Listener
11. MVC 패턴
JSP 구성요소
 Directive
: Page, taglib, include
 스크립트
Scriptlet
<% … %>
Expression
<%= … %>
Declaration
<%! … %>
자바소스
함수작성
 Implicit Object
: request, response, session, exception, page, config,
out, pageContext, application
 정적인 데이터
 Action Tag
 Expression language
 Custom Tag, JSTL
디렉티브

<%@ 디렉티브 attr=“val” … %>

Page, taglib(함수를 정의한 태그라이브러리 로딩:EL참조), include
Page 디렉티브 : JSP 페이지의 설정정보 지정
속성
기본값
설명
language
java
jsp 스크립트 코드에 사용되는 언어
contentType
text/html
Jsp가 생성할 문서 타입
※ “text/html; charset=EUC-KR”
: 브라우저의 인코딩메뉴 (기본: ISO-8859-1)
Session
true
세션생성 여부
buffer
8kb
jsp 페이지의 출력버퍼크키 (kb단위/none)
autoFlush
true
False이면 버퍼풀시에 예외발생 및 작업 중지됨
info
errorPage
오류 발생시 실행할 페이지 지정
isErrorPage
false
에러페이지로 지정되어, exception 기본객체 사용가능
pageEncoding
jsp 페이지 자체의 캐릭터인코딩 지정
isELIgnored
web.xml
deferredSyntaxAl
lowedAsLiteral
false
#{
trimDirectiveWhit
espaces
false
생성된 HTML에서 스크립트코드로 인해 생성된 불필요 공백 제
거
import
include 디렉티브
목적
<%@ include file=“~.jspf” %>
포함시킬 파일의 내용을 현위치에 삽입한 JSP를 자바로 변환하여 컴파일
※ jspf의 f는 fragment
용도
- 모든 페이지에 사용되는 공통변수를 지정
- 간단하면서도 모든 페이지에 중복되는 문장 (저작권표시 등)
코드조각
자동포함
기능
(web.xml)
<jsp-config>
<jsp-property-group> <= jsp의 프로퍼티를 지정
<url-patterm> /view/* </url-patterm> <= 프로퍼티 적용할 jsp URL패턴
<include-prelude> /com/variable.jspf </include-prelude>
<include-coda> /com/footer.jspf </include-coda>
<jsp-property-group> <= 프로퍼티그룹이 여러 개인 경우, 입력 순서대로 적용
</jsp-config>
인코딩
파라미터 인코딩/디코딩
POST
브라우저
입력폼 화면이 사용하는 캐릭터셋으로 인코딩
서버
request.setCharaterEncoding()에서 지정된 캐릭터셋으로 인코딩
디폴트 : ISO-8859-1
※ request.setCharaterEncoding()
- 인코딩된 charset으로 디코딩할 수 있도록 지정
- request.getParameter() 전에 사용해야 함.
- HTTP 데이터 영역에 적용됨
GET
브라우저
서버
<a>, <form>
웹페이지에서 사용하는 charset으로 인코딩
주소창입력
(IE, 파이어폭스) 브라우저에 선택된 캐릭터셋
(크롬, 사파리) UTF-8
(톰캣) default : ISO-8859-1
~/conf/server.xml
<connector port=“8080”
URIEncoding=“utf-8”
useBodyEncodingForURI=“true”/>
(제티) default : UTF-8
request.setAttribute(“org.mortbay.jetty.Request.queryEncoding”, “euc-kr”)
※ useBodyEncodingForURI: request.setCharaterEncoding()을 적용
JSP 페이지 인코딩
BOM 으로 시작(O)
BOM으로 결정된 인코딩 -> PageEncoding
※ BOM ≠ pageEncoding => 오류발생
BOM으로 시작 (X),
유니코드 (X)
기본인코딩 -> pageEncoding -> contentType -> ISO-8859-1
※ 단, ascii 이외의 문자가 포함되지 않은 경우
<%@ page contentType=“text/html; charset=utf-8” %>
<%@ page pageEncoding=“euc-kr” %>
<- 응답결과 생성시 인코딩
<- JSP파일 읽을 때 사용할 인코딩
- jsp 페이지를 구현한 파일은 eud-kr로 인코딩됨
- 응답결과는 utf-8으로 생성
※ BOM(Byte Order Mark) : 유니코드 바이트 순서가 little/big endian 여부를 알려주는 값
오류 처리

에러페이지 적용 우선순위
페이지 디렉티브 -> 예외타입별 지정 -> 응답상태 코드별 지정
페이지 디렉티브 이용
<%@ page errorPage=“~.jsp” %>
오류발생시 실행할 페이지 지정
<%@ page isErrorPage=“true” %>
에러페이지로 지정. Exception 기본객체 사용가능
※ ie의 경우, 응답상태코드가 404, 500이고 응답결과 데이터가 512바이트 이하일 때,
지정한 오류페이지 대신 자체 오류화면 출력
예외 타입별 에러페이지 지정 (WEB-INF/web.xml)
<error-page>
<exception-type> java.lang.NullPointerException </exception-type>
<location> error.jsp </location>
</error-page>
응답상태코드별 에러페이지 지정 (WEB-INF/web.xml)
<error-page>
<error-code> 404 </error-code>
<location> error.jsp </location>
</error-page>
주요응답상태코드
200
정상
307
Response.sendRedirect()로 페이지가 리다이렉트됨
400
클라이언트 요청이 잘못된 구문
401
접근이 허용되지 않음
404
지정된 URL에 대한 자원이 없음
405
허용되지 않는 메소드
500
서버내부오류 (JSP에 exception 발생, DB연결실패 등)
503
서버가 일시적으로 서비스제공 불가 (급격한 부하증가 등)
Implicit Object (1)

request, response, session, exception, page, config, out, pageContext, application

페이지 영역 (pageContext)
: 하나의 jsp처리시 사용하는 영역

Request 영역 (request)
: 하나의 http요청처리시 사용되는 영역. 요청처리에 사용되는 모든 jsp 포함

Session 영역 (session)
: 하나의 브라우저와 관련된 영역

Application영역 (application)
: 하나의 어플리케이션과 관련된 영역
※ Attribute 사용 : setAttribute(), getAttributeNames(), removeAttribute(), …
Request - Javax.servlet.ServletRequest, …
클라이언트(브라우저) 관련 정보
getRemoteAddr(), …
서버 관련 정보
getServerName(), …
클라이언트 요청 파라미터
getParameter(), getParameterValues(),
getParameterNames(), …
클라이언트 요청 헤더
getHeader(), getHeaders(), getHeaderNames(),
getIntHeader(), …
클라이언트 전송 쿠키
getCookies()
속성처리 기능
setAttribute(), getAttributeNames(), removeAttribute(), …
Implicit Object (2)
Response - Javax.servlet.http.HttpServletResponse, …
헤더정보 입력
addHeader(), setHeader(), setDateHeader(), containsHeader()
리다이렉트
sendRedirect(URI)
※ URI: java.net.URLEncoder.encode(val, “euc-kr”)로 인코딩할 것
※ 브라우저 캐시제어
Response.setHeader(“Pragma”, “No-cache”);
// HTTP 1.0
Response.setHeader(“Cache-Control”, “no-cache”);
// HTTP 1.1
Response.addHeader(“Cache-Control”, “no-store”);
// FireFox 버그 관련
Response.setDateHeader(“Expires”, 1L); // 0 또는 1로 설정하여 만료일자를 현재시각 이전으로
Session - Javax.servlet.http.HttpSession
세션ID
getId()
속성처리
setAttribute(), getAttribute(), removeAttribute()
getCreationTime(), getLastAccessedTime()
현재 사용중인 세션객체를 삭제하여,
세션종료처리
Invalidate()
세션유효시간지정(초단위)
setMaxInactiveInterval()
Exception - Java.lang.Throwable
에러페이지에서만 사용가능
Page - Java.lang.Object
JSP를 변환한 자바클래스의 인스턴스. 거의 사용하지 않음
Config - Java.servlet.ServletConfig
JSP페이지에 대한 설정정보 저장
Implicit Object (3)
Out - Javax.servlet.jsp.JspWriter
JSP가 생성한 데이터를 브라우저에 전송하는 출력스트림
출력스트림
Print(), newline(), flush(), clear(), getBufferSize(),
getRemaining(), …
PageContext - Javax.servlet.jsp.PageContext
JSP페이지에 대한 정보저장. 하나의 JSP페이지와 1:1 매핑되는 객체
타기본객체 구하기
getRequest(), getSession(), getServletContext(), getOut(), …
속성처리하기
페이지 흐름제어
에러데이터 구하기
Application - Javax.servlet.ServletContext
웹어플리케이션에 대한 정보 저장.
초기설정정보, 서버정보, 리소스텅보 등 특정 웹어플리케이션에 포함된 모든 JSP가 공유
초기화 파라미터
getInitParameter(), getInitParameterNames()
서버(웹컨테이너)
정보
getServerInfo(), getMajorVersion(), …
로그기록
application.log()
log(): JSP가 자체적으로 제공하는 메소드
※ 톰캣의 경우, ~tomcat/logs/localhost.date.log에 기록됨
리소스 접근
String getRealPath(), java.net.URL getResource(), java.io.InputStream
getResourceAsStream()
※ 초기화 파라미터 (WEB-INF/web.xml)
<context-param>
<description> … </description>
<param-name> … </param-name>
<param-value> … </param-value>
</context-param>
쿠키/세션
쿠키
브라우저가 보관하는 데이터로, 웹서버에 요청을 보낼 때마다, 함께 전송됨
서버/브라우저 양쪽에서 생성
addCookie()는 Set-Cookie 헤더를 통해 전달되므로, 출력버퍼 flush전에 쿠키 추가/변경할 것
속성
설명
관련함수
이름
아스키코드 알파벳과 숫자만 포함
getName()
값
알파벳/숫자 이외의 값을 포함한 경우, BASE64 인코딩
필요함
getValue(), setValue()
유효시간
쿠키 유지시간 (초단위)
0:삭제, -1/비지정:세션쿠키,브라우저 닫을 때까지
setMaxAge()
도메인
쿠키를 전송할 도메인 (현재 서버의 도메인/.으로 시작
하는 상위 도메인)
※ 보안정책을 낮추면, 다른 도메인에 대한 쿠키 생성
허용 가능
setDomain()
경로
쿠키를 전송할 경로
별도로 지정하지 않으면, 실행한 JSP의 경로 사용 (주로
“/”로 지정)
setPath()
쿠키사용
new Cookie(“name”, “value”)
Response.addCookie()
동일 이름의 쿠키 값을 변경/생성, 삭제 처리
삭제는 MaxAge=0으로 add
Request.getCookies()
Set-Cookie 헤더 값 예
name=value; Domain=.idp.com; Path=/; Expires=Thu, 29-Jan…GMT
세션
웹 컨테이너에서 보관
서버에서 생성
세션 생성
세션유효시간 지정
(WEB-INF/web.xml)
<%@ page session=“true” %>
Default가 true입
Request.getSession(false)
세션이 없으면 생성하여 리턴
False: 세션이 없으면 null리턴
<session-config>
<session-timeout> 분단위지정
</session-timeout>
</session-config>
0이하는 세션이 제거되지 않음
액션 태그 (1)
<jsp:include page=“~.jsp“ flush=“true” />
지정한 JSP페이지의 실행결과를 현재 위치에 포함시킴
include 디렉티브와 달리, 다른 JSP로 흐름을 이동시켜, 그 결과를 현위치에 포함시킴
※ flush : 지정한 JSP실행 전, 출력버퍼의 flush 여부
<jsp:param name=“~” value=“~” />
<jsp:include>, <jsp:forward>의 엘리먼트로 추가하여, 지정한 page로 파라미터 전달
include 밖에서 전달받은 파라미터와 동일한 이름으로 지정된 경우, 변수가 추가되며, param
tag로 추가된 값이 우선시 된다.
※ request.setAttribute()를 사용하면, 객체를 전달할 수 있으므로 편리하다.
<jsp:forward page=“~.jsp“ />
하나의 jsp에서 다른 jsp페이지로 요청처리를 전달.
요청흐름이 이동할 때, from.jsp에서 사용한 request, response 기본객체가 to.jsp에 전달됨
From.jsp가 아닌 to.jsp에서 생성한 응답결과가 브라우저로 전달되나, 브라우저 주소는 from.jsp
로 유지
출력버퍼가 없거나 flush되어 브라우저에 데이터가 전송된 경우, forword 태그로 이동불가(오류
발생)
<jsp:doBody var=“…” scope=“page” />
커스텀태그의 body부분을 출력하거나 EL변수로 저장
Scope의 default 값 : page
<jsp:attribute name=“속성명” trim=“true|false”> … </jsp:attribute>
fragment=“true”로 정의된 커스텀태그의 태그파일로 attribute 전달
Body에는 <jsp:include … />, EL, text 만 가능하며, 표현식은 불가능
Trim: 속성값 좌우 공백 제거 여부. JSP를 자바코드로 컴파일 하는 단계에서 trim 처리
<jsp:invoke fragment=“속성명” var=“…” scope=“…” />
JSP에서 <jsp:attribute>로 전달한 속성을, 커스텀태그의 태그파일에서 사용
액션 태그 (2)
<jsp:useBean id=“cust” class=“com.vo.CustInfo” type=“com.vo.CustInfo” scope=“request” />
사용할 자바빈 객체 지정(생성)
CustInfo 객체를 생성 -> cust 변수에 할당 -> request 객체의 cust 속성으로 저장
(request.setAttribute(“cust”, cust);
class/type: 지정영역에 객체가 생성되어 있지 않을 경우, class는 생성하고, type은 에러 발생
Scope: page(dafault), request, session, application
<jsp:setProperty name=“BeanId” property=“custId” value=“1234” param=“id” />
자바빈 객체의 프로퍼티 값 지정
Value : 데이터 형에 맞게 변환되며, “”인 경우 0, false가 기본값이다.
Param: request.getParameter(“id”)의 값
<jsp:setProperty name=“BeanId” property=“*” />
: 각각의 프로퍼티를 같은 이름의 파라미터 값으로 세팅
<jsp:getProperty name=“BeanId” property=“custId” />
자바빈 객체의 프로퍼티 값 출력
※ 자바빈
- 데이터를 표현하는 것을 목적으로 하는 자바 클래스
- 데이터저장필드, get메소드, set 메소드로 구성
JDBC 프로그래밍
① JDBC
Class.forName(“oracle.jdbc.driver.OracleDriver”)
드라이버 로딩
※ Class.forName()
클래스인스턴스를 구하는 기능
JDBC 관련 클래스는 로딩시에 DriverManager에 JDBC드라이버로 등록한다.
※ WEB-INF/lib 에 드라이버 복사할 것
※ 웹어플리케이션 구동동시 한번만 로딩하면 됨
- Class.forName()을 서블릿클래스(init())로 작성한 후, web.xml에 등록
- web.xml
<servlet>
<servlet-name> JDBCDriverLoader </servlet-name>
<servlet-class> package.LoaderClass </servlet-class>
<init-param>
<param-name> … </param-name>
<param-value> … </param-value>
</init-param>
<load-on-startup> 1 </load-on-startup>
</servlet>
※ <init-param>
- init()에 전달되는 파라미터
- ServletConfig conf.getInitParameter() 사용
② DB커넥션
구하기
Connection conn = DriverManager.getConnection(jdbcURL, …)
③ Statement
객체생성
Statement stmt = conn.CreateStatement()
PreparedStatement pstmt = conn.prepareStatement()
※ JDBC URL
(oracle) jdbc:oracle:thin:@host:port:SID
(mySQL) jdbc:mysql://host:port/DB명?param=value
※ PreparedStatement
setString(), setFloat(), setDate(),…
setCharaterStream() : StringReader, FileReader에서 읽어와 LONG VARCHAR 값
을 지정
④ 쿼리실행
executeQuery()
executeUpdate()
⑤결과사용
(ResultSet)
getString(), getInt(), getLong(), getTimestamp(), …
getCharaterStream() : LONG VARCHAR 타입을 스트림형태로 읽기
Next(): 커서 이동
⑥ Statement,
커넥션 종료
Close()
JDBC 프로그래밍
CLOB 처리
오라클 10g부터는 varchar와 동일하게 처리 가능하나, 메모리 부족 방지를 위해 스트림 이용가능
① EMPTY_CLOB()
INSERT문의 경우, EMPTY_CLOB()을 insert
② DB LOCK
-FOR UPDATE로 테이블 SELECT
- Clob clob = rs.getClob()
③ 스트림 구하기
Insert/update
Writer w =
((oracle.sql.CLOB)clob).getCharacterOutputStream()
Select
Reader r = clob.getCharacterStream()
Insert/update
w.append(data)
select
r.read(buff)
④ CLOB 데이터
읽기/쓰기
: 데이터 길이만큼 반복
⑤ 스트림 닫기
트랜잭션 처리
JDBC 오토커밋 모드
단일 DB에 접근
Connection.setAutoCommit(), commit(), rollback()
JTA(Java Transaction API) 이용
둘 이상의 데이터베이스 작업에 이용
자카르타 DBCP를 이용한 커넥션 풀 사용
① 라이브러
리설치
WEB-INF/lib
commons-dbcp-1.22.jar
Commons-pool-1.4.jar
~tomcat/common/lib
JDBC 드라이버
② 설정파일
작성
WEB-INF/classes/설정파일.jocl
③ 커넥션풀
초기화 (드라
이버로딩)
JDBC 드라이버 : Class.forName(“JDBC Driver Class”)
<object class=“…dbcp.PoolableConnectionFactory” xmlns=“…/jocl”>
<object class=“…dbcp.DriverManagerConnectionFactory”>
<string value = “JDBC URL” />
<string value = “DB username” />
<string value = “DB password” />
</object>
<object class=“…pool.impl.GenericObjectPool”> 커넥션풀관련 추가설정정보
<object class=“…pool.PoolableObjectFactory” null=“true”/>
<int value=“10”/> <!– maxActive -->
<byte value=“…”/> <!– whenExhaustedAction-->
<long value=“…”/> <!– maxWait-->
<int value=“…”/> <!– maxIdle -->
<int value=“…”/> <!– minIdle -->
<boolean value=“…”/> <!– testOnBorrow -->
<boolean value=“…”/> <!– testOnReturn -->
<long value=“…”/> <!– timeBetweenEvictionRunsMillis-->
<int value=“…”/> <!– numTestsPerEvictionRun-->
<long value=“…”/> <!– minEvictableIdleTimeMillis -->
<boolean value=“…”/> <!– testWhileIdle -->
</object>
<object class=“..pool.KeyedObjectPoolFactory” null=“true”/>
<string null=“true”/> 커넥션 유효 검사용 쿼리
<boolean value=“false”/> 읽기 전용 여부
<boolean value=“true”/> auto commit 여부
</object>
DBCP API의 JDBC 드라이버 : Class.forName(“org.apache.commons.dbcp.PoolingDriver”)
※ web.xml에 load-on-startup 이용
④ 커넥션풀
사용
DriverManager.getConnection(jdbcURL)
※ jdbcURL => jdbc:apache:commons:dbcp:/풀이름(jocl파일명에서 확장자 제외)
※ conn.close() : 커넥션 풀에서 구한 connection의 경우, 풀로 반환함을 의미
- jocl : 웹어플리케이션에서 직접 커넥션 만들어서 사용
- 톰캣 context.xml : 컨테이너 제공 DB 커넥션 풀 사용 (내부적으로 dbcp사용)
파일업로드
파일업로드
 자카르타 Commons FileUpload API 사용
WEB-INF/lib
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
 클라이언트에서 파일 업로드
<form action=“…” method=“post” enctype=“multipart/form-data”>
 전송된 파일을 처리하는 API
① Fileupload.disk.DiskFileItemFactory
setSizeThreshold()
setRepository()
메모리저장 최대 파일사이즈. 바이트단위 (default:10240)
임시파일을 저장할 디렉토리 (default: 시스템기본 임시디렉토리)
※ 기본 임시디렉토리: Sytstem.getProperty(“java.io.tmpdir”)
② Fileupload.servlet.ServletFileUpload : 업로드 요청을 처리 new ServletFileUpload(factory)
isMultipartContent()
multipart/form-data 형식인지 확인
parseRequest()
Request를 파싱해서 FileItem 리스트 생성
setSizeMax()
한번에 업로드 가능한 전체파일 크기
setFileSizeMax()
업로드 파일 최대 크기
③ Fileupload.FileItem : 멀티파트로 전송된 파라미터 및 파일정보 저장
isFormField()
파라미터/파일 구분
getFieldName(), getString()
파라미터명, 값
getName(), getSize()
파일명, 사이즈(0:업로드하지 않음)
write()
전송된 파일을 디스크에 저장
getInputStream()
전송된 파일을 읽기위한 스트림 리턴
get()
전송된 파일전체를 byte배열로 메모리에 로딩
isInMemory()
전송된 파일 위치 (메모리/임시디렉토리)
delete()
파일관련 자원 즉시제거(FileItem 가비지컬렉션때 임시파일 자동삭제)
전송된 파일에 특
별한 처리를 하거
나 DB에 저장할 때
파일다운로드
response.setContentType(“application/octet-stream”) 다운로드를 위한 콘텐츠타입 지정
response.setHeader(“Content-Disposition”, “attachment; filename=sample.txt”) 파일명은 ISO-
8859-1로 인코딩
response.setHeader(“Content-Transfer-Encoding”, “binary”)
response.ContentLength()
파일사이즈 지정
response.getOutputStream() 파일을 inputStream으로 읽어서 OutputStram에 write
Expression Language (1)

JSP 스크립트 요소 중 표현식을 간결하게 사용할 수 있는 스크립트 언어

용도
- 기본객체의 attribute 사용 : ${requestScope.CustVO.name}
- 액션태그, 커스텀 태그의 속성값
<jsp:include page=“/${folder_name}/${file_name}.jsp“ />
- 함수호출을 사용한 값의 포매팅
기본문법
${expr}
- 구문 분석 시점에 값을 계산
- JSP 2.0 (서블릿 2.4) 부터 지원
#{expr}
- 사용시점에 매번 값을 계산
- deferred expression을 허용하는 태그의 속성으로만 사용가능
- JSP 2.1 (서블릿 2.5) 부터 지원
※ expr : 객체 접근시 expr.expr 또는 expr[expr]의 형태로 사용
※ \${expr}, \#{expr} : “${expr}”, “#{expr}”를 그대로 출력
EL이 제공하는 기본객체
pageContext
JSP의 page 기본객체와 동일
${pageContext.requ
est.requestURI}
pageScope
pageContext의 Attribute에 대한 Map<속성,값> 객체
${requestScope.nm}
requestScope
request의 Attribute에 대한 Map<속성,값> 객체
sessionScope
session의 Attribute에 대한 Map<속성,값> 객체
applicationScope
application의 Attribute에 대한 Map<속성,값> 객체
Param
요청파라미터에 대한 Map<파라미터이름,값> 객체
paramValues
요청파라미터에 대한 Map<파라미터이름,값배열> 객체
header
요청정보에 대한 Map<헤더이름,값> 객체
Request.getHeader(이름)의 결과와 동일
headerValues
요청정보에 대한 Map<헤더이름,값배열> 객체
Request.getHeaders(이름)의 결과와 동일
cookie
Map<쿠키이름,Cookie> 객체
initParam
초기화 파라미터에 대한 Map<이름,값> 객체
Application.getInitParameter(이름)의 결과와 동일
${nm}
page→req→sess→a
pp의 순서 적용
${param.cust_name}
${cookie.userid.value}
Expression Language (2)
데이터 타입 및 연산자
데이터타입
Boolean, 정수, 실수, 문자열, null
연산자
+-*/%
-객체를 숫자로 변환하여 계산, null은 0
-정수를 나눈 결과도 실수
== != < > <= >=
- 객체의 비교는 compareTo() 사용
&& || !
empty 값
Null, 길이가 0인 객체 판단
?:
비교선택연산자
자바클래스 함수 호출 기능
static method만 호출 가능
① TLD(Tag Library Descriptor) 파일작성 : 태그라이브러리에 대한 설정정보 (WEB-INF 하위에)
<taglib xmlns=…>
<description> … </description>
<tlib-version> … </tlib-version>
<short-name> … </short-name>
<function>
EL에서 사용할 함수정의
<description> … </description>
<name> myMethod</name>
EL에서 사용할 함수명
<function-class> package.className </function-class>
<function-signature> return_type method_name(arg_type) </function-signature>
</function>
return_type, arg_type은 패키지명까지 적어줄 것
</taglib>
② web.xml에 TLD 파일에 대한 정보 추가
<jsp-config>
<taglib>
<taglib-uri> /WEB-INF/tlds/sample.tld </taglib-uri> JSP에서 taglib를 참조하는 식별자
<taglib-location> /WEB-INF/tlds/sample.tld</taglib-location> TLD파일 위치
</taglib>
</jsp-config>
③ EL에서 함수 사용
<%@ taglib prefix=“mylib” uri=“/WEB-INF/tlds/sample.tld“ %>
${mylib:myMethod(…)}
Expression Language (3)
EL 비활성화 방법
적용 우선순위: JSP페이지 옵션 > web.xml 옵션 > web.xml 버전
① JSP 페이지에 비활성화 옵션 지정
<%@ page isELIgnored=“true” %>
${expr}, #{expr}을 문자열로 처리
<%@ page deferredSyntaxAllowedAsLiteral=“true” %>
#{expr}을 문자열로 처리
② web.xml에 비활성화 옵션 지정
<jsp-config>
<jsp-property-group>
<url-pattern> … </url-pattern>
<el-ignored> true </el-ignored>
<deferred-syntax-allowed-as-literal> true </deferred-syntax-allowed-as-literal>
</jsp-property-group>
</jsp-config>
③ web.xml 파일을 EL지원 서블릿 버전에 맞춰 작성
서블릿 2.3
(JSP 1.2)
-EL 지원하지 않음
- XML스키마가 아닌 DTD이용
<!DOCTPYE web-app PUBLIC … “http://java.sun.com/dtd/web-app_2_3.dtd”>
<web-app> … </web-app>
서블릿 2.4
(JSP 2.0)
-${expr} 만 지원
- 네임스페이스가 j2ee로 끝나고, 스키마경로가 web-app_2_4.xsd
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="..."
xsi:schemaLocation="... http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
</web-app>
JSTL (1)
JSTL (JSP Standard Tag Library)
- 커스텀 태그 중 많이 사용되는 것을 모아서 만든 규약
- 스크립트 코드를 간결한 형식으로 대체
- JSTL 1.2는 JSP 2.1에서 지원
※ Tomcat6는 JSP2.1을 지원하나 JSTL1.2는 미포함 (WEB-INF/lib/jstl-1.2.jar)
JSTL 태그 종류
라이브러리 (접두어)
기능
URI
코어 (c)
변수지원, 흐름제어, URL처리
http://java.sun.com/jsp/jstl/core
국제화 (fmt)
지역, 메시지형식, 숫자/날짜 형식
하나의 JSP에서 다양한 언어지원
http://java.sun.com/jsp/jstl/fmt
함수 (fn)
컬렉션, String 처리
http://java.sun.com/jsp/jstl/functions
XML (x)
XML코어, 흐름제어, XML변환
http://java.sun.com/jsp/jstl/xml
데이터베이스 (sql)
SQL
http://java.sun.com/jsp/jstl/sql
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
코어-변수지원
<c:set>
JSP에서 사용할 변수 생성 및 값 할당
var
String
EL변수명
value
Object (E/EL)
변수에 할당할 값. (null: map/기본객체의 경우, 속성삭제)
<c:set …> 변수값 </c:set>의 형식 가능
scope
String
Page, request, session, application
target
Object (E/EL)
프로퍼티값을 설정할 객체. 자바빈/Map
Property
String (E/EL)
프로퍼티명
- EL변수 생성: <c:set var=“mapServerInfo” value=“<%= myMap %>”/>
- 객체의 프로퍼티값 설정: <c:set target=“${mapServerInfo}” property=“host” value=“localhost” />
- Deferred Expression을 값으로 설정: <c:set var=”myVar” value=“#{expr}” />
<c:remove>
변수 제거
var
String
EL변수명
scope
String
지정하지 않으면, 모든 영역을 대상으로 삭제
JSTL (2)
코어-흐름제어
<c:if>
else문은 없음
Test
boolean (E/EL)
조건. Deferred Expression은 불가능
Var
String
조건의 결과값을 저장할 EL변수
<c:if test=“${param.name == ‘kim’}” var=“testResult”> …</c:if>
조건 검사 결과: ${testResult}
<c:choose>
Test 결과가 참인 첫번째 조건만 실행됨
<c:choose>
<c:when test=“조건”> … </c:when>
<c:otherwise> … </c:otherwise>
</c:choose>
<c:forEach>
배열, Map, Collection에 저장된 값을 순차적으로 사용
var
String
Body에서 사용할 EL변수명
items
(E/EL)
대상데이터 (Collection, Iterator, Enumeration, Map, 배열)
begin, end, step
int (E/EL)
시작/종료 인덱스, 인덱스 증분값
varStatus
String
루프상태를 저장할 EL변수명
Index: 현재인덱스
Begin, end, step: forEach 속성값
Count: 루프실행회수
First, last : booean
Current: 현재 컬렉션 객체
<c:forEach var=“i” items=“${myMap}” varStatus=“status”>
${status.index} : ${i.key} : ${i.value}
</c:forEach>
<c:forTokens>
var
String
EL변수명
items
String(E/EL)
문자열
delims
구분자. “,.”과 같이 2개이상 지정하면, 각각 모두 나눔
begin, end, step
int (E/EL)
시작/종료 인덱스, 인덱스 증분값
varStatus
String
루프상태를 저장할 EL변수명
<c:forTokens var=“token” items=“a,b,c,d;e;f” delims=“,:”>
${token}
</c:forTokens>
JSTL (3)
코어-URL처리
<c:import>
특정 URL의 결과를 출력/저장
url
String (E/EL)
절대 URL: java.net.URL, java.netURLConnection 이용
상대 URL: <jsp:include> 액션태그와 동일 (실행결과 삽입)
Var
String
URL에서 읽은 결과저장 EL변수 (지정하지 않으면 현위치에 출력)
scope
String
EL변수생성영역
charEncoding
String (E/EL)
캐릭터셋
※ 인코딩 방식
- 절대 URL : charEncoding 속성 -> URLConnection.getContentType() -> ISO-8859-1
- 상대 URL : <% request.setCharacterEncoding(“…”); %> <c:import> 전에 캐릭터셋 지정
※ 파라미터 전달
- <c:param name=“…” value=“…” />
page 디렉티브의 contentType으로 인코딩됨
- URL속성을 이용하여 GET방식으로 전달 별도로 인코딩 처리 필요함
<c:url>
URL 생성/출력
value
String (E/EL)
URL (상대URL을 절대경로로 지정할 경우 Context가 추가됨)
var
String
EL변수명
scope
String
EL변수생성영역
※ <c:param>을 body에 추가하여 파라미터 설정 가능: page 디렉티브의 contentType으로 인코딩
<c:redirect>
지정한 경로로 리다이렉트. <c:redirect> 이후의 코드는 실행되지 않음
url
String (E/EL)
URL (절대경로로 지정할 경우 현재 Context가 추가됨)
context
String(E/EL)
Context 경로
※ <c:param>을 body에 추가하여 파라미터 설정 가능
코어-기타
<c:out>
JspWriter에 데이터 출력
value
Object (E/EL)
JspWriter에 출력할 값. String, java.io.Reader 종류…
escapeXml
Boolean (E/EL)
< > & ‘ “를 변환 (true, false)
default
Object (E/EL)
Value에 지정한 값이 존재하지 않을 때 사용. Body에 기술 가능
<c:catch>
<c:catch var =“ex”>
소스코드
</c:catch>
${ex}
발생된 예외를 EL변수에 저장
JSTL (4)
국제화-지역
<fmt:setLocale>
국제화태그에서 Accept-Language가 아닌 다른 언어를 사용하도록 로케일 지정
value
Locale을 언어코드-국가코드 형식으로 지정 ex) “ko”, “ko-kr”
null: web.xml이나 JVM의 기본로케일 사용
scope
지정한 locale이 영향을 미치는 범위 (default: page)
※ Accept-Language : 브라우저가 수용가능한 언어목록을 전송하는데 사용하는 헤더
<fmt:requestEncoding>
요청파라미터의 캐릭터인코딩을 지정
<fmt:requestEncoding value=“euc-kr” /> <% request.setCharacterEncoding(“euc-kr”); %>와 동일
국제화-메시지처리 (언어권에 따라 알맞은 메시지 출력)
<fmt:bundle>
body에서 사용할 리소스번들 지정
Basename
사용할 리소스번들명 (클래스경로기준으로 “패키명.번들이름” 형식)
Prefix
하위 <fmt:message>태그 내 key속성 값에 붙일 prefix
<fmt:bundle basename=“resource.message” prefix=“SYSTEM_”>
<fmt:message key=“001” /> message 리소스번들에서 SYSTEM_001로 지정된 메시지 출력
</fmt:bundle>
※ 리소스 번들 (파일명에 지정한 로케일에 따라 사용할 리소스번들 결정)
- 이름: 번들이름_언어_국가.properties
- 내용: key = value 형식으로 구성
<fmt:setBundle>
특정 메시지 번들을 로딩하여 변수에 저장
var
String
EL변수명
Basename
String (E/EL)
리소스번들 이름
scope
String
EL변수생성영역
message_ko.properties
SYSTEM_001 = ABC
VISITOR = Your ID is {0}
<fmt:setBundle var=“myMessage” basename=“resource.message” />
<fmt:message bundle=“${myMessage}” key=“VISITOR”>
<fmt:param value=“${param.id}” /> 리소스번들의 {0} 부터 순서대로 적용
</fmt:message >
<fmt:message>
지정한 리소스번들에서 메시지를 읽어, 지역에 알맞은 메시지 출력
key
읽어올 키 값
var
메시지 저장할 EL변수명
scope
변수저장영역
Bundle
<fmt:setBundle>로 로딩한 리소스번들 변수
※ 리소스번들 적용 순서 : Bundle 속성값 -> <fmt::bundle> 지정값 -> 기본리소스번들
기본리소스번들 (web.xml) : javax.servlet.jsp.jstl.fmt.localizationContext
JSTL (5)
국제화-숫자/날짜 포맷팅
<fmt:formatNumber>
숫자를 포매팅한 문자열로 변환
value
String, Number (E/EL)
숫자값
Type
String (E/EL)
number, percent, currency
Pattern
String (E/EL)
출력양식 (java.text.DecimalFormat에 정의된 패턴)
currencyCode
String (E/EL)
통화코드 (ISO4217)
currencySymbol
String (E/EL)
통화 표현 기호
groupingUsed
boolean (E/EL)
,등으로 단위 구분 (True, false)
var, scope
String
변수명, 영역(default: page)
<fmt:parseNumber>
문자열을 숫자로 변환
value
String (E/EL)
파싱할 문자열
Type
String (E/EL)
Value의 타입 : number, currency, percentage
Pattern
String (E/EL)
파싱할 양식
parseLocale
String, java.util.Locale (E/EL)
파싱할 통화코드
integerOnly
Boolean (E/EL)
정수부분만 파싱 (true, false)
Var, scope
String
변수명, 영역(default: page)
<fmt:formatDate>
Date 객체를 포맷팅
value
Java.util.Date (E/EL)
포맷팅할 날짜값
Type
String (E/EL)
포맷팅 대상 : time, date, both
dateStyle, timeStyple
String (E/EL)
포매팅 스타일 : default, short, medium, long, full
Pattern
String (E/EL)
파싱할 패턴. java.text.DateFormat 사용
timeZone
String, java.util.TimeZone (E/EL)
변경할 시간대
Var, scope
String
변수명, 영역(default: page)
<fmt:parseDate>
문자열을 Date 객체로 변환
value
String (E/EL)
파싱할 날짜 문자열
Type
String (E/EL)
포맷팅 대상 : time, date, both
dateStyle, timeStyple
String (E/EL)
포매팅 스타일 : default, short, medium, long, full
Pattern
String (E/EL)
파싱할 패턴. java.text.DateFormat 양식 사용
timeZone
String, java.util.TimeZone (E/EL)
변경할 시간대. <fmt:setTimeZone>생성 객체사용
parseLocale
String. Java.util.Locale (E/EL)
파싱할 때 사용할 로케일
Var, scope
String
변수명, 영역(default: page)
<fmt:timeZone>
시간대를 지정
<fmt:timeZone value=“시간대”>
<fmt:formatDate … />
</fmt:timeZone>
<fmt:setTimeZone>
value: String, java.util.TimeZone
timeZone에서 지정한 시간대에 맞게 출력
시간대정보를 변수에 저장
<fmt:formatDate>, <fmt:parseDate>의 timeZone 속성에 사용가능
JSTL (6)
국제화
※ 리소스번들 생성시 인코딩 처리
$native2ascii 소스파일명 변환파일명
※ 브라우저 기본로케일 설정
(ie) 도구->인터넷옵션->언어
※ 국제화 태그 기본값 설정 : web.xml에 콘텍스트 초기화 파라미터 이용
Javax.servlet.jsp.jstl.fmt.localizationContext
기본 리소스번들 (basename) 지정 (basename)
Javax.servlet.jsp.jstl.fmt.locale
기본로케일 지정
Javax.servlet.jsp.jstl.fmt.timeZone
기본 시간대 지정
<web-app>
<context-param>
<param-name> javax.servlet.jsp.jstl.fmt.localizationContext </param-name>
<param-value> resource.message </param-value> package.properties파일명 형식
</context-param>
</web-app>
함수
length(), toUpperCase, toLowerCase()
substring(), substringAfter(), substringBefore(), trim(), replace()
indexOf(), startsWith(), endsWith(), contains(), containsIgnoreCase()
split(), join(), escapeXml()
<c:set var=“myString” value=“…” .>
length: ${fn:length(myString)}
커스텀태그 (1)
※ 커스텀 태그
JSTL, JSP액션태그 이외에 목적에 맞게 작성된 태그
재사용성 향상, 쉽고 단순, 코드 가독성 향상
구현방법
JSP1.2방식
JSP2.0이상, SimpleTag 이용
JSP2.0이상, 태그파일 이용
- 자바개발자에 적합
- 상속받거나 커스텀태그의 표준인터페이스를 구현
- TLD를 web.xml에 기술
- JSP와 동일한 문법 사용
- 웹컨테이너가 태그파일을 커스텀태그클래스로 변환
- TLD불필요 (태그파일에 커스텀태그정보 포함)
태그파일
파일 위치
/WEB-INF/tags 하위 디렉토리
tablib 디렉티브의 tagdir 속성의 값
확장자
*.tag, *.tagx
확장자를 제외한 파일명이 커스텀태그의 이름
기본객체
jspContext
pageContext의 setAttribute(), getAttribute() 제공
request
Jsp와 동일
Response
Session
Application
out
디렉티브
tag
태그파일 관련 설정정보 (JSP의 page 디렉티브 역할)
Taglib
태그파일에서 사용할 태그라이브러리 명시. (태그파일에서 다른 커스텀태그 사용가능)
Include
태그파일에 특정 파일(태그파일 문법 준수) 포함
Attribute
커스텀태그로 부터 태그파일로 입력 받을 속성 명시. TLD파일의 <attribute>에 해당
IN 파라미터 개념, jSP에서 변수생성
variable
EL변수로 사용될 변수정보. TLD파일의 <variable>에 해당
OUT 리턴파라미터 개념, 태그파일에서 변수생성
커스텀태그 (2)
디렉티브
<%@ tag … %>
display-name
도구에서 보여줄 태그파일명
Default: 확장자 .tag를 제외한 파일명
Description
태그에 대한 설명
Import
Page 디렉티브와 동일
pageEncoding
isELIgnored
deferredSyntaxAllowedAsLiteral
trimDirectiveWhitespaces
Body-content
Body 내용의 종류
- empty : 커스텀 태그 body에 내용이 없음
- tagdependent : body 내용을 text로 사용
- Scriptless : body에 포함된 EL, 액션태그가 처리된 결과를 사용
(myTag.tag)
(jsp파일)
Dynamic-attributes
<jsp:doBody var=“변수명” scope=“영역” />
<tf:myTag attr1=“…”>
<jsp:attribute name=“attr2”> … </jsp:attribute>
<jsp:body>
<jsp:attribute>가 있을 때, <jsp:body>로 명시
…
text, EL, <jdp:include>만 가능. 표현식(X)
</jsp:body>
</tf:myTag>
- 동적속성이 저장될 java.util.Map 타입의 EL변수명
- page 속성에 저장 (jspContext로 접근)
- Attribute 디렉티브로 미리 속성을 결정할 수 없을 때 사용
(예: HTML의 <select><option>태그에 이용)
(dyn.tag)
<%@ tag dynamic-attributes=“myMap” %>
$(myMap.attrName}
성공attrName 속성값
<c:forEach items=“${myMap}” var=“option”>
${option.key} : ${option.value}
succ : 성공 …
</c:forEach>
(jsp파일)
<tf:dyn succ=“성공” fail=“실패” />
태그파일 attribute 디렉티브에 지정되지 않은 속성은 동적속성으로 전달
<%@ taglib … %>
<%@ taglib preifx=“tf” tagdir=“/WEB-INF/tags” %>
<tf:myTag> … </tf:myTag>
/WEB-INF/tags/myTag.tag 사용
커스텀태그 (3)
디렉티브
<%@ attribute … %>
Description
속성 설명
name
속성명 : 스크립트변수, EL변수명으로 사용됨
Variable 디렉티브의 name-given. Tag의 dynamic-attributes와 중복 불가
required
True, false
rtexprvalue
속성값으로 표현식가능 여부: True, false
type
속성의 타입(래퍼타입 이용). default: java.lang.String
fragment
<jsp:attribute>액션태그로 속성값 전달 여부: True, false
※ true: rtexprvalue=false, type=javax.servlet.jsp.tagext.JspFragment로 자동지정
(MyAttr.tag)
<%@ attribute name=“title” %>
<%= title %> ${title}
(jsp파일)
<tf:MyAttr title=“…” />
(frag.tag)
<%@ attribute name=“title” fragment=“true” %>
<jsp:invoke fragment=“title” />
출력
<jsp:invoke fragment=“title” var=“rs” scope=“page” /> 저장후 출력
${pageScope.rs}
(jsp파일)
<tf:frag>
<jsp:attribute name=“title”> ${param.title} </jsp:attribute>
</tf:frag>
커스텀태그 (4)
디렉티브
<%@ variable … %>
JSP 컨테이너는 variable의 given-name에 지정한 변수를 JSP의 EL변수로 복사함
일종의 리턴변수 개념인 듯
JSP에서 태그파일과 동일한 변수를 변경해도, 태그파일의 변수값은 변경되지 않음
Name-given
JSP페이지로 리턴될 변수명
Variable-class
변수타입 (default: java.lang.String)
scope
AT_BEGIN: 태그파일의 시작태그 시점부터 사용가능
<jsp:doBody> 실행전과 태그 끝에서, JSP의 변수에 동기화 처리
AT_END: 태그파일의 끝태그 이후부터 사용가능
태그끝에서 동기화
NESTED: 태그파일의 시작태그와 끝태그 사이에서 사용가틍(커스텀태그의 body내)
doBody 실행전 동기화(동일변수명이 있으면 블럭내 지역변수처럼 행동)
Name-fromattribute
JSP페이지 커스텀태그에서 변수명이 저장된 속성명
※ 변수명으로 사용될 속성: rtexprvalue=false, required=true,
type=java.lang.String 이어야 함
alias
태그파일에서 사용할 변수명
(given.tag)
(jsp파일)
(AttrVar.tag)
(jsp파일)
<%@ variable name-given=“myReturn” variable-class=“java.lang.String”
scope=“AT_END” %>
<c:set var=“myReturn” value=“success” />
<tf:given />
${myReturn}
<%@ attribute name=“var” type=“java.lang.String” rtexprvalue=“false”
required=“true” %>
<%@ variable name-from-attribute=“var” alias=“rs” variableclass=“java.lang.String” scope=“AT_BEGIN” %>
<set var=“rs” value=“…” />
<tf:AttrVar var=“myResult” />
${myResult}
Tiles를 이용한 레이아웃템플릿 처리 (1)
※ Composite View: 레이아웃 중복코드를 제거하기 위해, 레이아웃 구성 정보에 대한 템플릿 작성
※ Tiles2를 이용한 Composite View 구현
① WEB-INF/lib에 jar 복사
tiles-api-2.1.2.jar
(Tiles2가 사용하는 외부 라이브러리)
tiles-jsp-2.1.2.jar
commons-beanutils-1.8.0.jar
tiles-core-2.1.2.jar
commons-digester-1.8.1.jar
tiles-servlet-2.1.2.jar
commons-logging-api-1.1.jar
② Tiles 엔진 초기화 (web.xml)
<방법1: TilesServlet 설정>
<방법2: TilesListener 설정>
<servlet>
<servlet-name> tiles </servlet-name>
<servlet-class>
org.apache.tiles.web.startup.TilesServlet
</servlet-class>
<init-param>
<param-name>
<listener>
<listener-class>
org.apache.tiles.web.startup.TilesListener
</listener-class>
</listener>
<context-param>
<param-name>
org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
</param-name>
<param-value>
/WEB-INF/tiles-hello.xml
</param-value>
</init-param>
<load-on-startup> 1 </load-on-startup>
</servlet>
org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
</param-name>
<param-value>
/WEB-INF/tiles-hello.xml 설정파일 목록
</param-value>
</context-param>
(공백없이 ,로 나열)
※ TilesDispatchServlet : 웹요청 URI와 동일한 이름(context, 확장자제외)의 Definition 호출
<servlet>
<servlet-name> TilesDispatchServlet </servlet-name>
<servlet-class> org.apache.tiles.web.util.TilesDispatchServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name> TilesDispatchServlet </servlet-name>
<url-pattern> *.tiles </url-pattern>
</servlet-mapping>
http://localhost:8080/idp/index.tile
<= definition 이름 index를 출력
Tiles를 이용한 레이아웃템플릿 처리 (2)
③ Tiles 설정파일 작성 : 템플릿 JSP 및 템플릿의 각 영역에 대한 정보 설정
<!DOCTYPE tiles-definitions …>
<tiles-definitions>
<definition name=“idp.base” template=“/template/layout.jsp">
<put-attribute name=“header” value=“/template/header.jsp” />
<put-attribute name=“body”>
<definition template=“/template/body.jsp”>
Definition 중첩가능
<put-attribute name=“menu” value=“/home/menu.jsp/” />
<put-attribute name=“content” value=“/home/content.jsp” />
</definition>
</put-attribute>
</definition>
<definition name=“idp” extends=“idp.base”>
definition 상속 후, attribute 추가/변경 가능
<put-attribute name=“title” value=“헬로월드” />
<put-attribute name=“header” value=“/template/header2.jsp” />
</definition>
<definition name=“idp_home” template=“/template/layout.jsp” preparer=“idp.MenuPreparer”>
<put-attribute name=“main” value=“idp.base” />
다른 Definition을 재사용
<put-attribute name=“footer” value=“/template/footer.jsp” />
</definition>
</tiles-definitions>
※ ViewPreparer : 공통화면에 필요한 데이터를 생성하기 위해 사용하는 인터페이스
execute{tileRequestContext, AttributeContext)를 구현하여 데이터 전달 가능
인터페이스 구현시 데이터 전달
JSP에서 데이터 사용
tileRequestContext.getRequestScope().put()
request.getAttribute()
attributeContext.putAttribute()
<tiles:importAttribute name=“title” />
${title}
④ 레이아웃 템플릿 JSP 작성
<tiles:getAsString name=“attribute명” ignore=“true|false” />
: 해당 attribute 값을 현재 위치에 문자열로 삽입 (ignore = false: 런타임예외 발생)
<tiles:insertAttribute name=“속성명” flush=“true|false” ignore=“true|false” />
: 해당 attribute의 JSP 실행결과를 현위치에 삽입 (<jsp:include>와 동일)
<%@ taglib prefix=“tiles” uri=“http://tiles.apache.org/tags-tiles” %>
<head><title> <tiles:getAsString name=“tiltle” /> </title></head>
<tiles:insertAttribute name=“header” />
<tiles:insertAttribute name=“body” />
⑤ 템플릿을 사용하는 JSP 작성
<%@ taglib prefix=“tiles” uri=“http://tiles.apache.org/tags-tiles” %>
<tiles:insertDefinition name=“idp_home” template=“/home/layout.jsp“ />
<tiles:putAttribute name=“footer” value=“/home/footer.jsp“ />
Definition 설정값 수정 가능
</tiles:insertDefinition>
<tiles:insertTemplate template=“/template/layout.jsp“>
설정파일을 이용하지 않고 템플릿사용
<tiles:putAttribute name=“header” value=“/template/header.jsp“ />
<tiles:putAttribute name=“body” value=“/template/body.jsp“ />
</tiles:insertTemplate>
Filter (1)

클라이언트의 요청/응답과 최종 자원(서블릿, jsp, 기타문서) 사이에 위치하여,
요청/응답을 알맞게 변경할 수 있는 재사용 가능한 코드

용도
- 사용자 인증, 권한 체크
- 데이터 변환 (파일압축, 데이터 암호화, 이미지 변환)
- XSL/T를 이용한 XML 문서 변경
- 캐싱 필터, 자원 접근에 대한 로깅, 요청이 올바른지 확인
필터 설정 (WEB-INF/web.xml)
<web-app …>
<filter>
<filter-name> FilterName </filter-name>
<filter-class> … </filter-class>
<init-param>
필터 사용 전, 객체 초기화, 자원할당에 대한 정보
<param-name> … </param-name>
<param-value> … </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> FilterName </filter-name>
<url-pattern> *.jsp </url-pattern> /만 포함하는 경우, 어플리케이션의 기본 서블릿으로 매핑
<servlet-name> FileDownload </servlet-name>
<dispatcher> INCLUDE </dispatcher>
</filter-mapping>
</web-app>
※ dispatcher : 필터 적용 시점 (서블릿 2.4 이상)
- REQUEST: 클라이언트가 지원 요청시
- FORWARD : RequestDispatcher의 forward()를 통해서 제어가 이동된 경우
- INCLUDE : include()를 통해 포함하는 경우
※ <filter-mapping>에 <url-pattern>과 <servlet-name>을 여러 개 중복설정 가능 (서블릿 2.5 이상)
※ <filter-mapping>을 여러 개 정의한 경우, 순서대로 실행
Filter (2)
Filter 구현
 필터가 요청을 변경한 결과를 저장
Javax.servlet.ServletRequestWrapper 상속
Javax.servlet.http.HttpServletRequestWrapper 상속
 필터가 응답을 변경할 결과를 저장
Javax.servlet.ServletResponseWrapper 상속
Javax.servlet.http.HttpServletResponseWrapper 상속
 javax.servlet.Filter 인터페이스 구현
- init(FilterConfig)
FilterConfig
getFilterName(), getInitParameter(), getInitParameterNames(), getServletContext()
- doFilter(request, response, chain)
① ServletRequestWrapper 상속 클래스를 생성하여, 요청을 변환
② 필터 체인을 통해 결과를 전달받을 ServletResponseWrapper 상속 클래스 생성
③ 체인의 다음 필터 처리
chain.doFilter(requestWrapper, responseWrapper)
④ ServletResponseWrapper 의 결과를 변환하여 응답을 전송
- destroy()
Listener
 Listener : 웹 어플리케이션 시작/종료 시점에 특정 기능을 실행
 javax.servlet.ServletContextListener 인터페이스
contextInitialized(ServletContextEvent)
웹 어플리케이션 초기화시 호출됨
contextDestroyed(ServletContextEvent)
웹 어플리케이션 종료시 호출됨
ServletContextEvent
getServletContext()
ServletContext
Application 기본 객체와 동일
getInitParameter(), getInitParameterNames()
※ 리스너의 메소드는 명시적(thorws)으로 예외를 발생시키지 않으므로 RuntimeException을 사용
 web.xml
<web-app …>
<listener>
1개 이상의 리스너를 등록한 경우, 순서대로 initialize, 역순으로 destroy
<listener-class> … </listener-class>
</listener>
<context-param>
ServletContext.getInitParameter() 사용
<param-name> … </param-name>
<param-value> … </param-value>
</context-param>
</web-app>
MVC 패턴
 컨트롤러 : 사용자의 입력 및 흐름제어를 담당. 서블릿을 통해 구현
①
②
③
④
⑤
HTTP 요청 수신
request 객체에서 클라이언트의 요청 분석
모델을 사용하여 요청한 비지니스 로직 수행
결과를 request/session에 저장
RequestDispatcher를 사용하여 알맞은 뷰로 포워딩/리다이렉트
 뷰 : 요청 결과를 보여주는 프리젠테이션 역할. JSP를 통해 구현
 모델 : 서비스클래스나 DAO클래스를 이용해 비즈니스 로직을 수행
① 컨트롤러로부터 요청 수신
② 비지니스 로직 수행
③ 수행결과를 컨트롤러에 리턴 (결과값은 주로 자바빈에 저장)
 커맨드 패턴 기반 MVC 구현 기법
- 명령어를 사용하여 사용자 요구 판단
- 각 명령어에 해당하는 로직처리 코드를 컨트롤러에서 별도의 클래스로 분리
- 로직 수행 후, 뷰 페이지 정보를 리턴
① 특정 파라미터에 명령어 정보 전달
② 요청 URI 자체를 명령어로 사용 – 컨트롤러의 URL을 사용자에게 감출 수 있다
 web.xml
<web-app …>
<servlet>
<servlet-name> ControllerUsingURI </servlet-name>
<servlet-class> … </servlet-class>
<init-param>
<param-name> … </param-name>
<param-value> … </param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name> ControllerUsingURI </servlet-name>
<url-pattern> *.do </url-pattern>
</servlet-mapping>
</web-app>
모델1 구조
모델2 구조
- 하나의 기능과 JSP가 직관적으로 연결
- 로직과 뷰의 혼합으로 JSP 코드 복잡
- 뷰 변경시 유지보수 불편
- 로직과 뷰의 분리로 유지보수 용이
- 컨트롤러 서블릿에서 공통 작업 처리 가능
- 작업량이 많음 (커맨드 클래스, 뷰 JSP)
HTTP 프로토콜 구성
① 요청/응답
상태
② 헤더영역
요청라인
- 브라우저-> 웹서버로 전송
- 요청메소드(GET/POST), 요청자원의 URL, HTTP 프로토콜 버전
응답상태라인
웹서버->브라우저로 결과전송
- 실제 전송데이터 이외의 정보
- “이름:값”의 형식
- Host, User-Agent, Cookie 등
③ 데이터영역
 GET방식을 이용한 파라미터 전송시 요청데이터 예
GET /idp/idf/view.jsp?name=admin&address=seoul HTTP/1.1
HOST: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ko; rv:1.9.0.3) …
Accept: text/html, application/xhtml+xml, application/xml; q=0.9,*/*;q=0.8
Accept-Language: ko-kr,ko;q=0.8,en-us;q=0.5, en;q=0.3
Acccept-Encoding: gzip,deflate
Accept-Charset: EUC-KR,utf-8;q=0.7,*;q=0.7
Proxy-Connection: keep-alive
Cookie: JSESSIONID=AB133D343FD12…
 POST방식을 이용한 파라미터 전송시 요청데이터 예
POST /idp/idf/view.jsp HTTP/1.1
HOST: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ko; rv:1.9.0.3) …
Accept: text/html, application/xhtml+xml, application/xml; q=0.9,*/*;q=0.8
…
Referer: /idp/idf/form.jsp
Cookie: JSESSIONID=AB133D343FD12…
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
name=admin&address=seoul
 multipart/form-data 방식으로 전송된 데이터
[multipart/form-data; boundary=------------------------------------7d9202102082c]
------------------------------------7d9202102082c
Content-Disposition: form-data; name=“id”
admin
------------------------------------7d9202102082c
Content-Disposition: form-data; name=“file1”; filename=“test.txt”
Content-Type: application/octet-stream
테스트 파일 내용
------------------------------------7d9202102082c
web.xml 주요 태그
web-app
설명관련태그
listener
context-param
filter
filter-mapping
servlet
servlet-mapping
session-config
welcome-file-list
error-page
jsp-config
description
display-name
icon
small-icon
large-icon
설명관련태그
listener-class
description
param-name
param-value
설명관련태그
filter-name
filter-class
init-param
description
param-name
param-value
filter-name
url-pattern
servlet-name
dispatcher-name
설명관련태그
servlet-name
servlet-class
jsp-file
init-param
load-on-startup
-…
servlet-name
url-pattern
session-timeout
welcome-file
error-code
exception-type
location
taglib
jsp-property-group
taglib-uri
taglib-location
설명관련태그
url-pattern
el-ignored
page-encoding
include-prelude
include-coda
deferred-syntax-allowed-as-literal
trim-directive-whitespaces
톰캣 server.xml 기초 설정
<Server
port=“8005”
shutdown=“SHUTDOWN”>
<Listener className=“…” SSLEngine=“on” />
<GlobalNamingResources>
<Resource name=“UserDatabase” auth=“” … />
</GlobalNamingResources>
<Service name=“Catalina”>
<Executor name=“tomcatThreadPool” … />
<Connector port=“8080”
protocol=“HTTP/1.1”
connectionTimeout=“20000”
redirectPort=“8443”
executor=“tomcatThreadPool” />
<Connector port=“8009”
protocol=“AJP/1.3”
redirectPort=“8443”
URIEncoding=“…”
useBodyEncodingForURI=“…” />
maxThreads=“300” />
<Engine name=“Catalina”
defaultHost=“localhost”>
<Realm className=“…”
resourceName=“UserDatabase” />
<Host
name=“localhost”
appBase=“webapps”
unpackWARs=“true”
autoDeploy=“true”
xmlValidation=“false”
xmlNamespaceAware=“false”
workDir=“…”>
</Host>
<Host name=“www.idp.com”
appBase=“/home/ktidp”>
<Context docBase=“/home/ktidp/admin”
</Host>
</Engine>
</Service>
</Server>
path=“/admin” />
서블릿 컨테이너 설정을 위한 루트 태그
종료명령어 수신 포트번호 (shutdown.bat 등에 사용)
1개 엔진과 n개 connector를 공유하는 서비스를 정의
클라이언트 요청처리시 사용되는 쓰레드풀 설정
지정한 프로토콜에 따라 클라이언트의 요청을 전달받는
커넥터
HTTP 기반의 요청을 처리할 때 사용하는 커넥터
다수의 커넥터가 동일한 쓰레드풀을 사용하도록 설정
클라이언트의 요청을 받을 포트
AJP 프로토콜 기반으로 아파치 웹서버와 연동하는 커넥
터
동시 요청처리 최대 개수 (Default:200)
커넥터로 전달받은 요청을 처리하는 엔진 설정
요청한 호스트에 일치하는 <Host> 설정이 없는 경우
가상 호스트를 설정
한 개의 호스트와 관련된 전반적인 콘텍스트 데이터 설
정
가상호스트의 이름 (IP나 도메인명)
localhost로 들어오는 요청 처리
이 호스트를 위한 어플리케이션 기본 디렉토리
default: true
default: [톰캣]/work
www.idp.com 으로 들어오는 요청 처리
컨텍스트 설정 방법
1. <Host>에 <Context> 태그 추가
2. [톰캣]/conf/[엔진이름]/[호스트이름]/[컨텍스트경로
명].xml 파일 추가
※ 디렉토리명이 ROOT이면 컨텍스트 경로는 “”가 됨