Search

Servlet → Spring

웹 어플리케이션

동적 웹 프로그래밍

클라이언트 웹 서버 웹 어플리케이션 서버 DB

웹 어플리케이션 구성 요소의 기능

1.
루트 디렉토리: 다른 웹 어플리케이션 이름과 중복을 허용하지 않으며, JSP, HTML파일 저장
2.
WEB-INF: 웹 어플리케이션 정보 저장. 외부에서 접근 불가능
3.
classes: 서블릿 및 일반 클래스들이 위치하는 곳
4.
lib: 여러 가지 라이브러리 압축 파일이 저장되는 곳.
5.
web.xml: 배치 지시자로서 환경 설정 파일.

WEB-INF 하위 구조

1. jsp/html : jsp파일과 html파일이 저장된 곳
2.
css: 스타일시트 파일이 저장된 곳
3.
image: 웹 어플리케이션에서 사용되는 이미지
4.
js: 자바스크립트 파일이 저장된 곳
5.
bin: 애플리케이션에서 사용되는 각종 실행 파일이 저장된 곳
6.
conf: 프레임워크에서 사용하는 각종 설정 파일이 저장된 곳
7.
src: 자바 소스 파일이 저장

컨테이너에서 웹 어플리케이션

웹 어플리케이션을 톰캣에 등록해야한다.
1.
%CATALINA_HOME%webApps 에 애플리케이션을 저장
2.
server.xml에 직접 웹 어플리케이션을 등록

컨텍스트

server.xml에 등록하는 웹 어플리케이션을 컨텍스트라 부른다.
컨테이너 실행 시 웹 어플리케이션 당 하나의 컨텍스트가 생성
<Context path = "/webMal" docBase = "C:\\webShop" reloadable = "true"/>
JavaScript
복사
path: 웹 어플리케이션의 컨텍스트 이름. 웹 브라우저에서 실제 웹 애플리케이션을 요청하는 이름
docBase: 컨텍스트에 대한 실제 웹 애플리케이션이 위치한 경로 WEB-INF 상위 폴더까지의 경로
reloadable: 실행 중 소스 코드가 수정될 경우 바로 갱신할지를 설정.

동작 과정

1.
웹 브라우저에서 컨텍스트 이름으로 요청
2.
요청을 받은 톰캣 컨테이너는 요청한 컨텍스트 이름이 server.xml에 있는지 확인
3.
해당 컨텍스트 이름이 있으면, 컨텍스트 이름에 대한 실제 웹 애플리케이션이 있는 경로로 가서 요청한 main.html을 클라이언트 웹 브라우저로 전송
4.
웹 브라우저는 전송된 main.html을 브라우저에 나타냄

서블릿 API 계층 구조와 기증

Servlet, ServletConfig: 인터페이스
GenericServlet 추상 클래스: 이 두 인터페이스의 추상 메서드를 구현
HttpServlet: GenericServlet을 상속받는다.
Servlet 인터페이스
Servlet관련 추상 메서드를 선언
init(). service(), destroy(). getServletInfo(), getServletConfig()를 선언
ServletConfig 인터페이스
Servlet 기능 관련 추상 메서드가 선언
getInitParameter(), getInitParameterNames(), getServletContext(), getServletName()이 선언
GenericServlet 클래스
상위 두 인터페이스를 구현하여 일반적인 서블릿 기능을 구현한 클래스
GenericServlet을 상속받아 구현한 사용자 서블릿은 사용되는 프로토콜에 따라 각각 service()를 오버라이딩해서 구현함
HttpServlet
HTTP프로토콜을 사용하는 웹 브라우저에서 서블릿 기능을 수행
웹 브라우저 기반 서비스를 제공하는 서블릿을 만들 때 상속받아 사용
요청 시 service()가 호출되면서 요청 방식에 다라 doGet()이나 doPost()가 차례대로 요청

서블릿 매핑

<servlet> <servlet-name>aaa</servlet-name> <servlet-class>sec01.ex01.FirstServlet</servlet-class> </servlet> <servlet> <servlet-name>b</servlet-name> <servlet-class>sec01.ex01.SecondServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>aaa</servlet-name> <url-pattern>/first</url-pattern> <servlet-mapping> <servlet-mapping> <servlet-name>b</servlet-name> <url-pattern>/second</url-pattern> <servlet-mapping>
JavaScript
복사
→ 근데 여러 서블릿을 web.xml에 설정할 경우 복잡해진다
⇒ 각 서블릿 클래스에 애너테이션을 이용해서 기능을 호출한다.

서블릿 기능

클라이언트로부터 요청을 받고, 비즈니스 로직을 처리, 처리한 결과를 클라이언트에게 돌려줌
요청과 관련된 API : HttpServletRequest 클래스
응답과 관련된 API: HttpServletResponse

HttpServletRequest

1.
authenticate: 현재 요청한 사용자가 ServletContext 객체에 대한 인증을 하기위한 컨테이너 로그인 매커니즘을 사용
2.
changeSessionId(): 현재 요청과 연관된 현재 세션의 id를 변경하여 새 세션 id를 반환
3.
getContextPath(): 요청한 컨텍스트를 가리키는 URI를 반환
4.
getCookies(): 클라이언트가 현재의 요청과 함께 보낸 쿠기 객체들에 대한 배열을 반환
5.
getHeader(): 특정 요청에 대한 헤더 정보를 문자열로 반환
6.
getHeaderNames(): 현재의 요청에 포함된 헤더의 name속성을 enumeration으로 반환
7.
getMethod(): 현재 요청이 어떤 HTTP요청인지 반환
8.
getRequestURI(): 요청한 URL의 컨텍스트 이름과 파일 경로까지 반환
9.
getServletPath(): 요청한 URL에서 서블릿이나 JSP이름을 반환
10.
getSession(): 현재의 요청과 연관된 세션을 반환. 세션이 없으면 만들어서 반환

HttpServletResponse

1.
addCookie(Cookie cookie): 응답에 쿠키를 추가
2.
addHeader(String name, String value): name과 value를 헤더에 추가
3.
encodeURL(String url): 클라이언트가 쿠키를 지원하지 않을 때 세션 id를 포함한 특정 URL을 인코딩
4.
getHeaderNames(): 현재 응답의 헤더에 포함된 name을 얻어옴
5.
sendRedirect(String location): 클라이언트에게 리다이렉트 응답을 보낸 후 특정 URL로 다시 요청
6.
getPathInfo(): 클라이언트가 요청시 보낸 URL과 관련된 추가 경로 정보를 반환

서블릿에서 클라이언트의 요청을 얻는 방법

String getParameter(String name) : name의 값을 알고 있을 때, name에 대한 전송된 값을 받아옴
String[] getParameterValues(String name): 같은 name에 대해 여러 개의 값을 얻을 때 사용
Enumeration getParameterNames(): name값을 모를 때 사용

서블릿의 응답 처리 방법

1.
doGet()이나 doPost() 메서드 안에서 처리
2.
HttpServletResponse 객체를 이용
3.
setContentType()을 이용해 클라이언트에게 전송할 데이터 종류(MIME-TYPE)을 지정
4.
클라이언트와 서블릿의 통신은 자바 I/O의 스트림을 이용
request.seCharracterEncoding("utf-8"); response.setContentType("text/html;charset = utf-8"); PrintWriter out = response.getWriter(); String id = request.getParameter("user-id"); String pw = request.getParameter("user_pw"); out.print(data);
Java
복사

DataSource 이용해 데이터베이스 연동하기

웹 애플릴케이션이 필요할 때마다 DB에 연결하여 작업하는 방식
이런 식으로 필요할 때마다 연동해서 작업하는 경우, 데이터베이스 연결에 시간이 많이 걸림
⇒ 웹 앱이 실행됨과 동시에 연동할 DB와의 연결을 미리 설정.
⇒ 필요할 때마다 미리 연결해 놓은 상태를 이용해 빠르게 DB와 연동하여 작업
⇒ DB와 연결시킨 상태를 유지하는 기술을 커넥션풀 이라고 부름.

JNDI

실제 웹 어플리케이션에서 ConnectionPool객체를 구현할 때는 Java Se에서 제공하는 javax.sql.Datasource 클래스를 이용
웹 앱 실행 시 톰캣이 만들어 놓은 ConnectionPool 객체에 접근할 때는 JNDI를 이용
JNDI: 필요한 자원을 키/값/쌍으로 저장한 후 필요할 때 키를 이용해 값을 얻는 방법.
미리 접근할 자원에 키를 지정한 후 애플리케이션이 실행 중일 때 이 키를 이용해 자원에 접근해 작업하는 것.
Ex)
1.
웹 브라우저에서 name/value 쌍으로 전송한 후 서블릿에서 getParameter(name)으로 값을 가져올 때
2.
해쉬맵이나 해시테이블에 키/값으로 저장한 후 키를 이용해 값을 가져올 때
3.
웹 브라우저에서 도메인 네임으로 DNS서버에 요청할 경우 도메인 네임에 대한 IP 주소를 가져올 때
톰캣 컨테이너가 ConnectionPool 객체를 생성하면 이 객체에 대한 JNDI 이름을 미리 설정해놓는다. 그러면 웹 애플리케이션에서 데이터베이스와 연동작업을 할 때 JNDI 이름으로 접근하여 작업
→ context.xml에 Connection 객체 생성시 연결할 데이터베이스 정보를 JNDI로 설정
Context ctx = new InitialContext(); Context envContext = (Context) ctx.lookup("java:/comp/env"); dataFactory = (Datsource) envContext.lookoup("jdbc/oracle"); con = dataFactory.getConnection();
Java
복사

서블릿 확장 API

포워딩

하나의 서블릿에서 다른 서블릿이나 JSP와 연동하는 방법을 포워드
1.
redirect
HttpServletResponse 객체의 sendRedirect() 메서드를 이용
웹 브라우저에 재요청하는 방식
웹 브라우저를 통해 다른 서블릿을 호출하면서 원하는 데이터 전달 가능
GET방식을 이용해 데이터 전달
2.
Refresh
HttpServletResponse 객체의 addHeader() 메서드
웹 브라우저에 재요청하는 방식
response.addHeadeR("Refresh",10;url=url)
3.
location
자바스크립트 location 객체의 href 속성을 이용
자바스크립트에서 재요청하는 방식
4.
dispatch
일반적으로 포워딩 기능을 지칭
서블릿이 직접 요청하는 방식
RequestDispatcher 클래스의 forward() 메서드를 이용
Ex) RequestDispatcher dis = request.getRequestDispatcher("jsp");
dis.forward(request,response);
주소 창의 URL이 변경되지 않고 그대로

바인딩

서블릿에서 다른 서블릿을 대량의 데이터를 공유하거나 전달하고 싶을 때
주로 HttpServletRequest, HttpSession, ServletContext 객체에서 사용, 저장된 자원은 공유하여 사용
1.
setAttribute(String name, Object obj)
2.
getAttribute(String name)
3.
removeAttribute(String name)

ServletContext, ServletConfig

ServletContext : 톰캣 컨테이너 실행 시 각 컨텍스트(웹 어플리케이션 마다) 한개의 ServletContext 객체를 생성. 톰캣 컨테이너가 종료하면 ServletContext 객체 역시 소멸
ServletContext 객체는 웹 애플리케이션이 실행되면서 애플리케이션 전체의 공통 자원이나 정보를 미리 바인딩해서 서블릿들이 공유하여 사용
Servletcontext
서블릿에서 파일 접근 기능
자원 바인딩 기능
로그 파일 기능
컨텍스트에서 제공하는 설정 정보 제공 기능
ServletContext는 컨텍스트당 생성되는 반면에 ServletConfig는 각 서블릿에 대해 생성
메소드들
1.
getAttribute(String name), setAttribute(String name, Object object)
name을 이용해 값을 꺼내오거나 바인딩한다.
2.
getAttributeNames()
바인딩된 속성들의 name을 반환
3.
getcontext(String uripath)
지정한 uripath에 해당되는 객체를 반환
4.
getInitParameter(String name)
name에 해당하는 매개변수의 초기화 값을 반환
name에 해당되는 매개변수가 존재하지 않으면 null을 반환
5.
getParameterNames()
컨텍스트의 초기화 관련 매개변수들의 이름들을 String 객체가 저장된 Enumeration 타입으로 반환
매개변수가 존재하지 않으면 null을 반환
6.
getMajorVersion()
서블릿 컨테이너가 지원하는 주요 서블릿 API 버전을 반환
7.
getRealPath(String path)
지정한 path에 해당되는 실제 경로를 반환
8.
getResource(String path)
지정한 path에 해당되는 Resource를 반환
9.
getServerInfo()
서블릿이 실행되고 있는 컨테이너의 이름과 버전을 반환
10.
getServletContextName()
애플리케이션 ServletContext에 대한 웹 앱 이름을 반환
11.
log(String ms)
로그 파일에 로그 기록
12.
removeAttribute(String name)
바인딩된 객체 제거
13.
setInitParameter(String name, String value)
주어진 name으로 value를 컨텍스트 초기화 매개변수로 설정
ServletContext context = getServletContext(); InputStream is = context.getResourceAsStream("/WEB-INF/bin/init.txt"); BufferedReader buffer = new BufferedReader(new InputStreamReader(is)); while((menu = buffer.readLine())!= null){ StringTokenizer tokens = new StringTokenizer(menu,","); }
Java
복사

ServletConfig

서블릿과 동일하게 생성되고, 소멸될 대 같이 소멸됨
ServletContext 객체를 얻는 기능
서블릿에 대한 초기화 작업 기능

세션과 쿠키

웹 페이지나 서블릿끼리 상태나 정보를 공유하려면 웹 페이지 연결 기능, 세션 트래킹을 이용해야함.
웹 페이지를 연동하는 방법
1.
<hidden> 태그
2.
URL Rewriting: GET방식으로 URL 뒤에 정보를 붙여서 다른 페이지로 전송
3.
쿠키: 클라이언트 PC의 Cookie 파일에 정보를 저장한 후 웹 페이지들이 공유
4.
세션: 서버 메모리에 정보를 저장한 후 페이지들이 공유

쿠키

정보가 클라이언트 PC에 저장된다.
저장 정보 용량에 제한이 있다
보안이 취약하다
클라이언트 브라우저에서 사용 유무를 설정할 수 있다
도메인당 쿠키가 만들어진다.
쿠키의 종류
1.
Persistence 쿠키
파일로 생성
쿠키를 삭제하거나 쿠키 설정 값이 종료된 경우
최초 접속 시 서버로 전송
로그인 유무 또는 팝업창을 제한할 대
2.
Session 쿠키 → 세션과 함께 사용함
브라우저 메모리에 생성
브라우저를 종료한 경우
최초 접속 시 서버로 전송되지 않음
사이트 접속시 Session 인증 정보를 유지할 때
쿠키 실행 과정
1.
브라우저로 사이트에 접속
2.
서버는 정보를 저장한 쿠키를 생성
3.
생성된 쿠키를 브라우저로 전송
4.
브라우저는 서버로부터 받은 쿠키 정보를 쿠키 파일에 저장
5.
브라우저가 다시 접속해 서버가 브라우저에게 쿠키 전송을 요청하면, 브라우저는 쿠키 정보를 서버에 넘겨줌
6.
서버는 쿠키 정보를 이용해 작업
쿠키 API
Cookie 클래스를 이용
HttpServletResponse의 addCookie() 메서드를 이용해 클라이언트로 전송 후 저장
HttpServletRequest의 getCookie() 메서드를 이용해 쿠키를 서버로 가져옴
getComment(), setComment(String) : 쿠키에 대한 설명
getDomain(), setDomain(String) : 쿠키의 유효한 도메인 정보
getMaxAge(), setMaxAge(): 쿠키 유효 기간
getName(), setValue() : 쿠키 이름과 값을 설정
getPath(), setPath() : 쿠키의 디렉터리 정보
setMaxAge() 메서드 인자 값의 종류 → Persistence 쿠키를 만들거나 메모리에만 저장하는 Session 쿠키
인자 값으로 음수나 setMaxAge()를 사용하지 않고 쿠키를 만들면 Session 쿠키로 저장됨.
인자 값으로 양수를 지정하면 Persistence 쿠키로 저장

세션

세션은 서버의 메모리에 생성되어 정보를 저장
세션은 각 브라우저당 한 개, 사용자당 한개가 생성
브라우저의 세션 연동은 세션 쿠키를 이용
브라우저당 한 개의 세션(세션 id)가 생성
세션은 유효한 시간을 가짐
동작과정
1.
브라우저로 사이트에 접속
2.
서버는 접속한 브라우저에 대한 세션 객체를 생성
3.
서버는 생성된 세션 id를 클라이언트 브라우저에 응답
4.
브라우저는 서버로부터 받은 세
5.
션 id를 브라우저가 사용하는 메모리의 세셔 쿠키에 저장한다.
6.
브라우저에 재접속하면 브라우저는 세션 쿠키에 저장된 세션 id를 서버에 전달
7.
서버는 전송된 세션 id를 이용해 해당 세션에 접근하여 작업을 수행
메소드들
getAttribute(), setAttribute() : 세션 속성 이름이 name인 속성에 속성 값으로 value를 할당
getAttributeNames(): 속성 이름이 name인 속성 값을 Object타입으로 반환
getCreationTime(): 현재 세션이 생성된 시간까지 경과된 시간 계산
getId(): 세션에 할당된 고유 식별자를 String 타입으로 반환
getMaxInactiveInterval(): 현재 생성된 세션을 유지하기 위해 설정된 세션 유지 시간을 int타입으로 반환
invalidate(): 세션을 소멸
isNew(): 최초로 생성된 건지, 기존에 생성되어있던건지 판별
removeAttribute(): 세션 속성 이름이 name인 속성을 제거
setMaxInactiveInterval(): 세션 유지 시간을 초 단위롯 설정

서블릿 필터와 리스너

서블릿 속성과 스코프

Servletcontext: 애플리케이션 전체에 대해 접근
HttpSession: 브라우저에서만 접근
HttpServletRequest: 해당 요청/응답 사이클에서만 접근

필터 API

한글 인코딩처럼 각 서블릿에서 반복적으로 처리해야하는 작업 등, 공통 작업을 미리 필터에서 처리하면 반복해서 작업할 필요가 없다.

필터 종류

요청 필터, 응답 필터
요청 필터: 사용자 인증 및 권한 검사, 요청 시 요청 관련 로그 작업, 인코딩
응답 필터: 응답 결과에 대한 암호화 작업, 서비스 시간 측정

메소드

destroy(): 필터 소멸 시 종료 작업을 수행
doFilter(): 요청,응답 시 호출되어 기능을 수행
init(): 필터 생성 시 호출되어 초기화 작업 수행

예시

사용자 정의 필터 클래스는 반드시 Filter 인터페이스를 구현해야함
브라우저 요청시 doFilter() 메서드의 매개변수로 request, response가 전달.
FilterChain 타입인 chain을 세번째 매개변수로 가짐.
chain.doFilter()메서드를 기준으로 위쪽에는 요청 필터 기능, 아래족은 응답 필터
chain.doFilter(request,response); → 다음 필터로 넘기는 작업

서블릿 관련 ListenerAPI

서블릿에서 발생하는 이벤트에 대해 적절한 처리를 해주는 여러가지 리스너를 제공

메소드들

1.
ServletContextAttributeListener
Context 객체에 속성 추가,제거,수정 이벤트 발생 시 처리
2.
HttpSessionListener
세션 객체의 생성,소멸 이벤트 발생 시 처리
3.
ServletRequestListener
클라이언트의 요청 이벤트 발생 시 처리
4.
ServletRequestAttributeListener
요청 객체에 속성 추가,제거,수정 이벤트 발생시 처리
5.
HttpSessionBindingLlistener
세션에 바인딩,언바인딩된 객체를 알려주는 이벤트 발생시 처리
6.
HttpSessionAttributeListener
세션에 속성 추가,제거,수정 이벤트 발생 시 처리
7.
ServletContextListener
컨텍스트 객체의 생성,소멸 이벤트 발생 시 처리
8.
HttpSessionActivationListener
세셔의 활성화,비활성화 이벤트 발생 시 처리

JSP

변환 과정

1.
변환 단계: JSP파일을 자바 파일로 변환
2.
컴파일 단계: 컨테이너는 변환된 자바 파일을 클래스 파일로 컴파일
3.
실행 단계: 컨테이너는 class파일을 실행하여 그 결과를 브라우저로 전송해 출력

Model2 방식

MVC 구성 요소와 기능

Controller : 서블릿이 컨트롤러 역하을 함
Model: 데이터베이스 연동과 같은 비즈니스 로직을 수행
View: JSP가 화면 기능을 담당, Model에서 처리한 결과를 화면에 표시

스프링 프레임워크

1.
제어 역행: 서블릿이나 빈 등을 개발자가 코드에서 생성하지 않고 프레임워크에서 직접 수행
2.
의존성 주입: 클래스 객체를 개발자가 코드에서 생성하지 않고 프레임워크가 생성
3.
관점 지향: 핵심 기능 외 부수 기능들을 분리 구현함으로써 모듈성을 증가시키는 방법

DI

setter를 이용한 DI기능 & 생성자를 이용한 DI 기능

AOP

메서드 안의 주기능과 보조 기능을 분리한 후 선택적으로 메서드에 적용해서 사용함
전체 코드에 흩어져있는 보조 기능을 하나의 장소에 모아서 관리할 수 있다.
aspect: 구현하고자 하는 보조기능
advice: aspect의 실제 구현체
joinpoint: advice를 적용하는 지점. 스프링은 method결합점만 제공
pointcut: advice가 적용되는 대상을 지정. 패키지이름,클래스이름,메서드이름을 정규식으로 지정하여 사용
target: advice가 적용되는 클래스
weaving: advice를 주기능에 적용하는 것
인터페이스들
MethodBeforeAdvice : 메서드 실행 전 실행
AfterReturningAdivce : 메서드 실행 후 실행
ThrowsAdvice : 메서드에서 예외 발생 시 실행
MethodInterceptor : 해당 메서드의 실행 전,후와 예외 발생 시 실행

스프링MVC기능

구성요소

DispatcherServlet: 클라이언트 요청을 전달받아, 해당 요처에 대한 컨트롤러를 선택하여 클라이언트 요청을 전달. 컨트롤러가 반환한 값을 View에 전달하여 알맞은 응답을 생성
HandlerMaping: 클라이언트가 요청한 URL을 처리할 컨트롤러를 지정
Controller: 클라이언트 요청을 처리한 후 그 결과를 DispatcherServlet에 전달
ModelAndView: 컨트롤러가 처리한 결과 및 뷰 선택에 필요한 정보를 저장
ViewResolver: 컨트롤러의 처리 결과를 전달할 뷰를 지정
View: 컨트롤러의 처리결과 화면을 생성
웹 브라우저 —> DispatcherServlet —> HandlerMapping —> Controller —> ModelAndView —> DispatcherServlet —> ViewResolver —> View —> DispatcherServlet —> 브라우저
DispatcherServlet : web.xml에 정의
HandlerMapper: web.xml에 정의
viewResolver: web.xml에 정의

스프링의 기능들

다중 파일 업로드
썸네일 이미지 사용
스프링 이메일
HTML형식 메일 보내기
스프링 인터셉터 사용
인터셉터 사용해 요청명에서 뷰이름 가져오기

스프링 동작과정