HTTPServlet
- HttpServlet을 상속하는 별도의 서블릿을 정의하고 이를 이용
- HttpServlet의 특징
① HttpServlet은 doGet( ), doPost( ) 메서드 등을 제공
→ 필요한 메서드를 오버라디드하여 처리 가능
② HttpServlet을 상속받은 클래스 객체는 톰캣과 같은 WAS의 내부에서 자동으로 객체 생성 및 관리됨
③ HttpServlet은 멀티 스레드에 의해서 동시에 실행될 수록 처리됨
서블릿 lifecycle
- 서블릿 ( Servlet ) : 웹 서버가 동적인 웹 페이지를 제공할 수 있도록 도와주는 애플리케이션
· 서블릿 : 서버 측에서 실행 ( 클라이언트의 요청을 받으면 서버에서 처리한 후, 응답으로는 결과값만 보내주는 구조 )
자바 파일(.java)을 컴파일한 클래스 파일(.class) 형태
· 서블릿 컨테이너 : 서블릿을 실행하고 관리해주는 런타임 서버로, Apache Tomcat이 대표적인 서블릿 컨테이너
▷ 서블릿의 특징
❶ 클라이언트의 요청에 대해 동적으로 작동하는 웹 애플리케이션 컴포넌트
❷ HTML을 사용하여 요청에 응답함
❸ Java Thread를 이용하여 동작함
❹ MVC 패턴에서 Controller로 이용됨
❺ HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속 받음
❻ HTML 변경 시 Servlet을 재컴파일해야 하는 단점
▷ 서블릿 동작 방식
서블릿은 HTTP 프로토콜을 사용하는 웹 환경이나 서버환경에서 쓰이는 기술이므로, HTTP에 대한 이해가 필요함( 참고자료 )
전체적인 흐름은 쓰레드를 배운 후, 공부하기로 하고 우선 대략적인 흐름만 공부하자
① 브라우저가 톰캣에 서블릿이 처리햐야 하는 특정한 경로 호출
② 톰캣은 해당 경로에 맞는 서블릿 클래스를 로딩하고 객체 생성 ( HttpServletRequest, HttpServletResponse 객체 )
서블릿의 init( ) 메서드를 이용해 서블릿 객체가 동작하기 전에 수행해야 하는 일들을 처리
③ 생성된 서블릿 객체는 브라우저의 요청에 대한 정보를 분석해 GET / POST 등의 정보와 함께 같이 전달되는 파라미터들을 HttpServletRequest 객체의 파라미터로 전달 받음, 이 과정에서 응답을 처리하는 데 필요한 기능들은 HttpServletResponse 객체로 전달 받음
④ 서블릿 내부에서는 GET / POST에 맞게 doGet( ) / doPost( ) 등의 메서드 실행
※ 이 후 동일한 주소의 호출이 있을 때 서블릿은 동일한 객체 하나만을 이용해서 처리함
⑤ 톰캣이 종료될 때는 서블릿의 destroy( ) 메서드 실행시켜 HttpServletRequest, HttpServletResponse 객체는 소멸됨
( 요약 )
❶ 서블릿의 객체는 경로에 맞게 하나만 생성
❷ 매번 호출 시에는 자동으로 doGet( ) / doPost( ) 메서드를 이용해 처리
SampleServlet을 생성 후, 실행해보자.
처음 실행 시, init( ) 메서드와 doGet( ) 메서드 실행되는 것을 확인 할 수 있음
이 상태에서 여러번 호출할 경우,
더 이상 init( ) 메서드는 호출되지 않고, doGet( ) 메서드만 호출됨
또한, this의 결과로 출력되는 @ 이하의 값이 동일한 것을 확인 할 수 있음
→ 서블릿의 객체는 경로에 맞게 하나만 생성된 후, 매번 호출 시 자동으로 doGet( ) 또는 doPost( ) 메서드를 이용해 처리됨을 확인할 수 있음
톰캣 종료시, destroy( ) 메서드가 호출됨
∴ init( )와 destroy( ) 메서드는 한 번씩만 호출, doGet( ), doPost( )는 동일한 객체를 이용해서 여러 번 호출됨
HttpServletRequest의 주요 기능
- HttpServletRequest는 HTTP 메시지 형태로 들어오는 요청에 대한 정보를 파악하는 주요 메서드
메서드 | 설명 |
String getParameter(name) | 파라미터 변수 name에 저장된 변수를 얻어내는 메서드로, 이때 변수의 값은 String으로 리턴됨 즉, key을 이용해서 value을 얻는 역할 만일, 해당 파라미터가 존재하지 않은 경우, null을 반환함 ( 항상 null 체크 주의하기 ) |
String[] getParameterValues(name) | 파라미터 변수 name에 저장된 모든 변수값을 얻어내는 메서드로, 이때 변수의 값은 String 배열로 리턴됨 → 주로 checkbox에서 사용됨 |
Enumeration getParameterNames() | 요청에 의해 넘어오는 모든 파라미터 변수를 java.util.Enumeration 타입으로 리턴함 |
void setAttribute( String name, Object obj ) | JSP로 전달할 데이터를 추가할 때 사용하는 메서드로, "key 이름", "value"의 형태로 데이터를 저장 key는 문자열로 지정, value는 모든 객체 타입 이용 가능 |
- RequestDispatcher 객체의 메서드
→ RequestDispatcher 객체 : 현재의 요청을 다른 서버의 자원에게 전달하는 용도로 사용
메서드 | 설명 |
RequestDispatcher getRequestDispatcher( String path ) | HttpServletRequest의 getRequestDispatcher( ) 메서드를 이용해 RequestDispatcher 타입의 객체를 구할 수 있음 |
void javax.servlet.RequestDispatcher.forward( ServletRequest request, ServletResponse response ) | 현재까지의 모든 응답(response) 내용은 무시하고, JSP가 작성하는 내용만을 브라우저로 전달 |
void javax.servlet.RequestDispatcher.include( ServletRequest request, ServletResponse response ) | 지금까지의 만들어진 응답(response) 내용 + JSP가 만든 내용을 브라우저로 전달 |
HttpServletResponse의 주요 기능
- HttpServletResponse는 쓰는 기능을 담당
메서드 | 설명 |
void setHeader(name, value) | 헤더 정보의 값을 수정하는 메서드로, name에 해당하는 헤더 정보를 value 값으로 설정함 |
void setContentType(type) | 웹 브라우저의 요청의 결과로 보일 페이지의 contentType을 설정함 |
void sendRedirect(url) | 페이지를 이동시키는 메서드로, url로 주어진 페이지로 제어가 이동함 |
- sendRedirect( ) 메서드로 경로를 지정하면, HTTP에서 'Location' 이름의 HTTP 헤더로 전달됨
→ 브라우저는 'Location'이 있는 응답을 받으면, 화면을 처리하는 대신에 주소창에 지정된 주소로 이동 후, 다시 호출
▷ TodoListController 구현
- 목록을 보여주는 기능 / GET방식
package org.zerock.w1.todo;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zerock.w1.todo.dto.TodoDTO;
import org.zerock.w1.todo.service.TodoService;
@WebServlet(name="todoListController", urlPatterns="/todo/list")
public class TodoListController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// 콘솔 창에 로그 출력
System.out.println("/todo/list");
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/todo/list.jsp");
rd.forward(req, res);
}
}
* list.jsp 파일 생성 ( /WEB-INF/todo/list )
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>List Page</h1>
</body>
</html>
▷ TodoRegisterController 구현
- 등록(입력) / GET 방식
package org.zerock.w1.todo;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TodoRegisterController
*/
@WebServlet(name="todoRegister", urlPatterns="/todo/register")
// 접근해야 할 웹 서비스의 위치를 알려주는 역할
public class TodoRegisterController extends HttpServlet {
// forwardJSP() 메서드 : 서블릿이 요청한 View(JSP Page)를 대신 실행하는 역할
// 파라미터 :
// jspFilePath ; 실행할 jsp 파일의 위치 -> WEB-INF 폴더 내 위치
// req - HttpServletRequest ; 요청 객체
// res - HttpServletResponse ; 응답 객체
// * JSP는 서블릿의 요청객체를 받아 데이터를 처리한 후 응답객체로 바로 웹 브라우저로 보냄
private void forwardJSP(
String jspFilePath,
HttpServletRequest req,
HttpServletResponse res ) throws ServletException, IOException {
// 예외 처리는 forwardJSP의 상위인 Servlet으로 보냄
// 메서드 구현부
RequestDispatcher rd = req.getRequestDispatcher(jspFilePath); // * 디버그 중단점
rd.forward(req, res);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// 콘솔창에 로그 출력
System.out.println("TodoRegisterController1//doGet()");
System.out.println("Method " + req.getMethod() + " 입력화면을 볼 수 있도록 조정"); // * 디버그 중단점
// String javax.servlet.http.HttpServletRequest.getMethod()
// -> register.jsp의 지정된 method 방식을 문자열로 출력하는 메서드
String jspPath = "/WEB-INF/todo/register.jsp";
// 실제 jsp 실행 결과를 마지막으로 처리하는 것이 서블릿임을 확인해보자.
// 확인용 tempReq와 tempRes객체 변수를 선언
HttpServletRequest tmpReq = req;
HttpServletResponse tmpRes = res;
forwardJSP(jspPath, tmpReq, tmpRes);
//forwardJSP(jspPath, req, res);
}
}
* register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Todo 등록</title>
</head>
<body>
<form action="/todo/register2" method="post" >
<input type="text" name="num1" value="1000" />
<input type="text" name="num2" value="2000" />
<button type="submit">등록처리</button>
</form>
</body>
</html>
▷ TodoRegisterController2 구현
- 등록(처리) / POST 방식
package org.zerock.w1.todo;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TodoRegisterController2
*/
@WebServlet(name="todoRegisterController2", urlPatterns="/todo/register2")
public class TodoRegisterController2 extends HttpServlet {
private static final long serialVersionUID = 1L;
// 서블릿으로 들어온 요청을 대신 처리(위임)하는 View 기능 호출
// req : 요청 변수 / res : 응답 변수
private void forwardJSP(
String jspFilePath,
HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException {
RequestDispatcher rd = req.getRequestDispatcher(jspFilePath);
rd.forward(req, res);
}
@Override
// 상속받은 메서드이므로 접근제어자를 'protected'로 설정
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// 로그 출력
System.out.println("TodoRegisterController2//doGet()");
System.out.println("Method " + req.getMethod() + " 입력화면을 볼 수 있도록 조정");
// View역할 jsp 파일의 위치
String jspPath = "/WEB-INF/todo/result.jsp";
forwardJSP(jspPath, req, res);
// String redirectUrl = "/todo/list";
// res.sendRedirect(redirectUrl);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// 로그 출력
System.out.println("TodoRegisterController2//doPost()");
System.out.println("Method " + req.getMethod() + " 입력화면을 볼 수 있도록 조정");
// View역할 jsp 파일의 위치
String jspPath = "/WEB-INF/todo/result.jsp";
forwardJSP(jspPath, req, res);
}
}
* result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>NUM1 ${param.num1}</h1>
<h1>NUM2 ${param.num2}</h1>
<h1>SUM ${
Integer.parseInt(param.num1) +
Integer.parseInt(param.num2)
}</h1>
</body>
</html>
'백엔드 > JSP' 카테고리의 다른 글
JSP : EL (0) | 2023.06.20 |
---|---|
JSP : JSTL (0) | 2023.06.19 |
웹 프로그래밍의 시작 (2) (0) | 2023.06.16 |
웹 프로그래밍의 시작 (1) (0) | 2023.06.14 |
JSP Servlet 기초 (8) : Session (0) | 2023.06.13 |