요청재지정
- 클라이언트가 최초 요청한 서블릿을 응답하지 않고 다른 서블릿 내부에서 다른 웹 어플리케이션(서블릿, jsp, html...)을 재요청해서 실행하는 것
- 서블릿에서 뷰를 분리하기 위해서 반드시 알아야 하는 개념
1. 데이터공유
: page, request, session, application객체 내부에 있는 map구조의 저장소(모델)에 데이터를 공유
----------------
name과 value를 같이 저장(공유)
-page (this - 현재 jsp페이지) - jakarta.servlet.jsp.PageContext
-request(요청객체 - 한 번의 request가 응답되기 전까지 실행되는 모든 application) - HttpServletRequest(ServletRequest)
-session(세션객체 - 세션이 한 번 생성된 순간 브라우저 위에서 실행되는 모든 작업을 수행하면서 사용하는 application) - HttpSession
-application(context객체 - 서버메모리에 공유되므로 서버에서 실행되는 모든 application) - ServletContext
* page-페이지 한 장에서만 쓸 수 있음 < request-한 번 클릭하고 사라짐 < session죽이기 전까지 공유가능(로그아웃하기 전까지) < application-서버가 restart되기 전까지
1)데이터저장
scope객체.setAttribute("저장할 attribute의 이름, 저장할 객체)
---------
자바에서 사용하는 모든 객체를 공유(저장)할 수 있다.
따라서 타입은 Object
2)저장된 데이터꺼내기
Object 저장된 객체 = scope객체.getAttribute("저장된 attribute의 이름")
=> 원래 타입으로 casting만 하면 된다.
2. 요청 재지정
1) response객체의 sendRedirect
2) RequestDirpatcher의 forward
3) RequestDirpatcher의 include
3. sendRedirect
1) 문법
HttpSErvletResponse의 sendRedirect라는 메소드를 이용해서 구현
res.sendRedirect("요청 재지정될 web application path")
----------------------------------
/context명/폴더명../요청application명
2) 개요
최초 요청했던 서블릿이 response하고 다시 재요청하는 방법이므로 데이터를 공유할 수 없다.
로그인 아이디나 패스워드를 잘못 입력한 경우 로그인 페이지를 다시 보여주기 위한 방법으로 주로 사용
스프링으로 구축된 시스템에서는 거의 사용하지 않는다(기본이 forward).
3) 실행흐름
sendRedirect를 이용해서 요청을 재지정하는 경우 처음 요청된 서블릿이 실행되고 응답한 후 새롭게 요청을 하는 방식이므로 두 번의 요청으로 처리된다.
4) 특징
- 두 번의 요청으로 응답되므로 데이터는 절대 공유할 수 없다(request객체에 데이터를 공유한 경우에 해당).
- 새롭게 요청을 다시 보내는 것이므로 주소표시줄이 요청 재지정으로 설정한 web application의 path로 변경된다.
4. forward
1) 문법
: RequestDirpatcher의 forward메소드를 이용
RequestDirpatcher rd = request.getRequestDirpatcher("요청재지정 할 application path");
rd.forward(request객체, response객체) //까먹지말고 꼭 적어주기!!!!!!!!
2) 개요
최초 요청된 서블릿이 실행되고 응답하지 않은 상태에서 새로운 web application을 요청
한 번의 요청으로 모든 application이 실행된다.
서버 내부에서 페이지 호출하는 방식
< 실습1 >
- view 분리하기
- 사원 등록하기 서블릿
package kr.multicampus.erp.user.mvc;
@WebServlet(name = "mvcinsert",urlPatterns = {"/mvc/insert.do"})
public class EmpInsertServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//요청과 응답에 한글을 셋팅안 해도 됨. jsp에 이미 셍팅되어있기 때문에
PrintWriter pw = res.getWriter();
System.out.println("서블릿요청mvc");
//1. 클라이언트 요청정보 추출
int deptno = Integer.parseInt(req.getParameter("deptno")); //리퀘스트 안의 값을 꺼냄
String name = req.getParameter("name");
String id = req.getParameter("id");
String pass = req.getParameter("pass");
String addr = req.getParameter("addr");
int grade = Integer.parseInt(req.getParameter("grade"));
//2. 비지니스메소드 호출
empDAO dao = new empDAO();
empDTO emp = new empDTO(deptno, name, id, pass, addr, grade);
System.out.println(emp); //emp.tiString()
int result = dao.insert(emp);
System.out.println(result);
String view = "";
//3. 데이터공유
req.setAttribute("insertUser", emp);
//4. 요청재지정 - forward
if(result > 0) {
view = "/mvc/insertOk.jsp";
}else {
view = "/mvc/insertFail.jsp";
}
RequestDispatcher rd = req.getRequestDispatcher(view);
rd.forward(req, res);
}
}
String view = "";
//응답메세지 생성
if(result > 0) {
view = "/serverweb/emp/insertOk.html";
}else {
view = "/serverweb/emp/insertFail.html";
}
//서블릿에서 바로 응답하지 않고 요청재지정하기
res.sendRedirect(view);
|
|
↓
//3. 데이터공유
req.setAttribute("insertUser", emp);
//4. 요청재지정 - forward
String view = "";
if(result > 0) {
view = "/mvc/insertOk.jsp";
}else {
view = "/mvc/insertFail.jsp";
}
//객체를 공유하여 데이터를 넘겨받아 출력할 수 있도록 요청재지정하기
RequestDispatcher rd = req.getRequestDispatcher(view);
rd.forward(req, res);
=> 요청재지정한 곳에서도 객체를 사용할 수 있도록 데이터공유를 해주고 요청재지정을 해준다.
<%@page import="kr.multicampus.erp.user.empDTO"%>
<%@ 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>
<%
// 공유한 데이터꺼내기
empDTO user = (empDTO)request.getAttribute("insertUser");
%>
<h1>자바나라쇼핑몰</h1>
<hr/>
<img src='/serverweb/images/yc02.jpg' />
<h2><%= user.getName() %>님 가입을 축하합니다!</h2>
</body>
</html>
<!-- /mvc/insertOk.jsp -->
=> (empDTO)를 써주는 이유 : object를 리턴하기 때문에 캐스팅해줘야 함!!
=> 수행요청은 EmpInsertServlet.java 파일이 받았지만 요청 재지정을 했기 때문에 insertOk.jsp 가 대신 응답함
< 실습2 >
앞서 사원등록 서블릿으로 등록했던 모든 사원들의 정보를 웹 페이지에 출력하기 -> 기본키(pk)인 사원의 id를 누르면 새로운 페이지에 해당 사원의 모든 정보 출력하기
1. register.jsp - 회원목록을 볼 수 있는 페이지로 이동하기(EmpListServlet.java로 이동)
<a href="/serverweb/mvc/list.do"><h1>회원목록보기</h1></a> <!-- EmpListServlet.java로 이동됨 -->
2. EmpListServlet.java - /mvc/list.jsp로 요청재지정하기
package kr.multicampus.erp.user.mvc;
@WebServlet(name = "mvclist",urlPatterns = {"/mvc/list.do"})
public class EmpListServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
System.out.println("서블릿요청성공");
//1. 클라이언트 요청정보 추출
req.setCharacterEncoding("UTF-8");
//2. 비지니스메소드 호출
empDAO dao = new empDAO();
ArrayList<empDTO> allList = dao.select();
System.out.println(allList);
//3. 데이터공유
req.setAttribute("allList", allList);
//4. 요청재지정 - forward
RequestDispatcher rd = req.getRequestDispatcher("/mvc/list.jsp"); //이동할 페이지의 경로 지정. list.jsp로 이동됨
rd.forward(req, res);
}
}
* forward의 문법
: RequestDirpatcher rd = request.getRequestDirpatcher("요청재지정 할 application path ** 컨텍스트 패스를 생략 URI **");
=> 동일 웹 애플리케이션의 자원으로만 forward 할 수 있게 제한하기 위하여 서버가 컨텍스트 패스를 자동으로 붙여서 대상을 찾기 때문에 생략해준다.
3. list.jsp - 특정 아이디의 사원정보를 출력해야 하기 때문에 아이디를 파라미터로 넘겨준다.
<%@page import="kr.multicampus.erp.user.empDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ 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>
<%
//서블릿이 공유한 ArrayList를 꺼내서 테이블로 목록 출력하기
ArrayList<empDTO> userlist = (ArrayList<empDTO>) request.getAttribute("allList");
%>
<h1>회원목록보기</h1>
<table width='600' border='1'>
<tr>
글이 너무 길어지기 때문에 생략
</tr>
<%
int size = userlist.size();
for (int i = 0; i < size; i++) {
empDTO user = userlist.get(i);
%>
<tr>
<td><%=user.getDeptno()%></td>
<td><%=user.getName()%></td>
<td><a href="/serverweb/mvc/read.do?id=<%=user.getId()%>"><%=user.getId()%></a></td> <!-- EmpReadServlet.java로 이동됨 -->
<td><%=user.getPass()%></td>
<td><%=user.getAddr()%></td>
<td><%=user.getPoint()%></td>
<td><%=user.getGrade()%></td>
<td><a
href='/serverweb/mvc/delete.do?test=info&id=<%= user.getId() %>'>삭제</a></td>
</tr>
<% } %>
</table>
</body>
</html>
=> <a></a>는 하이퍼링크이며 <a>와 </a>사이에 <%=user.getId()%>를 호출해서 id를 하이퍼링크로 연결해준다.
아이디를 선택하면 EmpReadServlet.java 파일이 실행되도록 연결한다는 것이고, 하이퍼링크를 클릭할 때 선택한 레코드의 아이디를 서블릿으로 보낸다는 의미이다. 서블릿을 요청하며 파라미터를 넘길 때 서블릿 뒤에 '?'를 연결하며,
/serverweb/mvc/read.do?파라미터명=파라미터값
이와 같은 형식으로 요청해야 한다. 이 파라미터 명이 서블릿에서 req.getParameter("id");로 추출할 있는 값이 되는 것이다.
4. EmpReadServlet.java - 클라이언트의 요청 정보인 id를 추출하여 사원의 정보를 얻고 /mvc/emp_read.jsp에 요청재지정하기
package kr.multicampus.erp.user.mvc;
@WebServlet(name = "mvcread",urlPatterns = {"/mvc/read.do"})
public class EmpReadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("서블릿요청성공");
//1. 클라이언트 요청정보 추출
req.setCharacterEncoding("UTF-8");
String id = req.getParameter("id");
//2. 비지니스메소드 호출
empDAO dao = new empDAO();
empDTO user = dao.read(id);
System.out.println(user); //확인작업
//3. 데이터공유
req.setAttribute("userid", user); //userid이름으로 user 공유하겠다는 뜻
//4. 요청재지정 - forward
RequestDispatcher rd = req.getRequestDispatcher("/mvc/emp_read.jsp"); //emp_read.jsp로 이동됨
rd.forward(req, resp);
}
}
5. emp_read.jsp - 넘겨준 데이터를 받아(request 객체 공유) 화면에 출력하기
<%@page import="kr.multicampus.erp.user.empDTO"%>
<%@ 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>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<%
empDTO user = (empDTO)request.getAttribute("userid"); /* EmpReadServlet.java에서 요청재지정했기 때문에 데이터받아주기 */
%>
<div class="container-fluid">
<form role="form" class="form-horizontal"
action=""
method="get">
<fieldset>
<div id="legend">
<legend>아래 양식을 작성해주세요.</legend>
</div>
<div class="form-group">
<!-- 부서코드 -->
<label class="control-label col-sm-2" for="deptcode">부서코드 </label>
<div class="col-sm-3"> <%=user.getDeptno()%>
</div>
</div>
.
.
.
</div>
</body>
</html>
'MVC' 카테고리의 다른 글
MVC 패턴이란? (0) | 2022.11.27 |
---|---|
2022-11-17 MVC, 요청 재지정 (0) | 2022.11.17 |
2022-11-15 서블릿 메소드 분리하기(delete), jsp문법 (0) | 2022.11.15 |
2022-11-14 서블릿 메소드 분리하기, DB와 연결하기 (0) | 2022.11.14 |
댓글