티스토리 뷰
1. 요청 포워딩 ( request forwarding )
- 사용자의 요청을 받은 서블릿 또는 JSP에서 또 다른 컴포넌트( 서블릿, JSP, html )로 요청을 위임할 수 있는 방법이다.
- 포워드( forward )하는 이유는 직접 요청받은 서블릿 또는 JSP에서 모든 작업을 처리하지 않고, 모듈화시킨 다른 컴포넌트로 요청을 위임하여 재사용성도 높이고 유지보수를 쉽게 해주기 위해서다.
- 보통 요청을 처리하는 웹 컴포넌트는 FrontController 패턴을 적용한 서블릿으로,
- 응답을 처리하기 위한 웹 컴포넌트 JSP로 구현한다.
- 이런 구조를 MVC( Model, View, Controller ) 패턴이라고 한다.
- + MVC 패턴 ( == 모델2 아키텍쳐 ) : 웹개발에서 백엔드의 최상의 구현방식
- + M == Model ( 비즈니스 수행결과 데이터 ) : 공유데이터 영역
- + V == View ( 비즈니스 데이터가 반영된 응답화면 ) : 웹 컴포넌트 - JSP
- + C == Controller ( 요청처리 흐름을 제어하는 자 ) : 웹 컴포넌트 – FrontController
- + 하나의 요청이 처리되어 응답이 웹 브라우저로 나가기까지 여러 개의 웹 컴포넌트( Servlet, JSP )를 거쳐서 처리될 수 있다.
[ 1 -1. MVC 패턴 - 요청 포워딩 ] (*****)
package org.zerock.myapp;
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;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
// MVC 패턴의 Controller의 역할을 한다.
@WebServlet("/Request")
public class RequestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req, res) invoked.");
// 비지니스 로직 수행
// 비지니스 데이터 ( == Model ) : request Scope에 공유 데이터 올리기
req.setAttribute("name", "홍길동");
req.setAttribute("address", "서울");
// === 응답을 만들어낼 웹 컴포넌트( Servlet / JSP )에 요청을 위임 ( View ) ===
// forward : 요청을 위임
RequestDispatcher dis = req.getRequestDispatcher("/Response");
dis.forward(req, res);
log.info("Forward request to the /Response");
} // service
} // end class
[ 1 - 2. MVC 패턴 - 응답하는 웹 컴포넌트 생성 ] (*****)
package org.zerock.myapp;
import java.io.IOException;
import java.io.PrintWriter;
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 lombok.Cleanup;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@WebServlet("/Response")
public class ResponseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req, res) invoked.");
// 1. 공유데이터 영역( Request Scope )에서 Model 데이터 얻어내기
String name = (String) req.getAttribute("name");
String address = (String) req.getAttribute("address");
log.info("Model - name : {}, address : {}", name, address);
// ======================================================
// 응답문서 준비
// 2. Model을 이용한 응답문서의 생성 및 전송
res.setContentType("text/html; charset=utf8");
@Cleanup
PrintWriter out = res.getWriter();
out.println("<html><head></head><body>");
out.println("<h1> /Response </h1>");
out.println("<hr>");
out.println("<h2> 1. name 값 : " + name + "</h2>");
out.println("<h2> 2. address 값 : " + address + "</h2>");
out.println("</body></html>");
out.flush();
} // service
} // end class
[ 2 - 1. Redirect - 자신이 처리할 것이 아닐때 재요청하기 + 쿼리 스트링 이용하기 ] (***)
package org.zerock.myapp;
import java.io.IOException;
import java.net.URLEncoder;
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 javax.servlet.http.HttpSession;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@WebServlet("/RequestRedirect")
public class RequestRedirectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req, res) invoked.");
// 비지니스 로직 수행
// 1. 비지니스 데이터 ( == Model ) : request Scope에 속성 바인딩
// req.setAttribute("name", "홍만만");
// req.setAttribute("address", "주소");
// 1 - 2. 섹션 영역으로 공유 데이터 올려 놓기
// HttpSession sess = req.getSession();
// sess.setAttribute("name", "난섹션이다.");
// sess.setAttribute("address", "주소");
// 2. Redirect 응답 전송
String queryStr = "?name="+URLEncoder.encode("홍길동","utf8")+"&address="+URLEncoder.encode("서울","utf8");
// URLEncoder.encode("문자열","utf8"); ( 값부분만 바꿔주면 된다. )
// 이 방법을 사용할 경우 URL에 name과 address가 보여진다.
// 왜 URL 전체를 한번에 인코딩하지 않은 이유는, 그렇게 되면 특수문자까지도 인코딩으로 바뀌기때문이다.
// 그렇기 때문에 값부분만 인코딩해줘야 한다.(***)
res.sendRedirect("/ResponseRedirect" + queryStr); // (***)
// + 이때 queryStr는 한글을 허용하지 않는 언어이기에, utf8로 URLEncoding을 해야 한다.
log.info("Succeed to send a Redirection to the web browser");
// Redirect의 경우 URL이 위임한 곳으로 변경된다.
} // service
} // end class
[ 2 - 1. Redirect - 응답하기 ]
package org.zerock.myapp;
import java.io.IOException;
import java.io.PrintWriter;
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 javax.servlet.http.HttpSession;
import lombok.Cleanup;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@WebServlet("/ResponseRedirect")
public class ResponseRedirectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req, res) invoked.");
// 1. 공유데이터 영역( Request Scope )에서 Model 데이터 얻어내기
// String name = (String) req.getAttribute("name");
// String address = (String) req.getAttribute("address");
// 1 - 2. 공유데이터 영역( Session Scope )에서 Model 데이터 얻어내기
// HttpSession sess = req.getSession();
// String name = (String) sess.getAttribute("name");
// String address = (String) sess.getAttribute("address");
// 1 - 3. 전송파라미터로 얻기
req.setCharacterEncoding("UTF-8");
String name = req.getParameter("name");
String address = req.getParameter("address");
log.info("Model - name : {}, address : {}", name, address);
// ======================================================
// 2. Model을 이용한 응답문서의 생성 및 전송
res.setContentType("text/html; charset=utf8");
@Cleanup
PrintWriter out = res.getWriter();
out.println("<html><head></head><body>");
out.println("<h1> /ResponseRedirect </h1>");
out.println("<hr>");
out.println("<h2> 1. name 값 : " + name + "</h2>");
out.println("<h2> 2. address 값 : " + address + "</h2>");
out.println("</body></html>");
out.flush();
// ======================================================
// Redirect는 name과 address가 모두 null로 나오는데,
// 그 이유는 redirect는 재요청을 응답으로 보내버리기 때문에
// Request Scope에 올려 놓았던 name과 address가 없어져 버린다.
// 그렇기에 출력하기 위해서는 다른 방법을 사용해야 한다.
// ======================================================
} // service
} // end class
[ 3. 인코딩과 디코딩 ]
package org.zerock.myapp;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.DisplayNameGenerator.Standard;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@NoArgsConstructor
@Log4j2
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class URLEncodingDecodingTests {
@Test
@Order(1)
@DisplayName("testURLEncoder")
@Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
void testURLEncoder() throws UnsupportedEncodingException {
log.trace("testURLEncoder() invoked.");
String str1 = "한글"; // 한글은 utf8로 인코딩된다.
String str2 = "ABCDEFG1234567"; // 영어와 숫자는 인코딩해도 변함이 없다.
String str3 = "ABCDEFG 1234567"; // 공백은 +로 바뀐다.
// 인코딩하기
String urlencodedStr = URLEncoder.encode(str1, "utf8");
log.info("\t + urlencodedStr : {}", urlencodedStr);
// 디코딩하기
// String urldecoedeStr = URLDecoder.decode(urlencodedStr, StandardCharsets.UTF_8);
String urldecoedeStr = URLDecoder.decode(urlencodedStr, "utf8");
log.info("\t + urldecoedeStr : {}", urldecoedeStr);
}// testURLEncoder
} // end class
[ 4. MVC 패턴으로 FrontController 바꾸기 ] (*****)
package org.zerock.myapp;
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;
import org.zerock.myapp.domain.EmpDTO;
import org.zerock.myapp.exception.BizProcessException;
import org.zerock.myapp.service.DeleteService;
import org.zerock.myapp.service.InsertService;
import org.zerock.myapp.service.SelectService;
import org.zerock.myapp.service.Service;
import org.zerock.myapp.service.UnknownReqService;
import org.zerock.myapp.service.UpdateService;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@WebServlet("*.do") // 다른 서블릿이 *.do로 매핑하고 있으면 오류발생할 수 있다.
public class FrontControllerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req, res) invoked.");
// =======================================
// 1. ContextPath와 URL/URI(요청)확인
// =======================================
String contextPath = req.getContextPath();
String requestURI = req.getRequestURI();
String requestURL = req.getRequestURL().toString();
// =======================================
log.info("\t + 0. contextPath : {}", contextPath); // /maven01 or /myapp
// + contextPath가 그냥 /(루트)일 경우 빈문자열이기에, 출력되지 않는다.
// + 즉 그냥 루트일 경우에는 substring할 필요 없이 URI를 사용하면 된다.
// =======================================
log.info("\t + 1. requestURI : {}", requestURI); // /*.do
log.info("\t + 2. requestURL : {}", requestURL); // http://localhost:8080/*.do
// 현재 모든 URL 중 .do로 끝나는 모든 요청을 여기에 집중시키고 있다.
// =======================================
// substring으로 URI에서 컨텍스트 페스를 제외한 문자열을 돌려준다.
// String command = requestURI.substring(contextPath.length());
String command = requestURI;
log.info("\t + 3. command : {}", command); // /*.do
// + command는 contextPath가 그냥 루트일 경우 URI와 동일하게 나온다.
// =======================================
// 2. 전송파라미터를 DTO객체로 수집 (*****) <----- 여기서부터 시작해도 된다.
// =======================================
// req.setCharacterEncoding("UTF-8"); 은 이미 필터에서 수행되었다.
String empno = req.getParameter("empno");
String ename = req.getParameter("ename");
String sal = req.getParameter("sal");
String deptno = req.getParameter("deptno");
// 전송파라미터를 하나씩 계속 전달하면, 너무 비효율적이기에 DTO 객체에 저장해서 사용한다.
// 수집된 각 전송 파라미터를 DTO 객체에 저장 ( 이제, 이 객체를 전달하면 된다. )
// DTO 객체는 웹3계층(표현/비지니스/영속 계층)의 뒤로 전달되면서 사용된다.
EmpDTO dto = new EmpDTO();
// null이 아니고 빈문자열도 아니어야 한다.
if( empno != null && !"".equals(empno) ) { dto.setEmpno(Integer.parseInt(empno)); } // if - empno
if( ename != null && !"".equals(ename) ) { dto.setEname(ename); } // if - ename
if( sal != null && !"".equals(sal) ) { dto.setSal(Double.parseDouble(sal)); } // if - sal
if( deptno != null && !"".equals(deptno) ) { dto.setDeptno(Integer.parseInt(deptno)); } // if - deptno
// + 전송파라미터는 String으로 들어오기에, 필요시 형변환을 해줘야 한다.
// =======================================
// 3. 요청 URI에 따라, command(요청유형) 결정
// =======================================
// Request Scope 공유 데이터 영역에 DTO 객체를 속성으로 바인딩
// * 주의 * : 모든 Service 객체의 비지니스 로직 수행에 필요한 전송파라미터를
// 전달해주는 DTO 객체를, 또 다른 공유데이터 영역인 "Request Scope"을 통해 전달
// ( accessed by HttpServletRequest )
// -> 비지니스 로직 수행에 필요한 데이터를 가지고 있는 것이 DTO 객체이기 때문에 이를 넘겨줘야 한다.
req.setAttribute(Service.DTO, dto);
// req.getAttributeNames();
// 이를 통해서 공유된 데이터의 이름을 파악할 수 있다.
// =======================================
// 4. command 에 따라, 적합한 비지니스 서비스 객체 선택 및 비지니스 로직 수행
// =======================================
try {
// command(요청유형)에 따라, 각 요청을 처리하는 서비스 객체의 생성 및 비지니스 로직 수행(execute 메소드)
// * 주의 * : 비지니스 로직 수행 결과 데이터는, 공유데이터 영역인 "Application Scope"(accessed by ServletContext)에 바인딩
switch( command ) {
// 아래의 모든 service 객체에 필요한 전송파라미터를 전달해주는
// DTO 객체는 3번째 공유데이터 영역인 Request Scope을 통해 전달된다.
case "/insert.do":
log.info("\t + 4. insert request.");
new InsertService().execute(req, res); // 객체 생성 후 메소드 실행
break;
case "/update.do":
log.info("\t + 4. update request.");
new UpdateService().execute(req, res); // 객체 생성 후 메소드 실행
break;
case "/delete.do":
log.info("\t + 4. delete request.");
new DeleteService().execute(req, res); // 객체 생성 후 메소드 실행
break;
case "/select.do":
log.info("\t + 4. select request.");
new SelectService().execute(req, res); // 객체 생성 후 메소드 실행
break;
default : // == if-else
log.info("\t + 4. unknown request.");
new UnknownReqService().execute(req, res); // 객체 생성 후 메소드 실행
break;
} // switch
} catch(BizProcessException e) {
;;
} // try - catch
// =======================================
// 응답 문서 준비 --> /View로 이동
// =======================================
// =======================================
// MVC 패턴 적용
// =======================================
RequestDispatcher dis = req.getRequestDispatcher("/View");
dis.forward(req, res);
log.info("Forwarded request into /View");
} // service
} // end class
[ 4 - 2. Service 변경 -> Application Scope에서 Request 공유영역으로 바꾸기 ]
package org.zerock.myapp.service;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zerock.myapp.domain.EmpDTO;
import org.zerock.myapp.exception.BizProcessException;
import org.zerock.myapp.persistence.EmpDAO;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
public class DeleteService implements Service {
@Override
public void execute(HttpServletRequest req, HttpServletResponse res) throws BizProcessException {
log.trace("execute(req, res) invoked.");
try {
EmpDTO dto = (EmpDTO) req.getAttribute(Service.DTO);
EmpDAO dao = new EmpDAO();
int deleteRows = dao.delete(dto);
// req.getServletContext().setAttribute(Service.BIZ_RESULT, deleteRows);
// 위는 Application Scope에 올려 놓은 것이다.
req.setAttribute(Service.BIZ_RESULT, deleteRows); // Request Scope에 올려 놓았다.
log.info("\t + insertRows : {}", deleteRows);
} catch(SQLException e) {
throw new BizProcessException(e);
} // try - catch
} // execute
} // end class
package org.zerock.myapp.service;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zerock.myapp.domain.EmpDTO;
import org.zerock.myapp.exception.BizProcessException;
import org.zerock.myapp.persistence.EmpDAO;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
public class InsertService implements Service {
@Override
public void execute(HttpServletRequest req, HttpServletResponse res) throws BizProcessException {
log.trace("execute(req, res) invoked.");
try {
EmpDTO dto = (EmpDTO) req.getAttribute(Service.DTO);
EmpDAO dao = new EmpDAO();
int insertRows = dao.insert(dto);
// req.getServletContext().setAttribute(Service.BIZ_RESULT, insertRows);
// 위는 Application Scope에 올려 놓은 것이다.
req.setAttribute(Service.BIZ_RESULT, insertRows); // Request Scope에 올려 놓았다.
log.info("\t + insertRows : {}", insertRows);
} catch(SQLException e) {
throw new BizProcessException(e);
} // try - catch
} // execute
} // end class
package org.zerock.myapp.service;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zerock.myapp.domain.EmpVO;
import org.zerock.myapp.exception.BizProcessException;
import org.zerock.myapp.persistence.EmpDAO;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
// select.do 요청을 실제 처리할 비지니스 로직
public class SelectService implements Service {
@Override
public void execute(HttpServletRequest req, HttpServletResponse res) throws BizProcessException {
log.trace("execute(req, res) invoked.");
// =======================================
// 실제 로직
// =======================================
try {
// 영속계층에서 데이터를 가지고 오는 DAO객체 생성
EmpDAO dao = new EmpDAO();
// + dao의 selectAll메소드를 한 결과를 반환한다.
// + 즉, sql문대로 실행한 결과를 List<EmpVO>타입으로 반환한다.
// 비지니스 수행결과 데이터 발생
List<EmpVO> list = dao.selectAll();
// 공유데이터 영역에 비지니스 제이터를 속성 바인딩시킨다.
// ServletContext sc = req.getServletContext(); // Application scope 객체
// sc.setAttribute(Service.BIZ_RESULT, list); // 인터페이스에서 정적객체 가지고 오기
// 위는 Application Scope에 올려 놓은 것이다.
req.setAttribute(Service.BIZ_RESULT, list); // Request Scope에 올려 놓았다.
} catch(SQLException e) {
throw new BizProcessException(e);
} // try - catch
} // execute
} // end class
package org.zerock.myapp.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zerock.myapp.exception.BizProcessException;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
// 잘못된 요청(command)에 대한 처리를 수행하는 서비스 객체
public class UnknownReqService implements Service {
@Override
public void execute(HttpServletRequest req, HttpServletResponse res) throws BizProcessException {
log.trace("execute(req, res) invoked.");
// ServletContext sc = req.getServletContext(); // Application scoe 객체
// sc.setAttribute(Service.BIZ_RESULT, "Bad Request"); // 인터페이스에서 정적객체 가지고 오기
// 위는 Application Scope에 올려 놓은 것이다.
req.setAttribute(Service.BIZ_RESULT, "Bad Request"); // Request Scope에 올려 놓았다.
} // execute
} // UnknownReqService
package org.zerock.myapp.service;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zerock.myapp.domain.EmpDTO;
import org.zerock.myapp.domain.EmpVO;
import org.zerock.myapp.exception.BizProcessException;
import org.zerock.myapp.persistence.EmpDAO;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
public class UpdateService implements Service {
@Override
public void execute(HttpServletRequest req, HttpServletResponse res) throws BizProcessException {
log.trace("execute(req, res) invoked.");
try {
EmpDTO dto = (EmpDTO) req.getAttribute(Service.DTO);
EmpDAO dao = new EmpDAO();
int updateRows = dao.update(dto);
// req.getServletContext().setAttribute(Service.BIZ_RESULT, updateRows);
// 위는 Application Scope에 올려 놓은 것이다.
req.setAttribute(Service.BIZ_RESULT, updateRows); // Request Scope에 올려 놓았다.
log.info("\t + insertRows : {}", updateRows);
} catch(SQLException e) {
throw new BizProcessException(e);
} // try - catch
} // execute
} // end class
[ 4 - 3. 위임할 /View Servlet 생성 ]
package org.zerock.myapp;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
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.myapp.service.Service;
import lombok.Cleanup;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@NoArgsConstructor
@Log4j2
@WebServlet("/View")
public class ViewServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req,res) invoked.");
log.info(">>>> /View <<<<");
res.setContentType("text/html; charset=utf8");
@Cleanup
PrintWriter out = res.getWriter();
out.println("<html><head></head><body>");
// 위의 각 command 별로 수행되는 Service 개체의 execute 메소드의 수행결과를 Request Scope에서
// 얻어서, 응답문서를 만들어 준다!
Object bizResult = req.getAttribute(Service.BIZ_RESULT);
out.println("<p>" + bizResult + "</p>");
out.println("</body></html>");
out.flush();
} // service
} // end class
[ 5. 세션 아이디 확인하는 방법 ]
package org.zerock.myapp;
import java.io.IOException;
import java.io.PrintWriter;
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 javax.servlet.http.HttpSession;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@NoArgsConstructor
@Log4j2
@WebServlet(name = "Hello2", urlPatterns = { "/hello2" })
public class Hello2Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
log.trace("service(req, res) invoked.");
HttpSession sess = req.getSession();
log.info("JSE Session ID : {}",sess.getId());
// 세션 아이디 확인하는 방법
PrintWriter out = res.getWriter();
out.println("<h1>World!!!</h1>");
// WAS는 이처럼 동적으로 태그를 넣어서 문서를 만들 수 있다.
out.flush();
out.close();
} // service
// + service는 GET과 POST방식 모두 요청을 받을 수 있다.(***)
} // end class
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 95일차 - Servlet ( 쿠키 / 파일 업로드 및 다운로드 ) (****) (0) | 2022.07.13 |
---|---|
KH 94일차 - 세션 (**) (0) | 2022.07.12 |
KH 92일차 - 공유데이터 영역 (***) (0) | 2022.07.08 |
KH 91일차 - Servlet 고급 ( FrontController / Command 패턴 ) (****) (0) | 2022.07.07 |
KH 90일차 - Servlet ( JDBC와 커넥션풀로 연결 ) / 패턴 (****) (0) | 2022.07.06 |