Redirect
- HTTP 프로토콜로 정해진 규칙
- 서버는 클라이언트의 요청에 대해 특정 URL로 이동. 이를 redirect라고 함.
- 그 요청의 응답으로 HTTP 상태코드 302로 응답.
- 이 때 헤더 속 location 값에 이동할 URL을 추가
- 클라이언트는 서버로부터 받은 상태값이 302이면 헤더 속 location 값의 URL로 재요청
- 이 때 브라우저의 주소창은 전송받은 새 URL로 바뀜
- servlet이나 JSP는 redirect하기 위해 HttpServletResponse 클래스의 sendRedirect() 를 사용
브라우저에서 Redirect 확인하기
개발자도구의 Network 탭
예제
웹 브라우저가 redirect01.jsp 요청
redirect01은 redirect02.jsp로 리다이렉팅하는 로직이 실행되도록 함
1번 파일을 열였는데 2번 파일로 URL도 바뀌며 창도 그 내용으로 실행됨
redirect01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.sendRedirect("redirect02.jsp");
%>
redirect02.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>
redirect된 페이지 입니다
</body>
</html>
redirect01.jsp로 Run on Server
redirect01.jsp의 URL로 입력해도 redirect02.jsp가 나온다.
이 때 redirect01.jsp을 요청을 받은 서버(WAS)는
302 응답코드와 location 헤더값에 redirect02.jsp를 redirect02.jsp로 보낸다.
redirect01의 요청에 대한 응답은 redirect02로 간다는 점
Forward
클라이언트의 요청을 다른 servlet을 한 번 거친 후에 응답
- 웹 브라우저에서 Servlet1에게 요청을 보냄
- Servlet1은 요청을 처리한 후, 그 결과를 HttpServletRequest에 저장
- Servlet1은 HttpServletRequest와 응답을 위한 HttpServletResponse를, 같은 웹 어플리케이션 안에 있는 Servlet2에게 전송, 넘겨줌.(Forward)
- Servlet2는 Servlet1으로부터 받은 HttpServletRequest와 HttpServletResponse를 이용하여 요청을 처리한 후 웹 브라우저에게 결과를 전송
Redirect VS Foward
forward는 서버쪽에서 그 요청을 다 처리하지 않고 back에게 일부분 맡기면서 진행됨.
그렇기에 redirect는 url주소가 바뀌지만 forward에서는 클라이언트는 해당 요청을 누가 처리했는지 알 필요가 없기에 URL 주소가 바뀌지 않음.
Redirect - 요청이 서로 다른 두 개
Forward - 요청이 한 개
요청이 들어와서 서버가 내부적으로 옮긴 것뿐 새로운 요청이 아님. 그렇기에 클라이언트가 한 번 요청했을 때 만들었던 요청 객체, 응답 객체가 유지됨. servlet1에서 만든 객체를 다른 servlet이 쓰게 될 때 그 정보를 각각 요청객체, 응답객체에 저장함으로써 넘겨줌.
Forward 실습
+) service() 메소드만 오버라이딩 하는 이유: 특정 요청인지, 즉 GET인지 POST인지 중요하지 않고 그저 실행되기만 하면 될 때 service()에 적어주기만 하면 되니깐.
- FrontServlet
- 랜덤한 주사위 값을 구하여 그 값을 NextServlet에게 forward
- /front로 url-mapping하기. service() 메소드만 오버라이딩
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
// 1~6 정수값 추출. 이 값을 request 객체에 맡겨야 함
int diceValue = (int)(Math.random()*6)+1;
// request 객체의 setAttribute()메소드로 값을 객체에 맡김
// 값과 함께 이 값을 설명하는 단어도 함께 보냄
request.setAttribute("dice", diceValue);
// forwarding 코드
// request가 가진 requestDispatcher 객체를 이용
// 어디로 이동할 지 적어주어야 하는데, 이 때 '/'으로 시작해야함!!
// NextServlet의 값 주소를 적음
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/next");
// 넘겨줄 값들을 적어서 forward
requestDispatcher.forward(request, response);
}
- NextServlet
- FrontServlet으로부터 전달받은 주사위 값만큼 "hello" 출력
- /next로 url-mapping하기. service() 메소드만 오버라이딩
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>form</title></head>");
out.println("<body>");
// 그 값을 가지고 있는 request 객체로부터
// 지정한 라벨을 적어서 값을 찾아옴
// 값을 꺼내왔을 때 Object 형으로 나오기에
// Integer로 형변환
int dice = (Integer)request.getAttribute("dice");
out.println("dice : " + dice);
for(int i = 0; i < dice; i++) {
out.print("<br>hello");
}
out.println("</body>");
out.println("</html>");
}
- http://localhost:8081/firstweb/front
- 위의 URl로 FrontServlet이 호출됨
FrontServlet으로 Run on Server
URL은 /front 그대로이지만 내용은
NextServlet의 내용이 출력됨. 응답코드 302는 필요없음.
Servlet & JSP 연동
Servlet은 로직을 구현하기에 알맞지만, HTML 출력엔 불편. (IDE 등에서 지원도 좀 더 잘해줌)
JSP는 로직 구현에 불편하지만 HTML 출력에 편리함. (결과 출력에 유리)
둘을 함께 다루려면 forward 사용 (Servlet에서 로직 수행하고 그 결과를 JSP에게 forwarding)
실습
LogicServlet에서 1~100 사이 랜덤값 2개와, 그 합을 구하여 result.jsp에게 포워딩해서 출력하기
- LogicServlet
- url-mapping은 /logic, service() 메소드만 오버라이딩
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
int v1 = (int)(Math.random() * 100) + 1;
int v2 = (int)(Math.random() * 100) + 1;
int result = v1 + v2;
request.setAttribute("v1", v1);
request.setAttribute("v2", v2);
request.setAttribute("result", result);
// webapp 폴더의 바로 아래가 아닌 그 아래 다른 폴더에 접근하려면
// 경로도 표시해주기
RequestDispatcher rd = request.getRequestDispatcher("/jsp/result.jsp");
rd.forward(request, response);
}
- result.jsp
<body>
<%
int v1 = (int)request.getAttribute("v1");
int v2 = (int)request.getAttribute("v2");
int result = (int)request.getAttribute("result");
%>
<%=v1%> + <%=v2%> = <%=result %>
</body>
EL 방식으로 풀이하면 간단해짐.
JSP에서 최대한 자바 코드를 적게 쓰는 것이 좋음
<body>
${v1} + ${v2} = ${result }
</body>
- 결과
LogicServlet을 Run on Server
LogicServlet의 계산 후 result.jsp의 형식에 따라 출력됨
그래서 url은 바뀌지 않음
그리고 JSP 파일은 내부적으로 자바로 바뀜.
'Web > Java+Spring' 카테고리의 다른 글
EL (Expression Language) for JSP (0) | 2021.05.10 |
---|---|
Scope (0) | 2021.05.10 |
JSP (0) | 2021.05.08 |
Request, Response (0) | 2021.05.06 |
Servlet의 Life Cycle (0) | 2021.05.05 |