04. 라우팅(리다이렉션과 포워딩의 차이)

Jan 25, 2024
04. 라우팅(리다이렉션과 포워딩의 차이)
📌
스테이트리스(Stateless)란? 시스템이나 프로토콜이 이전에 받았던 요청의 정보를 저장하지 않고 각 요청을 별개의 것으로 처리하는 것이다. 즉 상태 정보가 저장되지 않는다.
  • webapp → WEB-INF로 파일 이동 → 강제성을 주기 위해서 한다.
 
필요하면 302로 다 리다이렉션을 때린다. 이러면 JSP 파일이 필요 없다 이래서 Controller는 class 파일로 만든다.
 
요청시마다 리퀘스트 리스폰스를 만든다. → 상태를 저장하지않는다. → 2번 만들어진다. → 최초에 요청한 데이터 없음. → 내부 호출을 해야한다. → (1요청 2내부에서 다시 요청 3전달) 순서
 
무조건 디스패쳐를 거쳐서 가야하므로 그런 것이다.
 
최초에 들고있는 req, resp를 들고 재요청을 한다. 강제성을 주기위해 하는 것이다. WEB-INF가 보안 폴더 이기 때문이다. → 내부적으로 통신할때는 가방을 두고 가는데 이 이유가 스테이트 리스 때문이다.
( 구조도 노출이 안됨 )

라우터를 이해하기 위한 코드

DispatcherServlet (라우터)
package com.example.userapp.config; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; // FromtController // 라우터 @WebServlet("*.do") // ~.do 하면 여기로 다 오는 것 public class DispatcherServlet extends HttpServlet { // /join-form.do @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 공통로직 resp.setHeader("Content-Type", "text/html; charset=utf-8"); System.out.println("common logic~~~~~"); // 2. 분기 String uri = req.getRequestURI(); if (uri.equals("/join-form.do")) { //resp.sendRedirect("/WEB-INF/user/join-form.jsp"); req.getRequestDispatcher("/WEB-INF/user/join-form.jsp").forward(req, resp); // 최초에 들고있는 req, resp를 들고 재요청을 한다. 강제성을 주기위해 하는 것이다. WEB-INF가 보안 폴더 이기 때문이다. } else if (uri.equals("/join.do")) { //resp.sendRedirect("/WEB-INF/user/join.jsp"); req.getRequestDispatcher("/WEB-INF/user/join.jsp").forward(req, resp); } else if (uri.equals("/main.do")) { //resp.sendRedirect("/WEB-INF/board/main.jsp"); req.getRequestDispatcher("/WEB-INF/board/main.jsp").forward(req, resp); } else { resp.setStatus(404); resp.getWriter().println("잘못된 페이지를 요청하셨습니다."); } } }
join
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <% // username=ssar&password=1234&email=ssar@gmail.com //response.setHeader("Content-Type", "text/html; charset=utf-8"); // body의 header에 타입을 알려주는 방법! 이래야 한글 안깨짐 // 1. 파싱(parsing) String username = request.getParameter("username"); // 톰캣에서 제공하는 파싱! String password = request.getParameter("password"); String email = request.getParameter("email"); System.out.println("username : " + username); System.out.println("password : " + password); System.out.println("email : " + email); // 2. 유효성 검사 (1000줄 됨) if (username.length() < 3 || username.length() > 10) { // 필터링 하듯! response.getWriter().println("<h1>username 글자수가 3~10 사이여야 합니다</h1>"); return; } // 3. DB 연결 // 4. DAO의 insert 메서드를 호출 // 5. 메인 페이지 그리기 (비효율적) // 6. 리다이렉트(Redirect) -> 안 쓰면 HTML 코드를 통째로 또 넣어야 해서 엄청나게 긴 코드가 되서 지저분해진다. //resp.sendRedirect("/main"); // 5의 메인 페이지 그리기는 간략화해서 하는 방법이라 보면 된다. // 위의 sendRedirect를 풀어 쓰면 아래의 두 줄이다. response.setStatus(302); // 프로토콜로 상태코드가 302여야 리다이렉트가 가능하다. response.setHeader("Location", "main.do"); //response.setHeader("clock", "12pm"); %>
join-form
<%@ page import="java.time.LocalDateTime" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% LocalDateTime now = LocalDateTime.now(); %> <html> <head> <title>Title</title> </head> <body> <h1>회원가입 페이지 <%=now%> </h1> <hr> <form action="/join.do" method="post"> <input type="text" placeholder="username" name="username"> <input type="text" placeholder="password" name="password"> <input type="text" placeholder="email" name="email"> <button>회원가입</button> </form> </body> </html>
main
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>main page</h1> <hr> </body> </html>
이 코드에서 보면 WEB-INF인 보안 폴더에 넣는데 이유는 강제성을 부여하기 위해서 이다! 이때는 리다이렉션이 안 먹는데 계속 막히기 때문에 내부적으로 요청을 해야 한다. 그로 인해 “forward”를 사용한다.
req.getRequestDispatcher("/WEB-INF/user/join-form.jsp").forward(req, resp); // 내부적 요청을 해서 보안을 유지한다

리다이렉션과 포워딩의 차이

🌟
리다이렉션(Redirection)과 포워딩(Forwarding) 사용자의 요청을 처리하는 두 개의 방식! 리다이렉션
  • 클라이언트에게 다른 URL로 이동하라고 지시
  • 브라우저 주소 창의 URL이 변경됨
  • 두 번의 네트워크 요청이 발생 (리스폰스와 리퀘스트가 두 번 생김)
 
포워딩
  • 서버 내부에서 요청을 다른 서블릿/JSP로 전달
  • 브라우저 주소 창의 URL이 그대로 유지됨
  • 한 번의 네트워크 요청으로 처리 (리스폰스와 리퀘스트가 한 번 생김)
fowarding = 덮어씌기 포워딩은 결국 확인!
 
결론 두개의 차이점은 리다이렉션은 디스패처 서블릿(프론트 컨트롤러)를 통해서 요청이 반환 되는 경우 말고도 각 컨트롤러를 통해서 반환 되는 것 을 얘기하고(url 변경)
포워딩은 디스패처 서블릿을 통해서만 클라이언트의 요청 결과가 반환 되어 실제로는 서버 내부에서 다른 페이지로 이동한다. 그러나 이를 클라이언트의 입장에서는 같은 url을 화면에 출력함으로써 눈치채지 못하게 할 뿐 이다. 이유는 보안 문제이다.
Share article
RSSPowered by inblog