목차
1 Servlet 실습 개요
2 home.jsp
3 web.xml
4 HelloController
5 ByeController
6 GET 방식과 POST 방식
7 Servlet Life Cycle
8 web.xml 방식과 Annotation 방식
9 오늘 실습의 핵심 정리
1 Servlet 실습 개요
1) Servlet 실습의 흐름
(1) Servlet
Servlet은 Java 클래스를 이용해서 웹 요청을 처리하는 서버 프로그램이다.
JSP가 HTML 화면 안에 Java 코드를 섞어 작성하는 방식이라면, Servlet은 Java 클래스에서 request와 response 객체를 이용해 요청과 응답을 처리한다.
(2) 오늘 실습의 목적
오늘은 JSP 파일에서 링크나 form 요청을 보내고, 그 요청을 Servlet이 받아 처리하는 흐름을 실습했다.
이전에는 mycontroller.jsp 같은 JSP 파일이 Controller 역할을 했지만, 이번 실습부터는 Java Servlet 클래스가 Controller 역할을 담당하기 시작했다.
(3) 전체 흐름
home.jsp에서 사용자가 링크나 버튼을 누르면 HelloServlet.do 또는 ByeServlet.do로 요청이 이동한다.
이 요청은 web.xml 또는 @WebServlet 설정에 따라 특정 Servlet 클래스로 연결되고, Servlet은 doGet 또는 doPost 메소드를 실행해 응답을 만든다.
2 home.jsp
1) home.jsp의 역할
(1) 요청을 보내는 시작 화면
home.jsp는 사용자가 Servlet으로 요청을 보내는 시작 화면이다.
링크와 form을 통해 GET 방식과 POST 방식 요청을 각각 테스트할 수 있다.
(2) Hello 링크
Hello 링크는 HelloServlet.do?command=hello 주소로 이동한다.
URL 뒤에 command=hello가 붙어 있으므로 GET 방식으로 command 값을 Servlet에 전달한다.
(3) hello post form
hello(post) 버튼은 form을 통해 HelloServlet.do로 POST 요청을 보낸다.
hidden input에 command=helloPost 값이 들어 있기 때문에 화면에는 보이지 않지만 Servlet으로 command 값이 전달된다.
(4) bye post form
bye(post) 버튼은 ByeServlet.do로 POST 요청을 보낸다.
이 요청은 @WebServlet으로 매핑된 ByeController에서 처리된다.
3 web.xml
1) web.xml의 역할
(1) 배포 서술자
web.xml은 웹 애플리케이션의 설정 정보를 작성하는 파일이다.
어떤 페이지를 시작 페이지로 사용할지, 어떤 Servlet을 어떤 URL과 연결할지 등을 설정할 수 있다.
(2) display-name
display-name은 웹 애플리케이션의 이름을 설정하는 부분이다.
현재 프로젝트에서는 Jsp04_HelloServlet이라는 이름으로 설정되어 있다.
(3) welcome-file-list
welcome-file-list는 웹 애플리케이션에 처음 접속했을 때 보여줄 시작 페이지 후보를 지정한다.
index.html, index.jsp, home.jsp 같은 파일을 시작 페이지로 사용할 수 있다.
2) context-param
(1) context-param의 의미
context-param은 웹 애플리케이션 전체에서 사용할 수 있는 전역 초기화 파라미터이다.
특정 Servlet 하나가 아니라 애플리케이션 전체 범위에서 공유할 수 있는 설정값이다.
(2) url 값
이번 실습에서는 url이라는 이름으로 Oracle DB 연결 주소를 설정했다.
Servlet에서는 ServletContext를 통해 이 값을 가져올 수 있다.
(3) 사용하는 이유
DB URL처럼 여러 곳에서 공통으로 사용할 수 있는 값은 코드에 직접 쓰는 것보다 설정 파일에 분리해두는 것이 관리하기 좋다.
3) servlet과 servlet-mapping
(1) servlet 태그
servlet 태그는 Servlet 이름과 실제 Java 클래스의 위치를 연결한다.
여기서는 HelloServlet이라는 이름을 com.hello.controller.HelloController 클래스와 연결했다.
(2) servlet-mapping 태그
servlet-mapping 태그는 사용자가 요청할 URL과 Servlet 이름을 연결한다.
/HelloServlet.do로 요청이 들어오면 HelloServlet이라는 이름의 Servlet이 실행된다.
(3) url-pattern
url-pattern은 브라우저에서 접근할 Servlet 주소이다.
사용자는 Java 클래스명을 직접 요청하는 것이 아니라 HelloServlet.do 같은 주소로 요청한다.
4) init-param
(1) init-param의 의미
init-param은 특정 Servlet에서만 사용할 초기화 파라미터이다.
Servlet 객체가 생성되고 init 메소드가 실행될 때 이 값을 사용할 수 있다.
(2) driver 값
이번 실습에서는 driver라는 이름으로 oracle.jdbc.OracleDriver 값을 설정했다.
HelloController의 init 메소드에서 config.getInitParameter("driver")로 가져올 수 있다.
(3) context-param과 차이
context-param은 애플리케이션 전체에서 사용하는 값이고, init-param은 특정 Servlet에서 사용하는 값이다.
즉, 사용 범위가 다르다.
4 HelloController
1) HelloController의 역할
(1) HttpServlet 상속
HelloController는 HttpServlet을 상속받은 Servlet 클래스이다.
HttpServlet을 상속받으면 HTTP 요청을 처리하는 doGet, doPost 같은 메소드를 사용할 수 있다.
(2) Controller 역할
HelloController는 home.jsp에서 보낸 HelloServlet.do 요청을 처리한다.
요청 파라미터를 읽고, 응답 화면을 직접 만들어 클라이언트에게 전달한다.
2) 생성자
(1) 생성자 실행
HelloController 생성자는 Servlet 객체가 처음 만들어질 때 실행된다.
콘솔에 "servlet 생성자!"를 출력하여 객체 생성 시점을 확인할 수 있다.
(2) 생성자의 의미
생성자는 객체가 생성될 때 가장 먼저 실행되는 부분이다.
Servlet에서도 객체가 만들어지는 순간을 확인할 수 있다.
3) init 메소드
(1) init의 역할
init 메소드는 Servlet 객체가 생성된 후 초기화될 때 실행된다.
Servlet이 본격적으로 요청을 처리하기 전에 필요한 설정값을 준비할 수 있다.
(2) ServletConfig
ServletConfig는 특정 Servlet의 초기화 정보를 담는 객체이다.
init-param 값을 가져올 때 사용한다.
(3) context-param 가져오기
config.getServletContext().getInitParameter("url")을 사용하면 web.xml의 context-param 값을 가져올 수 있다.
이 값은 애플리케이션 전체에서 사용할 수 있는 전역 설정값이다.
(4) init-param 가져오기
config.getInitParameter("driver")를 사용하면 web.xml의 init-param 값을 가져올 수 있다.
이 값은 HelloController Servlet에 설정된 초기화 값이다.
4) doGet 메소드
(1) doGet
doGet은 GET 방식 요청이 들어왔을 때 실행되는 메소드이다.
home.jsp의 Hello 링크를 클릭하면 GET 방식으로 HelloServlet.do 요청이 발생한다.
(2) doPost 호출
실습 코드에서는 doGet 안에서 doPost(request, response)를 호출한다.
이렇게 하면 GET 요청이 들어와도 실제 응답 처리 로직은 doPost에서 공통으로 처리할 수 있다.
(3) 사용하는 이유
GET과 POST의 처리 내용이 거의 같을 때 중복 코드를 줄일 수 있다.
다만 실제 프로젝트에서는 요청 방식에 따라 처리 로직을 분리해야 할 때도 있다.
5) doPost 메소드
(1) doPost
doPost는 POST 방식 요청이 들어왔을 때 실행되는 메소드이다.
home.jsp의 hello(post) 버튼을 누르면 HelloServlet.do로 POST 요청이 전달된다.
(2) 인코딩 설정
request.setCharacterEncoding("UTF-8")은 요청 데이터의 한글 깨짐을 방지하기 위해 사용한다.
response.setContentType("text/html; charset=UTF-8")은 응답 화면의 형식과 문자 인코딩을 설정한다.
(3) command 값 받기
request.getParameter("command")를 사용해 요청으로 전달된 command 값을 가져온다.
GET 방식에서는 URL 뒤의 command=hello 값을 가져오고, POST 방식에서는 hidden input의 command=helloPost 값을 가져온다.
(4) PrintWriter
response.getWriter()로 PrintWriter 객체를 얻는다.
PrintWriter는 Servlet에서 HTML 응답을 직접 작성할 때 사용한다.
(5) HTML 응답 출력
out.print를 사용해 h1, h2, h3, a 태그, script 태그 등을 직접 출력한다.
이 방식은 Servlet에서 직접 HTML 화면을 만드는 방법이다.
(6) 반복 출력
for문을 사용해 command 값과 숫자를 반복 출력한다.
Java 로직을 이용해 동적인 HTML 응답을 만들 수 있다는 것을 확인할 수 있다.
6) destroy 메소드
(1) destroy
destroy는 Servlet 객체가 소멸될 때 실행되는 메소드이다.
서버가 종료되거나 Servlet이 제거될 때 호출될 수 있다.
(2) 사용하는 이유
Servlet이 사용하던 자원을 정리할 때 사용할 수 있다.
이번 실습에서는 콘솔 출력으로 destroy 실행 시점을 확인했다.
5 ByeController
1) ByeController의 역할
(1) Annotation 방식 Servlet
ByeController는 web.xml에 직접 등록하지 않고 @WebServlet을 사용해 URL을 매핑했다.
@WebServlet("/ByeServlet.do")라고 작성하면 ByeServlet.do 요청이 ByeController로 연결된다.
(2) HttpServlet 상속
ByeController도 HttpServlet을 상속받는다.
따라서 doGet과 doPost를 오버라이딩해서 요청을 처리할 수 있다.
2) doPost와 doGet
(1) doPost
home.jsp의 bye(post) form은 POST 방식으로 ByeServlet.do에 요청을 보낸다.
이때 ByeController의 doPost 메소드가 먼저 실행된다.
(2) doGet 호출
doPost 안에서 doGet(request, response)을 호출한다.
따라서 POST 요청이 들어와도 doPost 실행 후 doGet까지 이어서 실행된다.
(3) 실행 확인
콘솔에 "doPost 호출!!"과 "doGet 호출!!"이 출력된다.
이를 통해 POST 요청이 들어왔을 때 doPost에서 doGet으로 흐름이 이어지는 것을 확인할 수 있다.
6 GET 방식과 POST 방식
1) GET 방식
(1) GET 요청
GET 방식은 URL 뒤에 데이터를 붙여서 요청하는 방식이다.
home.jsp의 Hello 링크는 HelloServlet.do?command=hello 형태로 command 값을 전달한다.
(2) 특징
데이터가 주소창에 보이기 때문에 검색이나 조회 요청에 많이 사용된다.
하지만 중요한 정보나 비밀번호 같은 데이터 전송에는 적합하지 않다.
2) POST 방식
(1) POST 요청
POST 방식은 form 데이터를 request body에 담아 전송하는 방식이다.
home.jsp의 hello(post), bye(post) 버튼은 form을 통해 POST 요청을 보낸다.
(2) 특징
URL에 데이터가 직접 보이지 않는다.
로그인, 글 작성, 정보 수정처럼 서버에 데이터를 전달하는 작업에 주로 사용된다.
3) doGet과 doPost
(1) doGet
GET 방식 요청이 들어오면 doGet 메소드가 실행된다.
URL 파라미터로 전달된 값을 request.getParameter로 받을 수 있다.
(2) doPost
POST 방식 요청이 들어오면 doPost 메소드가 실행된다.
form input 값도 request.getParameter로 받을 수 있다.
(3) 공통 처리
doGet에서 doPost를 호출하거나, doPost에서 doGet을 호출하면 두 요청 방식을 하나의 메소드에서 공통 처리할 수 있다.
오늘 실습에서는 이 흐름을 통해 GET과 POST 요청의 실행 순서를 확인했다.
7 Servlet Life Cycle
1) Servlet Life Cycle의 개념
(1) Life Cycle
Servlet Life Cycle은 Servlet 객체가 생성되고, 초기화되고, 요청을 처리하고, 소멸되는 전체 흐름이다.
이 흐름은 개발자가 직접 관리하는 것이 아니라 Servlet Container가 관리한다.
2) 실행 순서
(1) 생성자
Servlet 객체가 처음 만들어질 때 생성자가 실행된다.
실습에서는 "servlet 생성자!"가 콘솔에 출력된다.
(2) init
Servlet 객체가 초기화될 때 init 메소드가 실행된다.
web.xml의 init-param이나 context-param 같은 설정값을 확인할 수 있다.
(3) doGet 또는 doPost
클라이언트 요청이 들어올 때마다 요청 방식에 따라 doGet 또는 doPost가 실행된다.
GET 요청이면 doGet, POST 요청이면 doPost가 호출된다.
(4) destroy
Servlet 객체가 소멸될 때 destroy 메소드가 실행된다.
서버 종료나 Servlet 변경 시점에 실행될 수 있다.
3) Life Cycle을 배우는 이유
(1) Servlet 실행 흐름 이해
Servlet은 요청이 올 때마다 매번 새로 만들어지는 것이 아니다.
Container가 Servlet 객체를 관리하고, 요청이 들어올 때마다 doGet이나 doPost를 실행한다.
(2) 초기화 작업 위치 이해
한 번만 실행하면 되는 설정 작업은 init에서 처리할 수 있다.
요청마다 실행해야 하는 작업은 doGet이나 doPost에서 처리해야 한다.
8 web.xml 방식과 Annotation 방식
1) web.xml 방식
(1) 설정 파일 기반 매핑
web.xml 방식은 Servlet 클래스와 URL 매핑 정보를 web.xml에 작성하는 방식이다.
HelloController는 web.xml에 servlet과 servlet-mapping을 작성해서 HelloServlet.do와 연결했다.
(2) 장점
설정 정보를 한 파일에서 관리할 수 있다.
Servlet 클래스 코드와 URL 설정을 분리할 수 있다.
2) Annotation 방식
(1) @WebServlet
Annotation 방식은 Servlet 클래스 위에 @WebServlet을 작성해 URL을 직접 매핑하는 방식이다.
ByeController는 @WebServlet("/ByeServlet.do")를 사용해 ByeServlet.do 요청과 연결했다.
(2) 장점
web.xml에 별도 설정을 작성하지 않아도 된다.
Servlet 클래스에서 바로 어떤 URL과 연결되는지 확인할 수 있다.
3) 두 방식의 차이
(1) 설정 위치
web.xml 방식은 설정 파일에서 URL 매핑을 관리한다.
Annotation 방식은 Java 클래스 안에서 URL 매핑을 관리한다.
(2) 오늘 실습의 의미
HelloController는 web.xml 방식으로 매핑하고, ByeController는 Annotation 방식으로 매핑했다.
이를 통해 Servlet URL Mapping을 설정하는 두 가지 방법을 비교할 수 있었다.
9 오늘 실습의 핵심 정리
1) JSP에서 Servlet으로 흐름 확장
(1) 이전 실습과 차이
이전에는 JSP 파일이 Controller 역할을 했다.
오늘은 Java 클래스인 Servlet이 요청을 처리하면서 더 본격적인 MVC 구조로 넘어가는 기초를 배웠다.
(2) Servlet Controller
Servlet은 사용자의 요청을 받고, 필요한 로직을 실행하고, 응답을 만드는 역할을 할 수 있다.
앞으로는 JSP보다 Servlet이 Controller 역할을 맡는 구조가 더 자연스러워질 수 있다.
2) URL Mapping 이해
(1) 요청 주소와 클래스 연결
사용자는 HelloController라는 Java 클래스명을 직접 요청하지 않는다.
HelloServlet.do 같은 URL로 요청하면 설정에 따라 해당 Servlet 클래스가 실행된다.
(2) Mapping의 필요성
URL Mapping은 사용자의 요청 주소와 서버의 Java 클래스를 연결해주는 역할을 한다.
web.xml 또는 @WebServlet으로 설정할 수 있다.
3) GET과 POST 요청 처리
(1) GET 요청
링크를 클릭하면 GET 방식 요청이 발생한다.
URL 뒤에 붙은 command 값을 Servlet에서 request.getParameter로 받을 수 있었다.
(2) POST 요청
form을 제출하면 POST 방식 요청이 발생한다.
hidden input에 담긴 command 값도 Servlet에서 request.getParameter로 받을 수 있었다.
4) Servlet Life Cycle 이해
(1) 생성자와 init
Servlet 객체가 생성될 때 생성자가 실행되고, 초기화 시점에 init이 실행된다.
이때 설정값을 읽어올 수 있다.
(2) doGet과 doPost
요청 방식에 따라 doGet 또는 doPost가 실행된다.
Servlet의 실제 요청 처리는 대부분 이 메소드들 안에서 이루어진다.
(3) destroy
Servlet이 종료될 때 destroy가 실행된다.
Servlet 객체의 마지막 정리 단계이다.
5) 오늘 배운 점
(1) Servlet의 역할
Servlet은 단순한 Java 클래스가 아니라 웹 요청을 처리하는 서버 측 Controller 역할을 할 수 있다는 것을 배웠다.
(2) 설정값 사용
web.xml의 context-param과 init-param을 통해 설정값을 Servlet에서 가져올 수 있었다.
전역 설정과 Servlet별 설정의 차이를 이해했다.
(3) 응답 직접 작성
PrintWriter를 사용해 Servlet에서 HTML 응답을 직접 작성할 수 있었다.
다만 HTML을 Java 코드 안에서 문자열로 작성해야 하므로 화면이 복잡해질수록 JSP와 역할을 나누는 것이 더 좋다는 점도 느낄 수 있었다.
(4) 앞으로의 흐름
오늘 실습은 Servlet 기반 MVC로 넘어가기 위한 기초 단계였다.
앞으로는 Servlet이 Controller 역할을 맡고, JSP는 View 역할에 집중하는 구조로 확장될 수 있을 것 같다.