티스토리 뷰
CHAPTER 03
기본 코드 구조
- 설정 부분: JSP 페이지에 대한 설정 정보
l JSP 페이지가 생성하는 문서의 타입(종류)
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page … %> : page directive
l JSP 페이지에서 사용할 커스텀 태그
l JSP 페이지에서 사용할 자바 클래스 지정
- 생성 부분: HTML 코드 및 JSP 스크립트
JSP 페이지의 구성요소
JSP 페이지에 대한 정보를 지정
웹 브라우저가 전송한 데이터를 읽어오는 기능
JSP 페이지에서 사용할 데이터를 생성하는 실행 코드
웹 브라우저에 문서 데이터를 전송해주는 기능
JSP가 제공하는 것
- 디렉티브(Directive): JSP 페이지에 대한 설정 정보를 지정
<%@ 디렉티브이름 속성1=”값1” 속성2=”값2” … %>
<%@ page contentType="text/html; charset=UTF-8" %>
page: JSP 페이지에 대한 정보 지정. 문서의 타입, 출력 버퍼의 크기, 에러 페이지 등
taglib: JSP 페이지에서 사용할 태그 라이브러리를 지정한다.
include: JSP 페이지의 특정 영역에 다른 문서를 포함시킨다.
- 스크립트 요소: JSP 문서의 내용을 동적으로 생성하기 위해 사용,
스크립트릿(Scriptlet): 자바 코드를 실행
표현식(Expression): 값을 출력
선언부(Declaration): 자바 메서드(함수)를 만든다.
- 표현 언어(Expression Language): 스크립트 코드보다 코드를 간결하게 한다
${ expression;값을 생성하는 코드 }
- 기본 객체(Implicit Object): 웹 앱 프로그래밍을 하는 데 필요한 기능을 제공
Ex) request, response, session, application, page 등
(요청 파라미터 읽어오기, 응답 결과 전송하기, 세션 처리하기, 웹 앱 정보 읽어오기 등)
- 정적인 데이터
- 표준 액션 태그(Action Tag):
<jsp: 액션태그이름>
Ex) <jsp:include> : 특정 페이지의 실행 결과를 현재 위치에 포함시킬 때
- 커스텀 태그(Custom Tag)와 표준 태그 라이브러리(JSTL)
커스텀 태그: 개발자가 직접 개발하며 JSP를 확장시켜주는 기능, 코드의 중복이나 스크립트 코드의 복잡함을 없애기 위해 모듈화하거나 함
JSTL(JavaServer Pages Standard Tag Library): 커트텀 태그 중 별도로 표준화한 태그 라이브러리
request 기본객체
웹 브라우저의 파라미터 전송 방식 ( GET 메서드와 POST 메서드)
GET: 요청 URL에 파라미터(쿼리 문자열 query string)를 붙여서 전송한다. (default)
이름1=값1&이름2=값2&…&이름n=값n ( & ampersand )
URL의 쿼리 문자열로 전송되기 때문에, 폼을 사용하지 않아도 파라미터 전송 가능
웹 브라우저, 웹 서버, 웹 컨테이너에 따라 전송할 수 있는 파라미터 값의 길이에 제한 있을 수 있다.
POST: 데이터 영역을 이용해서 파라미터를 전송한다.
전송할 수 있는 파라미터의 길이에 제한이 없다.
response 기본객체 – 응답 정보에 헤더 정보를 추가, 리다이렉트 하기
웹 브라우저에 헤더 정보 전송하기
addDateHeader(String name, long date): name 헤더에 date를 추가한다.
addHeader(String name, String value): name 헤더에 value를 값으로 추가한다.
addIntHeader(String name, int value): name 헤더에 정수 값 value를 추가한다.
setDateHeader(String name, long date): name 헤더의 밧을 date로 지정한다.
setHeader(String name, String value): name 헤더의 값을 value로 지정한다.
setIntHeader(String name, int value): name 헤더의 값을 정수 값 value로 지정한다.
containsHeader(String name): 이름이 name인 헤더를 포함하고 있는지 여부를 나타낸다.
웹 브라우저 캐시 제어를 위한 응답 헤더 입력
웹 브라우저가 서버가 생성한 결과를 출력하지 않고 캐시에 저장된 데이터를 출력하는 경우는?
캐시는 동일한 데이터를 중복해서 로딩하지 않도록 할 때 사용한다. 웹 브라우저는 첫 번째 요청 시 응답 결과를 로컬 PC의 임시 보관소인 캐시에 저장하고, 이후 동일한 URL에 대한 요청이 있으면 WAS에 접근하지 않고 로컬에 저장된 응답 결과를 사용한다. (변경이 발생하지 않는 JSP의 응답 결과, 이미지, 정적 HTML 등에 유용)
HTTP는 특수한 응답 헤더를 통해서 웹 브라우저가 응답 결과를 캐시 할 것인지에 대한 여부를 설정
Cache-Control: (HTTP 1.1버전) “no-cache”, “no store”
Pragma: (HTTP 1.0버전) “no-cache”
Expires: (HTTP 1.0버전) 응답 결과 만료일 지정, 현재 시간 이전으로 설정함으로써 캐시에 보관하는 것을 막는다.
리다이렉트를 이용해서 페이지 이동 : 웹 서버가 웹 브라우저에게 다른 페이지로 이동하라고 응답하는 기능
response.sendRedirect(String location)
URLEncoder.encode(String value ,”charset”)
JSP 주석
스크립트릿과 선언부의 코드 블록은 //
JSP 코드 자체는 <%-- --%>
JSP의 요청 처리 과정
l JSP에 해당하는 서블릿이 존재하지 않을 경우 (과정1.1)
- JSP 페이지로부터 자바 코드를 생성한다. (과정1.2)
- 자바 코드를 컴파일해서 서블릿 클래스를 생성한다. (과정1.3)
- 서블릿에 클라이언트 요청을 전달한다. (과정2.1)
- 서블릿이 요청을 처리한 결과를 응답으로 생성한다. (과정2.2)
- 응답을 웹 브라우저에 전송한다. (과정3)
l JSP에 해당하는 서블릿이 존재하는 경우 (즉, 과정1.1~1.3을 거친 경우)
- 서블릿에 클라이언트 요청을 전달한다. (과정2.1)
- 서블릿이 요청을 처리한 결과를 응답으로 생성한다. (과정2.2)
- 응답을 웹 브라우저에 전송한다. (과정3)
JSP를 실행한다 -> JSP 페이지로부터 자바 소스 파일로 변환한 것을 컴파일 한 서블릿 클래스를 실행한다;
출력 버퍼와 응답
JSP 페이지는 출력 버퍼에 임시로 응답 결과를 저장했다가 한 번에 웹 브라우저에 전송한다.
- 데이터 전송 성능 향상 (작은 단위로 여러 번 보다 큰 단위로 한 번에 데이터를 전송)
- JSP 실행 도중에 버퍼를 비우고 새로운 내용 전송 가능
<jsp:forward>기능과 에러 페이지 처리 기능
- 버퍼가 다 차기 전까지 헤더 변경 가능
HTTP 구조상 응답 상태 코드와 함게 헤더 정보를 가장 먼저 웹 브라우저에 전송한다. WAS는 처음 버퍼의 내용을 웹 브라우저로 전송하기 전에 헤더 정보를 전송하기 때문에, 버퍼의 내용을 웹 브라우저에 전송하기 전가지는 헤더 정보를 얼마든지 변경할 수 있다.
page 디렉티브에서 버퍼 설정하기: buffer 속성과 autoFlush 속성
JSP 페이지가 사용할 버퍼의 크기를 지정 <%@ page buffer = “4kb” %> 일반적으로 하지 않는다. JSP 규약은 이를 지정하지 않을 시 최소 8KB 이상의 크기를 갖는 버퍼를 사용하도록 규정하고 있다. 사용하고 싶지 않다면 <%@ page buffer = “none” %> 이때는 JSP 페이지 출력 내용을 곧바로 웹 브라우저에 전송한다.
플러시(flush): 버퍼가 다 찼을 때, 전송하거나 저장하여 버퍼를 비우는 것
autoFlush 속성 (버퍼가 다 찼을 때) true: 버퍼를 플러시하고 계속해서 작업을 진행한다.
false: 예외(exception)를 발생시키고 작업을 중지한다.
웹 어플리케이션 폴더 구성과 URL 매핑
webapps\chap04\WEB-INF : 웹 어플리케이션 설정 정보를 담고 있는 web.xml 파일이 위치한다.
webapps\chap04\WEB-INF\classes : 웹 어플리케이션에서 사용하는 클래스 파일이 위치한다.
webapps\chap04\WEB-INF\lib : 웹 어플리케이션에서 사용하는 jar 파일이 위치한다.
서블릿 2.5 / JSP 2.1 이후 버전, web.xml 파일을 작성해야 하는 경우
- 서블릿을 직접 설정하는 경우
- 리스너를 직접 설정하는 경우
- 특정 URL에 속하는 JSP들에 대해 공통 속성값을 설정하는 경우
request.getContextPath(): 컨텍스트 경로를 제공하는 메서드 ex) chap04, ROOT 등
웹 애플리케이션 폴더 내에 하위 폴더 사용: JSP 페이지를 기능별로 분류 (개발 과정, 유지보수에 유리)
웹 어플리케이션을 WAS에 배포하는 방법
- 대상 폴더에 파일을 직접 복사 (서버의 특정 폴더에 파일을 직접 저장, 복사, FTP 파일 전송 기능 이용)
- war 파일(Web Application Archive: 웹 앱 구성 요소를 하나로 묶어 놓은 파일)로 묶어서 배포
war 파일로 묶으려면 JDK의 jar 명령어를 사용하면 된다. jar 명령어는 javac 명령어와 동일하게 [JDK설치폴더]\bin 폴더에 포함되어 있다. PATH 환경 변수에 [JDK설치폴더]\bin 폴더를 추가해주면 전체 경로를 입력할 필요 없이 jar 명령어를 실행할 수 있다.
cvf 옵션을 사용해서 jar 명령어를 실행하면 war 파일을 생성할 수 있다.
C:\apache-tomcat-9.0.17\webapps\chap04>jar cvf chap04.war *
( c: 새로운 파일을 생성, v: 세부 정보를 콘솔(명령 프롬프트)에 표시, f: 생성할 파일의 이름을 지정,
*: 현재 폴더의 모든 파일과 하위 폴더 대상)
-> chap04.war 파일을 [톰캣]\webapps 폴더에 복사해주면 배포가 된다. (톰캣 실행 시, chap04 폴더가 생성되고, 이 폴더는 \chap04 컨텍스트 경로를 갖는다.)
JSP의 9가지 기본 객체
request - 클라이언트의 요청 정보를 저장한다. javax.servlet.http.HttpServletRequest
response - 응답정보를 저장한다. javax.servlet.http.HttpServletResponse
session - HTTP 세션 정보를 저장한다. (10장, 세션) javax.servlet.http.HttpSession
out - JSP 페이지가 생성하는 결과를 출력할 때 사용하는 출력 스트림. javax.servlet.ServletContext
pageContext - JSP 페이지에 대한 정보를 저장한다. javax.servlet.jsp.PageContext
application - 웹 앱에 대한 정보를 저장한다. javax.servlet.ServletContext
exception - 에러 페이지에서만 사용한다. (6장, 에러처리) javax.lang.Throwable
page - JSP 페이지를 구현한 자바 클래스 인스턴스이다. javax.lang.Object
config - JSP 페이지에 대한 설정 정보를 저장한다. javax.servlet.ServletConfig
out 기본 객체 :
JSP 페이지가 생성하는 모든 내용은 out 기본 객체를 통해 전송된다. (브라우저에 테이터를 전송하는 출력 스트림)
복잡한 조건 비교 때문에 출력 코드가 복잡해지는 경우가 아니면 out 기본 객체를 사용하지 않는 것이 좋다.
출력 가능한 자료형 : boolean, char, char[], double, float, int, long, 그리고 Sring
JSP 페이지가 사용하는 버퍼는 out 기본 객체가 내부적으로 사용하는 버퍼이다. <%@ page buffer=”16kb” %>
(예제: chap05/useOutObject.jsp, bufferInfo.jsp)
pageContext 기본 객체 : JSP 페이지와 일대일로 연결된 객체
기본 객체 구하기, 속성 처리하기, 에러 데이터 구하기(6장), 페이지의 흐림 제어하기(7장)
직접 사용하는 경우는 드물고, 커스텀 태그를 구현할 때 사용한다.
(예제: chap05/usePageContext.jsp, )
application 기본 객체 : 웹 어플리케이션과 관련된 기본 객체
특정 웹 앱에 포함된 모든 JSP 페이지는 하나의 application 기본 객체를 공유하게 된다.
초기 설정 정보를 읽어오거나, 서버 정보, 웹 앱이 제공하는 자원(파일)을 읽어올 수 있다.
웹 앱 초기화 파라미터 읽어오기
초기화 파라미터 WEB-INF/web.xml 파일에 <context-param> 태그를 사용하여 추가
web.xml 파일 : 웹 앱을 위한 설정 정보를 담고 있는 파일. 꼭 필요하지 않기 때문에 필요할 때만 작성
(톰캣은 web.xml 파일을 변경하면 웹 앱을 자동으로 다시 시작하는 웹 컨테이너이다. 아닌 경우 수동 재시작.)
웹 앱 초기화 피라미터는 언제 사용할까? : 이름처럼 웹 앱을 초기화하는 데 필요한 설정 정보를 지정하기 위해 사용 된다. 예로, DB 연결과 관련된 설정 파일의 경로나, 로깅 설정 파일, 웹 앱 주요 속성 정보를 담고 있는 파일의 경로 등을 지정할 때 사용한다.
(C:\apache-tomcat-9.0.17\webapps\chap05\WEB-INF\web.xml, chap05/readInitParameter.jsp)
서버 정보 읽어오기 : 현재 사용중인 웹 컨테이너에 대한 정보를 읽어오는 메서드 제공
(http://localhost:8080/chap05/viewServerInfo.jsp)
로그 메시지 기록하기 : 웹 컨테이너가 사용하는 로그 파일에 고르 메시지를 기록하는 메서드 제공
(chap05/useApplicationLog.jsp, chap05/useJSPLog.jsp)
웹 앱의 자원 구하기 : 웹 앱 폴더에 위치한 파일 사용, 폴더 내 경로 이용하는 방법 알기
웹 어플리케이션의 네 가지 영역(scope) 구성
PAGE 영역: 하나의 JSP 페이지를 처리할 때 사용되는 영역 – pageContext 기본 객체
REQUEST 영역: 하나의 HTTP 요청을 처리할 때 사용되는 영역 (하나의 요청을 처리하는 데 사용되는 모든 JSP 페이지를 포함) – request 기본 객체
SESSION 영역: 하나의 웹 브라우저와 관련된 영역(세션이 생성되고 하나의 웹 브라우저와 관련된 모든 요청 포함) – session 기본 객체
APPLICATION 영역: 하나의 웹 어플리케이션과 관련된 전체 영역 (위의 것을 모두 포함) – application 기본 객체
웹 브라우저에서 한 번의 요청은 하나의 request 기본 객체와 관련된다. 웹 즈라우저가 결과를 받으면 그 요청과 관련된 request 기본 객체는 사라진다. 즉, 웹 브라우저가 요청할 때마다 새로운 request 기본 개체가 생성된다. 즉, 매번 새로운 REQUEST 영역이 생성된다.
하나의 요청을 처리하는 데 두 개 이상의 JSP가 사용될 수도 있다. 예를 들어, 웹 브라우저가 호출한 JSP 페이지가 다른 JSP를 include 하거나 forward 할 수 있는데, 이 경우 두 JSP 페이지는 같은 요청 범위에 속하게 된다. 즉. 같은 request 기본 객체를 공유하게 된다. (7장) 하나의 웹 브라우저는 하나의 세션과 관련된다. 서로 다른 두 개의 웹 브라우저가 같은 JSP 페이지를 사용한다 하더라도 두 웹 브라우저는 서로 다른 SESSION 영역에 포함되며, 서로 다른 session 기본 객체를 사용하게 된다.
모든 JSP는 한 개의 application 기본 객체를 공유하며, application 기본 객체는 APPLICATION 영역에 포함된다.
JSP 기본 객체의 속성(Attribute) 사용하기 : JSP 페이지 사이에서 정보를 주고받거나 공유하기 위한 목적으로 각 기본 객체가 존재하는 동안 기본 객체의 속성을 사용한다. <속성이름, 값>의 형태.
(chap05/setApplicationAttribute.jsp)
속성의 값 타입: 속성의 이름은 String 타입이지만, 값은 모든 클래스 타입이 올 수 있다. 오토 박싱/언박싱 가능
속성의 활용 용도
pageContext: (한 번의 요청을 처리하는) 하나의 JSP 페이지 내에서 공유할 RKQT을 저장한다. 주로 커스텀 태그에서 새로운 변수를 추가할 때 사용한다. (PAGE 영역)
request: 한 번의 요청을 처리하는 데 사용되는 모든 JSP 페이지에서 공유할 값을 저장한다. 주로 하나의 요청을 처리하는 데 사용하는 JSP 페이지 사이에서 정보를 전달하기 위해 사용된다. (REQUEST 영역)
session: 한 사용자와 관련된 정보를 JSP 사이에 공유하기 위해 사용한다. 사용자의 로그인 정보와 같은 것들을 저장한다. (SESSION 영역)
application: 모든 사용자를 위해 공유할 정보를 저장한다. 임시 폴더 경로와 같이 웹 앱의 설정 정보를 주로 저장한다. (APPLICATION 영역)
에러 처리, 예외
주요 응답 상태 코드: HTTP 프로토콜은 응답 상태 코드를 이용해서 서버의 처리 결과를 웹 브라우저에 알려준다.
200: 요청을 정상적으로 처리함
307: 임시로 페이지를 리다이렉트함 (response.sendRedirect()를 이용할 경우)
400: 클라이언트의 요청이 잘못된 구문으로 구성됨
401: 접근을 허용하지 않음
404: 요청한 URL을 처리하기 위한 자원이 존재하지 않음
405: 요청한 메서드(GET, POST, HEAD 등의 전송 방식)를 허용하지 않음
500: 서버 내부 에러가 발생함(예를 들어, JSP에서 예외가 발생함)
503: 서버가 일시적으로 서비스를 제공할 수 없음(급격하게 부하가 몰리거나 서버가 임시 보수 중인 경우가 해당)
에러 페이지의 우선순위와 지정 형태
1. page 디렉티브의 errorPage 속성에 지정한 에러 페이지를 보여준다.
2. JSP 페이지에서 발생한 익셉션 타입이 web.xml 파일의 <exception-type>에 지정한 익셉션 타입과 동일한 경우 지정한 에러 페이지를 보여준다.
3. 에러 코드가 web.xml 파일의 <error-code>에 지정한 에러 코드와 동일한 경우 지정한 에러 페이지를 보여준다.
4. 아무것도 해당하지 않는 경우 웹 컨테이너가 제공하는 기본 에러 페이지를 보여준다.
우선순위를 고려해 다음과 같이 에러 페이지를 지정한다 : 전용 에러 페이지가 필요한 경우 page 디렉티브의 errorPage 속성을 사용한다. 범용적인 에러 코드에 대해 web.xml에 <error-code> 태그를 추가해 에러 페이지를 지정하고, 별도로 처리해야 하는 예외에 대해서는 <exception-type> 태그를 추가해서 에러 페이지를 지정한다.
CHAPTER 07 페이지 모듈화와 요청 흐름 제어
<jsp:include> 액션 태그를 이용한 공통 영역 작성 (동일한 상단, 좌측 메뉴, footer 등) – 코드 중복 및 수정
<jsp:include page=”포함할 페이지” flush=”true /> 화면의 구성 요소에 대한 모듈로 사용할 수 있다.
<jsp:param>으로 포함할 페이지에 파라미터 추가하기 (<jsp:include>의 자식 태그로 추가)
<% String type = “typeA”; %>
<jsp:include page=”/module/top.jsp” flush=”false”’>
<jsp:param name=”name” value=”최범균” /> <%-- value에 값을 직접 입력 -->
<jsp:param name=”type” value=”<% type %>” /> <%-- 표현식으로 값 입력 -->
</jsp:include>
<jsp:param> 액션 태그로 추가한 파라미터는 <jsp:include> 액션 태그로 포함하는 페이지에서만 유효하다. 기존 파라미터 값을 유지한 채 새 파라미터 값을 추가하며, 이때 새롭게 추가된 값이 우선한다.
(http://localhost:8080/chap07/body_main.jsp?name=cbk 과 body_sub.jsp 참조)
<%
request.setCharacterEncoding("utf-8"); // <jsp:param>으로 전달되는 값은 request.setCharacterEncoding()에 명시한 캐릭터셋으로 인코딩해서 전달한다. 알맞은 캐릭터셋을 지정하지 않으면 설정한 값이 올바르게 전달되지 않는다.
%>
include 디렉티브를 이용한 중복된 코드 삽입 <%@ include file=”포함할 파일의 경로” %>
<jsp:include>는 다른 JSP로 실행 흐름을 이동시켜 실행 결과를 현재 위치에 포함하는 방식이고, include 디렉티브는 다른 파일의 내용을 현재 위치에 삽입한 후에 JSP 파일을 자바 파일로 변환하고, 서블릿 클래스로 컴파일하는 방식
활용: 모든 JSP 페이지에서 사용하는 변수 지정, 저작권 표시와 같이 모든 페이지에서 중복되는 간단한 문장
.jspf 코드 조각 자동 포함 기능
<jsp-property-group> : JSP의 프로퍼티를 포함한다.
<url-pattern> : 프로퍼티를 적용할 JSP 파일의 URL 패턴을 지정한다.
<include-prelude> : url-pattern 태그에 지정한 패턴에 해당하는 JSP 파일의 앞에 삽입할 파일을 지정한다.
<include-coda> : url-pattern 태그에 지정한 패턴에 해당하는 JSP 파일의 뒤에 삽입할 파일을 지정한다.
두 개 이상 <jsp-property-group> 태그 설정한 경우, 차례대로 적용
1. <url-pattern>/view/*</url-pattern>
2. <url-pattern>*.jsp</url-pattern>
비교 항목 |
<jsp:include> |
Include 디렉티브 |
처리 시간 |
요청 시간에 처리 |
JSP 파일을 자바 소스로 변환할 때 처리 |
기능 |
별도의 파일로 요청 처리 흐름을 이동 |
현재 파일에 삽입시킴 |
데이터 전달 방법 |
Request 기본 객체나 <jsp:param>을 이용한 파라미터 전달 |
페이지 내의 변수를 선언한 후, 변수에 값 저장 |
용도 |
화면의 레이아웃의 일부분을 모듈화할 때 주로 사용 |
다수의 JSP 페이지에서 공통으로 사용되는 변수를 지정하는 코드나 저작권 같은 문장을 포함 |
<jsp:forward page=”이동할 페이지” /> 액션 태그를 이용한 다른 JSP 페이지로 요청 처리를 전달
- from.jsp가 아닌 to.jsp가 생성한 응답 결과를 웹 브라우저에 전달한다. (간결하고 구조적인 프로그래밍)
- from.jsp에서 사용한 request, response 기본 객체를 to.jsp에 그대로 전달한다.
- 웹 브라우저의 주소는 from.jsp 그대로이다. 즉, 리다이렉트처럼 to.jsp로 변경되지 않는다.
<jsp:forward>액션 태그의 활용 : 조건에 따라 다른 페이지로 이동하여 그 결과를 보여줄 때. <jsp:param> 가능
page 속성 경로의 절대 경로와 상대 경로
request 기본 객체의 속성을 이용한 값 전달 방식(타입 변환 과정 불필요하기 때문에 <jsp:forward>보다 편리)은 웹 앱 개발에서 중요한 기법 중 하나이다. 특히 이 방식은 MVC 패턴이라는 것에 기반하여 웹 앱을 구현할 때 필수 요소이기 때문에 request 기본 객체의 속성을 사용하는 방법에 대해서 반드시 이해해야 한다.
CHAPTER 08 자바빈과 <jsp:useBean> 액션 태그
자바빈: 속성(데이터), 변경 이벤트, 객체 직렬화를 위한 표준, 자바빈 규약을 따르는 클래스(데이터를 저장하는 필드, 데이터를 읽어올 때 사용되는 메서드, 저장할 때 사용되는 메서드로 구성)
프로퍼티(property): 자바빈에 저장되는 값 ( set or get + 프로퍼티이름 = 메서드 이름)
ex) public void setMaxAge(int value){} public int getMaxAge(){}
private int maximumAge = 0; (프로퍼티 값을 저장하는 필드 이름과 프로퍼티 이름은 같지 않아도 된다.)
public boolean isFinished(){} 타입이 boolean인 경우 getFinished() 대신 isFinished() 가능
읽기 전용 프로퍼티: get 또는 is 메서드만 존재하는 프로퍼티
읽기/쓰기 전용 프로퍼티: get/set 또는 is/set 메서드가 존재하는 프로퍼티
public int[] getMark() {}
public void setMark(int[] values) {}
public int getMark(int index) {}
public void setMark(int value, int index) {}
<jsp:useBean> 액션 태그: JSP 페이지에서 사용할 자바빈 객체를 지정하고 영역별로 공유할 데이터를 쉽게 저장
<jsp:useBean id=”[자바빈 이름]” class=”[자바빈 클래스 이름]” scope=”[범위]” />
id: JSP 페이지에서 자바빈 객체에 접근할 때 사용할 이름을 지정한다.
class: 패키지 이름을 포함한 자바빈 클래스의 완전한 이름을 입력한다.
scope: 자바빈 객체를 저장할 영역을 지정한다. page, request, session, application 중 하나(기본값은 page)
예) <jsp:useBean id=”info” class=”chap08.member.MemberInfo” scope=”request” />
MemberInfo 클래스의 객체를 생성해서 이름이 info인 변수에 할당한다. 그리고 request 기본 객체의 “info” 속성의 값으로 생성된 객체를 저장한다.
MemberInfo info = new MemberInfo();
request.setAttribute(“info”, info);
지정한 영역에 이미 id 속성에서 지정한 이름의 속성값이 존재하면, 기존 객체를 그대로 사용한다. 아래와 같다.
MemberInfo info = (MemberInfo)request.getAttribute(“info”);
if(info == null) {
info = new MemberInfo();
request.setAttribute(“info”, info);
}
<jsp:useBean> 액션 태그는 객체를 생성할 뿐만 아니라 지정한 영역에 저장하고, 이미 영역에 객체가 존재하면 기존의 객체를 사용한다.
예) <jsp:useBean id=”member” type=”chap08.member.MemberInfo” scope=”request” />
type 속성을 사용하면 지정한 영역에 이미 객체가 존재한다고 가정한다. member 속성에 MemberInfo 객체가 존재하지 않으면 새로 객체를 생성하지 않고 에러를 발생시킨다.
MemberInfo member = (MemberInfo)request.getAttribute(“member”);
if(member == null) { // 에러를 발생시킨다. }
<jsp:setProperty> 액션 태그
<jsp:setProperty name=”[자바빈]” property=”이름” value=”[값]” />
name: 프로퍼티의 값을 변경할 자바빈 객체의 이름을 지정한다. <jsp:useBean> 액션 태그의 id 속성에서 지정한 값을 사용한다.
property: 값을 지정할 프로퍼티의 이름을 지정한다.
value: 프로퍼티의 값을 지정한다. 표현식(<%= 값 %>)이나 EL(${값})을 사용할 수 있다.
예) <jsp:useBean id=”member” class=”chap08.member.MemberInfo” />
<jsp:setProperty name=”member” property=”name” value=”최범균” />
<jsp:getProperty> 액션 태그
알아두자 <jsp:useBean> 액션 태그의 사용 감소 이유.
CHAPTER 09 클라이언트와의 대화1 : 쿠키
쿠키를 사용하여 웹 서버와 웹 브라우저는 필요한 값을 공유하고 상태를 유지
쿠키의 구성 요소: 이름, 값, 유효시간, 도메인(쿠키를 전송할 도메인), 경로(쿠키를 전송할 요청 경로path)
RFC2965 규약
<%
Cookie cookie = new Cookie(“cookieName”, “cookieValue”);
response.addCookie(cookie);
%>
아이디 및 로그인 정보를 쿠키에 보관하면 아이디 기억하기 기능과 자동 로그인 기능 구현 가능
한 개의 Set-Cookie 헤더는 한 개의 쿠키 값을 전달한다. 쿠키는 응답 헤더를 사용해서 웹 브라우저에 전달되기 때문에 출력 버퍼가 플러시 된 이후에는 새롭게 추가할 수 없다.
쿠키 이름=쿠키 값; Domain=도메인 값; Path=경로 값; Expires=GMT형식의 만료 일시
쿠키 처리를 위한 유틸리티 클래스
쿠키를 이용해 로그인 상태를 유지하는 방법
1. 로그인에 성공하면 특정 이름을 갖는 쿠키를 생성한다. 예) “AUTH”
2. 해당 쿠키가 존재하면 로그인한 상태라고 판단한다.
3. 로그아웃하면 해당 쿠키를 삭제한다.
클라이언트와의 대화 2 : 세션
쿠키와의 차이점은 웹 브라우저가 아니라 서버에 값을 저장한다는 점이며 세션은 웹 브라우저와 연관된 서버 영역 저장 공간이다. 로그인한 사용자 정보를 유지하기 위한 목적으로 세션의 사용법과 세션을 이용한 인증 정보 유지 방법을 안다.
session 기본 객체
웹 컨테이너는 기본적으로 한 웹 브라우저마다 한 세션을 생성한다. 웹 서버는 세션 ID를 이용해서 웹 브라우저를 위한 세션을 찾기 때문에, 웹 서버와 웹 브라우저는 세션 ID를 공유해야 하는데 이때 사용하는 것이 쿠키이다. (JSESSIONID 쿠키)
쿠키 대신 세션을 사용하는 가장 큰 이유는 세션이 쿠키보다 보안이 좋기 때문이다. 쿠키는 네트워크를 통해 전달되기 때문에 HTTP 프로토콜을 사용하는 경우 누군가 중간에 쿠키의 값을 읽어올 수 있지만 세션의 값은 오직 서버에만 저장된다. 또 다른 이유는 웹 브라우저가 쿠키를 지원하지 않을 경우 또는 쿠키 사용을 막는 경우가 있지만 세션은 쿠키 설정 여부에 상관없이 사용가능하다. 서블릿/JSP는 쿠키를 사용할 수 없는 경우, URL 재작성 방식을 사용해서 세션ID를 웹 브라우저와 웹 서버가 공유할 수 있다. 하지만, 세션은 여러 서버에서 공유할 수 없지만 쿠키는 도메인을 이용해서 여러 도메인 주소에 공유할 수 있다. 이런 이유로 포털 사이트는 쿠키를 이용해서 로그인 정보를 저장한다.
세션은 마지막 접근 이후 일정 시간 이내에 다시 세션에 접근하지 않는 경우 자동으로 세션을 종료하는 기능을 갖고 있다.
세션에 유효 시간 설정 방법
1. WEB-INF\web.xml 파일에 <session-config> 태그 사용하는 방법 (시간 단위 : 분)
<session-config>
<session-timeout>50</session-timeout>
</session-config>
2. session 기본 객체가 제공하는 setMaxInactiveInterval() 메서드를 사용
session.setMaxInactiveInterval(60*60); // 초 단위 (60 * 60초 = 60분)
0 혹은 음수를 지정하면 session.invalidate() 메서드 호출 전까지 세션 객체가 서버에 유지된다. 이는 메모리 부족 현상을 야기할 수 있다. 따라사 반드시 세션 타임아웃 시간을 지정해줘야 한다.
HttpSession을 생성하는 또 다른 방법 - request.getSession() 메서드 을 이용한 세션 생성(현재 요청과 관련된 session 객체를 리턴하며 기존에 session이 존재하면 해당 session을 리턴하고 존재하지 않으면 새롭게 session을 생성해서 리턴) page 디렉티브의 session 속성값은 false로 지정
request.getSession(false)는 session이 생성된 경우에만 session 객체를 리턴하고 존재하지 않으면 null을 리턴
세션을 사용한 로그인 상태 유지
1. 로그인에 성공하면 session 기본 객체의 특정 속성에 데이터를 기록한다.
2. 이후로 session 기본 객체의 특정 속성이 존재하면 로그인한 것으로 간주한다.
3. 로그아웃할 경우 session.invalidate() 메서드를 호출하여 세션을 종료한다.
연관된 정보 저장을 위한 클래스 작성
서블릿 컨텍스트와 세션
같은 웹 브라우저라 하더라도 서로 다른 두 웹 앱이 다른 세션 ID를 사용하고 다른 JSESSIONID 쿠키를 사용한다는 것은 세션을 공유하지 않음을 의미한다. 각각이 사용하는 session 기본 객체가 다르다.
CHAPTER 11 표현언어(Expression Language) 표현식보다 간결하고 편리하게 값을 표현하는 데 사용하는 스크립트 언어이다. JSTL(JSP Standard Tag Library) 1.0 규약에 소개된 내용. JSP 2.0 버전부터 JSP에 포함. JSP 2.3 – EL 3.0
기능
- JSP의 네 가지 기본 객체가 제공하는 영역의 속성 사용
- 수치 연산, 관계 연산, 논리 연산자 제공
- 자바 클래스 메서드 호출 기능 제공
- 쿠키, 기본 객체의 속성 등 JSP를 위한 표현 언어의 기본 객체 제공
- 람다식을 이용한 함수 정의와 실행 (EL 3.0)
- 스트림 API를 통한 컬렉션 처리 (EL 3.0)
- 정적 메서드 실행 (EL 3.0)
EL은 JSP의 스크립트 요소(스크립트릿, 표현식, 선언부)를 제외한 나머지 부분 액션 태그나 커스텀 태그뿐 아니라 비스크립트 요소 부분에서 사용할 수 있다.
JSTL 태그 <c:set>은 EL 변수를 생성해주는 기능
${expr} 구문을 분석할 때 값을 계산.
#{expr} Deferred Expression 실제로 값이 사용될 때 값을 계산. 템플릿 텍스트에서 사용하면 에러 발생.
EL 기초
EL의 데이터 타입과 리터럴
- Boolean 타입
- 정수 타입: java.lang.Long 타입
- 실수 타입: 소수점(‘.’), 지수형(3.24e3) 표현 가능. java.lang.Double. 타입
- 문자열 타입: ‘ 또는 “로 둘러싼 문자열. \’, \\. java.lang.String 타입
- 널 타입: null (EL은 값이 존재하지 않는 경우 아무것도 출력하지 않는다.)
EL의 기본 객체: 이를 이용해서 요청 파라미터나 세션 속성값 등을 표현 언어에서 사용할 수 있다.
pageContext: JSP의 pageContext 기본 객체와 동일
pageScope: pageContext 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
requestScope: request 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
sessionScope: session 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
applicationScope: application 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
param: 요청 파라미터의 <파라미터 이름, 값> 매핑을 저장한 Map 객체. 파라미터 값 타입은 String이며, request.getParameter(이름)의 결과와 동일하다.
paramValues: 요청 파라미터의 <파라미터 이름, 값 배열> 매핑을 저장한 Map 객체. 값 타입은 String[]이며, request.getParameterValues(이름)의 결과와 동일하다.
header: 요청 정보의 <헤더 이름, 값> 매핑을 저장한 Map 객체. request.getHeader(이름)의 결과와 동일하다.
headerValues: 요청 정보의 <헤더 이름, 값 배열> 매핑을 저장한 Map 객체. request.getHeaders(이름)의 결과와 동일하다.
cookie: <쿠키 이름, Cookie> 매핑을 저장한 Map 객체. request.getCookies()로 구한 Cookie 배열로부터 매핑을 생성
initParam: 초기화 파라미터의 <이름, 값> 매핑을 저장한 Map 객체이다. application.getInitParameter(이름)의 결과와 동일하다.
객체 접근
cookie.name 과 cookie[‘name’]은 같은 결과 리턴한다.
<표현1>.<표현2> 또는 <표현1>[<표현2>]
객체 탐색
수치 연산자: +, -, *, / 또는 div, % 또는 mod, 단항 연산자, 연산 규칙 순서 및 유의 사항
비교 연산자: == 또는 eq, != 또는 ne, < 또는 lt, > 또는 gt, <= 또는 le, >= 또는 ge,
${someValue == ‘2004’} 는 (someValue.compareTo(“2004”) == 0) 과 같은 의미다.
논리 연산자: && 또는 and, || 또는 or, ! 또는 not
empty 연산자: 객체가 텅 빈 객체인지 검사하기 위해 사용한다. ( empty <값> ) true 또는 false 리턴
비교 선택 연산자: <수식> ? <값1> : <값2>
문자열 연결: EL 2.2 버전까지는 문자열 연결 지원 없었지만, EL 3.0 버전(JSP 2.3 버전)에 += 연산자 추가.
<% request.setAttribute(“title”, “JSP 프로그래밍”); %>
${ “문자” += “열” += “연결” } -> 문자열연결
${ “제목 :” += title } -> 제목 : JSP 프로그래밍
컬렉션: List 타입, Map 타입, Set 타입
세미콜론 연산자: ${ A ; B } (B값만 출력)
할당 연산자: 결과를 출력한다. ${var1 = 10} ${var1} 을 실행하면 “10 10”와 같이 출력하기 때문에 세미콜록 연산자를 함께 사용하면 할당 연산자의 결과 대신 빈 문자열을 결과로 출력할 수 있다.
- 연산자 우선순위
l [].
l ()
l ㅡ(단항) not ! empty
l * / div % mod
l + -
l +=
l < > <= >= lt gt le ge
l == != eq ne
l && and
l || or
l ? :
l ㅡ>
l =
l ;
특수 문자 처리하기: 역슬래시 이용 \ |
표현 언어 EL에서 객체의 메서드 호출
첫번째, 클래스 생성 - TLD 파일 작성 – web.xml 파일 설정 – taglib 디렉티브 설정
두번째, EL 3.0 버전에서 기능 추가
람다식(함수처럼 파라미터를 가진 코드 블록) 사용하기 (파라미터1, 파라미터2) -> EL 식
컬렉션 객체를 위한 스트림 API 사용하기(EL 3.0 버전에 추가)
stream()를 이용한 스트림 생성,
filter()를 이용한 걸러내기,
map()을 이용한 변환,
sorted()를 이용한 정렬,
limit()을 이용한 개수 제한
toList(), toArray()를 이용한 결과 생성
count()를 이용한 개수 확인
Optional 타입:
get() : 값이 존재할 경우 값을 리턴, 존재하지 않을 경우 ELException 발생
orElse(other) : 값이 존재할 경우 값을 리턴, 존재하지 않을 경우 other를 리턴
orElseGet( ( () -> T ) other ) : 값이 존재할 경우 값을 리턴, 존재하지 않을 경우 람다식 other 실행 결과 리턴
ifPresent( ( (x) -> void ) consumer ) : 값이 존재할 경우 값을 파라미터로 전달하여 람다식 consumer 실행
sum()과 average()를 이용한 수치 연산 결과 생성
min()과 max()를 이용한 최소/최대 구하기
anyMatch(), allMatch(), nonMatch()를 이용한 존재 여부 확인
표현 언어 비활성화 방법
1. web.xml 파일에 비활성화 옵션 지정하기
<jsp-config>
<jsp-property-group>
<url-pattern>/oldversion/*</url-pattern>
<el-ignored>true</el-ignored>
/oldversion 경로에 위치한 JSP 파일은 EL 식을 분석하지 않고 그대로 일반 문자열로 처리한다.
${expr} 형식은 EL로 처리하고 #{expr} 형식은 문자열로 처리하는 방법
<deferred-syntax-allowed-as-literal>true</deferred-syntax-allowed-as-literal> 태그값 true 사용
2. JSP 페이지에서 page 디렉티브 속성을 이용해 비활성화 옵션 지정하기
isElIgnored: true일 경우 EL을 일반 문자열로 처리
deferredSyntaxAllowedAsLiteral: true일 경우 #{expr} 형식의 EL을 문자열로 처리
3. web.xml 파일을 서블릿 2.3 또는 2.4 버전에 맞게 작성하기
(web.xml 파일이 사용하는 서블릿 버전에 따라서 EL 지원 여부 결정)
servlet 2.3 버전의 web.xml: EL을 지원하지 않는다. (JSP 1.2 버전)
servlet 2.4 버전의 web.xml: #{expr}을 지원하지 않는다. (JSP 2.0 버전)
servlet 2.5/3.0/3.1 버전의 web.xml: EL을 지원한다.
CHAPTER 12 표준 태그 라이브러리 JSTL(JSP Standard Tag Library): 커스텀 태그 중 많이 사용되는 것(논리적인 판단, 반복 처리, 포맷 처리)을 모아 표준을 만들어 정의한 것이며 이를 사용하면 스크립트릿 코드의 사용을 줄이고 더욱 간결하고 이해하기 쉬운 코드를 작성할 수 있다.
JSP 2.3 버전 - JSTL 1.2 버전(JSP 2.1/2.2) 호환
JSTL이 제공하는 태그의 종류: 코어, 국제화, 함수, XML, 데이터베이스
접두어: JSP 페이지가 커스텀 태그를 호출할 때 사용
관련 URI: JSTL이 제공하는 커스텀 태그를 구분해주는 식별자로 이를 이용해서 JSP 페이지에서 사용할 커스텀 태그 라이브러리를 선택
코어 태그
변수 지원 태그, 흐름 제어 태그, URL 처리 태그, 기타 태그
국제화 태그
로케일 지정 태그, 메시지 처리, 숫자 및 날짜 포맷팅
<fmt:message> 태그의 리소스 번들 검색 순서
1. bundle 속성에 지정한 리소스 번들을 사용
2. <fmt:bundle> 태그에 중첩된 경우 <fmt:bundle> 태그에서 설정한 리소스 번들 사용
3. 1이나 2가 아닐 경우 기본 리소스 번들 사용. 기본 리소스 번들은 web.xml 파일에서 javax.servlet.jsp.jstl.fmt.localizationContext 컨텍스트 속성을 통해서 설정할 수 있다.
CHAPTER 13 Eclipse 사용
CHAPTER 14 데이터베이스 프로그래밍 기초: JDBC API를 이용
Java Database Connectivity (JDBC) is an application programming interface (API) for the programming language Java, which defines how a client may access a database. It is a Java-based data access technology used for Java database connectivity. It is part of the Java Standard Edition platform, from Oracle Corporation. It provides methods to query and update data in a database, and is oriented towards relational databases. A JDBC-to-ODBC bridge enables connections to any ODBC-accessible data source in the Java virtual machine (JVM) host environment.
연결 - 명령어 전송(SQL 실행) – 결과 전송 – 연결 종료
MySQL Server: MySQL DBMS 프로그램
MySQL Workbench: MySQL 클라이언트 프로그램으로 쿼리를 실행할 때 사용
Connector/J: 자바에서 MySQL에 연결할 때 사용하는 JDBC 드라이버
SQL (Structured Query Language)
자바 (웹) 어플리케이션 - JDBC API – 각 JDBC 드라이버 – 각 데이터베이스
JDBC 드라이버는 클래스 형태로 존재하며, 보통 Jar 파일로 제공
‘Access denied for –‘ 에러 메시지의 경우
- 데이터베이스를 올바르게 생성했는지
- 데이터베이스에 접근할 때 사용한 DB 계정과 암호가 올바른지
- 해당 계정이 데이터베이스에 접근할 권한이 있는지
05 JSP에서 JDBC 프로그래밍하기
JDBC의 구조: 자바(웹) 앱 – JDBC API – JDBC 드라이버 – 데이터베이스
JDBC 드라이버 준비하기
JDBC 프로그래밍의 코딩 스타일
1. JDBC 드라이버 로딩
2. 데이터베이스 커넥션 구함
3. 쿼리 실행을 위한 Statement 객체 생성
4. 쿼리 실행
5. 쿼리 실행 결과 사용
6. Statement 종료
7. 데이버테이스 커넥션 종료
DBMS와의 통신을 위한 JDBC 드라이버
데이터베이스 식별을 위한 JDBC URL
데이터베이스 커넥션
Statement를 사용한 쿼리 실행
ResultSet에서 값 읽어오기
ResultSet에서 LONG VARCHAR 타입 값 읽어오기
Statement를 이용한 쿼리 실행 시 작은따옴표 처리
PreparedStatement를 사용한 쿼리 실행
1. Connection.prepareStatement() 메서드를 사용하여 PreparedStatement 생성
2. PreparedStatement의 set 메서드를 사용하여 필요한 값 지정
3. PreparedStatement의 executeQuery() 또는 executeUpdate() 메서드를 사용하여 쿼리를 실행
4. finally 블록에서 사용한 PreparedStatement를 닫음
PreparedStatement에서 LONG VARCHAR 타입 값 지정하기
PreparedStatement 쿼리를 사용하는 이유
- 값 변환을 자동을 하기 위해
- 간결한 코드를 위해
06 웹 어플리케이션 구동 시 JDBC 드라이버 로딩하기
07 JDBC에서 트랜잭션 처리
- JDBC의 오토 커밋 모드를 false로 지정하는 방법 (단일 데이터베이스에 접근하는 경우)
- JTA(Java Transaction API)를 이용하는 방법(두개 이상의 데이터베이스를 트랜잭션으로 처리하는 경우)
08 커넥션 풀
- 데이터베이스와 연결된 커넥션을 미리 만들어 풀 속에 저장해 두고 필요할 때 가져다 쓰고 다시 반환
(커넥션 생성 및 종료, 연결 시간 절약, 커넥션 수 일정하게 유지)
- 오픈 소스 프로젝트 DBCP API를 이용해 커넥션 풀을 제공
1. DBCP 관련 jar 파일과 JDBC 드라이버 jar 파일 설치하기
2. 커넥션 풀 초기화 하기
1. 실제 커넥션을 생성할 ConnectionFactory를 생성한다.
2. 커넥션 풀로 사용할 PoolableConnection을 생성하는 PoolableConnectionFactory를 생성한다.
3. 커넥션 풀의 설정 정보를 생성한다.
4. 커넥션 풀을 사용할 JDBC 드라이버를 등록한다.
3. 커넥션 풀로부터 커넥션 사용하기
DBCP는 다음 두 가지 기준으로 풀에 있는 커넥션을 검사한다.
1. 커넥션이 최소 유휴 시간보다 오래 풀에 있는 경우 (minEvictableIdleTimeMillies)
2. 커넥션이 유효한지 여부 확인 (testWhileIdle)
CHAPTER 15 웹 어플리케이션의 일반적인 구성 및 방명록 구현
웹 어플리케이션의 주요 구성 요소
JSP(뷰): Service 클래스가 실행한 결과를 화면에 출력하거나 Service가 기능을 수행하는데 필요한 데이터를 전달
MVC 프레임워크: 사용자 요청을 Service에 전달하고 Service의 실행 결과를 JSP와 같은 뷰에 전달
Service 클래스: 사용자의 요청을 처리하는 기능을 제공하며 이를 위한 로직을 구현, DAO 클래스를 이용해서 DB 연동을 처리한다. (가입 신청 처리, 글 목록 제공 등의 기능을 구현)
DAO 클래스: DB와 관련된 쿼리를 실행, Service 클래스는 데이터를 DB에서 읽어 오거나 DB에 저장할 때 DAO 클래스를 사용
데이터 접근 객체(Data Access Object)의 구현:
데이터에 접근할 때 사용하는 객체를 위한 클래스, 한 개의 DB 테이블마다 한 개의 DAO 클래스를 작성, 각 클래스는 쿼리를 실행해주는 메서드를 제공한다. DAO 클래스는 테이블로부터 데이터를 읽어와 자바 객체로 변환하거나 자바 객체의 값을 테이블에 저장한다.
CRUD(DB 처리를 말하며, CREATE(insert), READ(select), UPDATE(update), DELETE(delete)
Connection 객체 -> Statement나 PreparedStatement 객체 -> DAO 클래스
- DAO 클래스의 메서드에서 직접 Connection을 생성(메서드마다 다른 커넥션 객체 사용 트랜잭션 불가능)
- DAO 객체를 생성할 때 생성자로 Connection 전달받기(각 메서드는 하나의 커넥션 객체 사용, 트랜잭션 가능, 하지만 매번 새로운 DAO 객체 생성)
- DAO 클래스 메서드의 파라미터로 Connection 객체를 전달받기(한 개의 커넥션 객체 사용, 트랜잭션 가능, DAO 객체 매번 생성하지 않아도, 하지만 메서드 실행마다 커넥션 객체를 파라미터로 전달, 길어진다)
ThreadLocal 사용하면 편리한 방법으로 Connection 객체 전달할 수 있다. ( http://javacan.tistory.com/entry/ThreadLocalUsage 참고)
close() 및 rollback() 처리 코드를 위한 JdbcUtil 클래스 생성, Template Method Pattern과 Strategy Pattern을 사용한 PreparedStatement의 생성부터 쿼리 실행 코드 반복 제거 ( http://javacan.tistory.com/entry/116 참고)
서비스 클래스의 구현: 사용자의 요청을 처리하기 위한 기능 (게시글 목록 제공, 게시글 쓰기, 회원 등록, 수정) – 서비스 클래스와 트랜잭션 처리, 서비스 클래스의 익셉션 처리
싱글톤(Singleton) 패턴을 이용한 구성 요소 구현: 매번 새로운 서비스 객체를 생성하지 않고, 한 개의 객체를 재사용하도록 하기 위해 특정 클래스의 객체가 단 한 개만 존재하도록 제약하는 구현 패턴
- 유일한 객체를 정적 필드에 저장 -> 유일한 객체에 접근할 수 있는 정적 메서드 정의 (생성자를 private으로 설정해서 외부 클래스에서 객체를 생성할 수 없도록 하는 대신 getInstance() 메서드를 public하게 제공하며 매번 동일한 객체를 리턴)
Connection을 제공하는 ConnectionProvider 만들기
방명록 구현
l 방명록을 구성하는 클래스의 구조 – 서비스 클래스, DAO 관련 클래스, JDBC 커넥션 관련 클래스
l 데이터베이스와 테이블 생성 – 데이터베이스 생성한 뒤 MySQL에서 사용할 사용자를 추가, 테이블 추가
l 이클립스 프로젝트 생성과 필요 모듈 복사
WebContent/WEB-INF/lib에 위치 (commons-dbcp2-2.6.0.jar / commons-logging-1.2.jar / commons-pool2-2.6.2.jar / mysql-connector-java-8.0.13.jar / jstl-1.2.jar)
l 커넥션 풀 설정을 위한 DBCPInit 클래스 구현과 web.xml 설정
l Message 클래스 작성
l MessageDao 클래스 구현
l 서비스 클래스의 구현 – GetMessageListService, WriteMessageService, DeleteMessageService
l JSP에서 서비스 사용하기 – 메시지 목록을 보여주는 list.jsp, 메시지 등록을 처리하는 write.jsp, 메시지 삭제 폼 confirmDeletion.jsp, 메시지 삭제 요청 처리하는 deleteMessage.jsp
CHAPTER 16 커스텀 태그 만들기
장점: 재사용, 쉽고 단순한 JSP 코드 작성, 코드 가독성 향상
커스텀 태그의 종류:
1. JSP 1.2 스타일로 구현한 커스텀 태그
2. JSP 2.0 또는 그 이상 버전의 SimpleTag를 사용한 커스텀 태그
3. JSP 2.0 또는 그 이상 버전의 태그 파일을 사용한 커스텀 태그
태그 파일이란 JSP 문법을 사용해서 커스텀 태그로 동작할 수 있도록 만들어진 소스 코드
태그 파일의 기본
내용을 출력하는 단순 태그 파일 구현
태그 파일의 속성 설정 방법
몸체 내용 처리
변수의 생성
CHAPTER 17 서블릿 기초 : 서블릿 보다는 JSP를 사용하지만, MVC 패턴을 지원하는 프레임워크를 만들어야 하는 경우 서블릿으로 기반 코드를 개발하는 경우가 많기 때문에 직접 구현하지는 않더라도 이해하고 있는 것은 중요
- 일반적인 서블릿의 개발 과정
1. 서블릿 규약에 따라 자바 코드를 작성한다.
2. 자바 코드를 컴파일해서 클래스 파일을 생성한다.
3. /WEB-INF/classes 폴더에 클래스 파일을 패키지에 알맞게 위치시킨다.
4. web.xml 파일에 서블릿 클래스를 설정한다.
5. 톰캣 등의 컨테이너를 실행한다.
6. 웹 브라우저에서 확인한다.
- URL 패턴 매핑 방법 - @WebServlet 애노테이션, web.xml 파일에 설정
- HTTP 각 방식별 구현 매서드
doGet(), doPost()
서블릿 로딩 과정 (웹 컨테이너가 서블릿 객체를 생성하고, init() 메서드를 호출하는 과정)
init() 메서드의 기본 구현 (서블릿 컨테이너는 서블릿을 초기화하기 위해 ServletConfig 파라미터를 갖는 init() 메서드를 실행)
웹 컨테이너를 처음 구동하는 시점에 서블릿을 초기화하기 위한 설정 <load-on-startup> 태그
서블릿 로딩과 초기화
초기화 파라미터 (사용 이유: 클래스의 수정 없이 초기화 과정에서 필요한 값을 수정할 수 있기 때문)
URL 패턴 매핑 규칙
URL 패턴은 다음 규칙에 따라 서블릿을 매핑한다.
1. ‘/’로 시작하고 ‘/*’로 끝나는 url-pattern은 경로 매핑을 위해서 사용한다.
2. ‘*.’로 시작하는 url-pattern은 확장자에 대한 매핑을 할 때 사용한다.
3. 오직 ‘/’만 포함하는 경우 어플리케이션의 기본 서블릿으로 매핑한다.
4. 이 규칙 외, 나머지 다른 문자열은 정확한 매핑을 위해서 사용한다.
이 책의 범위를 넘어가는 서블릿3에 추가된 비동기 서블릿. 이를 이해하려면 쓰레드에 대한 이해가 필요하다.
http://javacan.tistory.com/entry/Servlet-3-Async 참고
CHAPTER 18 MVC 패턴 구현
모델 2 구조와 MVC 패턴
모델 1 구조
모델 2 구조
MVC 패턴
MVC 패턴과 모델2 구조의 매핑
MVC의 컨트롤러: 서블릿
MVC의 뷰: JSP
MVC의 모델: 처리한 결과값을 저장하는 객체로 보통 자바빈을 사용하며, 서비스 클래스나 DAO 클래스를 이용해서 비즈니스 로직을 수행
모델 2 구조를 이용한 MVC 패턴 구현
모델 |
장점 |
단점 |
모델1 |
-배우기 쉽다. -자바 언어를 몰라도 어느 정도 구현 가능하다. -기능과 JSP가 직관적으로 연결된다 |
-로직 코드와 뷰 코드가 혼합되어 JSP 코드가 복잡해진다. -뷰 변경시 논리 코드의 빈번한 복사가 발생해서 코드 중복이 발생하기 쉽다. 즉 유지보수가 힘들어진다. |
모델2 |
-로직 코드와 뷰 코드를 분리해서 유지보수가 쉬워진다. -컨트롤러 서블릿에서 권한 검사나 인증과 같은 공통 기능 처리가 가능하다. -확장이 용이하다. |
-자바 언어에 친숙하지 않으면 접근하기가 쉽지 않다. -작업량이 많다.(커맨드 클래스+뷰JSP) |
CHAPTER 19 필터 : HTTP 요청과 응답을 변경할 수 있는 재사용 가능한 클래스. 정보와 흐름을 변경.
필터란 무엇인가?
필터의 구현
javax.servlet.Filter 인터페이스
javax.servlet.ServletRequestWrapper 클래스
javax.servlet.ServletResponseWrapper 클래스
/lib/servlet-api.jar 포함시키야 한다
Filter 인터페이스
init() 메서드에 전달되는 FilterConfig는 필터의 초기화 파라미터를 읽어올 때 사용
필터 설정하기: web.xml 이용
<filter-mapping>을 <url-pattern>이 아닌 <servlet-name>으로 하면 특정 서블릿에 대한 요청에 대해 필터를 적용한다.
<dispatcher> 태그를 사용하면 필터가 적용되는 시점을 설정할 수 있다. (
REQUEST(기본값): 클라이언트의 요청인 경우 필터를 적용
FORWARD: forward()를 통해서 제어 흐름을 이동하는 경우에 필터를 적용
INCLUDE: include()를 통해서 포함되는 경우에 필터를 적용 <jsp:include> 코드
필터 설정하기: @WebFilter 애노테이션 이용 (자동으로 필터로 등록된다)
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName=”xsltFilter”, urlPatterns={“/xml/*”, “/xsl/*”})
public class XSLTFilter implements Filter { 필터구현 }
그 외 속성: servletNames, initParams, dispatcherTypes(필터 적용 범위를 지정, 기본값은 DispatchType.REQUEST)
요청 및 응답 래퍼 클래스 : 요청 정보를 변경하여 최종 자원인 서블릿/JSP/HTML/기타 자원에 전달하고, 최종 자원으로부터의 응답을 변경하여 새로운 응답 정보를 클라이언트에 보낸다.
필터의 응용: 사용자 인증, 캐싱 필터, 자원 접근에 대한 로깅, 응답 데이터(HTML, 응답 헤더, 데이터 암호화 등) 변환, 공통 기능 실행
로그인 검사 필터
XSL/T 필터 -> 응답 데이터를 어떻게 변경하는지가 포인트!
- 응답 데이터를 임시로 보관하는 버퍼로 사용할 출력 스트림(PrintWriter 타입)
- 버퍼를 사용하는 응답 래퍼 클래스
- 응답 래퍼 클래스를 이용해서 응답 데이터에 XSL/T 변환을 수행하는 필터
필터의 작업 처리 단계
1. 응답 래퍼(XSLTResponseWrapper)를 생성한다.
2. 생성한 응답 래퍼를 체인의 다음 필터에 전달한다.
3. 래퍼로부터 서블릿/JSP가 출력한 데이터를 읽어와 XSL/T를 사용하여 HTML로 변환한다.
4. 변환된 결과인 HTML을 실제 응답 스트림에 출력한다.
캐릭터 인코딩 필터
CHAPTER 20 ServletContextListener 구현
ServletContextListener를 이용한 이벤트 처리
웹 어플리케이션이 시작되고 종료될 때 특정한 기능을 실행하려면
1. javax.servlet.ServletContextListener 인터페이스를 구현한 클래스를 작성한다.
2. web.xml 파일에 1번에서 작성한 클래스를 등록한다. (<listener>, <listener-class> 태그 사용)
javax.servlet.ServletContextListener 인터페이스는 웹 어플리케이션이 시작되거나 종료될 때 호출할 메서드를 정의한 인터페이스
- public void contextInitialized(ServletContextEvent sce) 웹 앱을 초기화할 때 호출
- public void contextDestroyed(ServletContextEvent sce) 웹 앱을 종료할 때 호출
ServletContextEvent 클래스는 웹 앱 컨택스트를 구할 수 있는 getServletContext() 메서드를 제공
(ServeltContext 객체는 JSP의 application 기본 객체와 동일한 객체로, 이를 이용하면 web.xml 파일에 설정된 컨텍스트 초기화 파라미터를 구할 수 있다.)
ServletContextListener를 이용해서 커넥션 풀을 초기화하는 클래스 구현 방법
- web.xml 파일에 커넥션 풀을 초기화할 때 사용할 컨텍스트 초기화 파라미터를 설정한다.
- ServletContextListener 인터페이스를 구현한 클래스는 contextInitialized() 메서드에서 컨텍스트 초기화 파라미터를 이용해서 커넥션 풀을 초기화하는 데 필요한 값을 로딩한다.