1. 리다이렉트(Redirect)
1️⃣ redirect의 개념
1) 정의
redirect는 서버 → 클라이언트 → 서버로 이어지는 재요청 메커니즘
response.sendRedirect("login.jsp");2) 핵심 한 줄
redirect는 “응답으로 새 요청을 지시하는 것”
2️⃣ redirect 동작 흐름
Browser
↓ (요청 1)
Servlet
↓ (302 응답 + Location 헤더)
Browser
↓ (요청 2, 새로운 URL)
서버
↓
Browser (최종 응답)- 요청 2번
- 응답 2번
- 클라이언트가 이동을 인지
3️⃣ redirect의 핵심 특징
1) URL 변경
- 브라우저 주소창 변경됨
/login.do → /loginResult.jsp
2) request 객체 유지 ❌
- 새로운 요청 → 새로운
request
- 기존 request 데이터 소멸
request.setAttribute("msg", "success");
response.sendRedirect("result.jsp"); // 전달 불가✔ 해결 방법
- session
- query string
- flash scope (Spring)
3) HTTP 상태 코드 사용
302 Found (기본)
303 See Other (POST → GET 권장)response.setStatus(HttpServletResponse.SC_FOUND);
response.setHeader("Location", "main.jsp");4) 외부 사이트 이동 가능
response.sendRedirect("https://www.google.com");- forward는 서버 내부 리소스만 가능
4️⃣ redirect vs forward (핵심 비교)
구분 | redirect | forward |
이동 주체 | 클라이언트 | 서버 |
요청 횟수 | 2회 | 1회 |
request 유지 | ❌ | ✅ |
URL 변경 | ✅ | ❌ |
새로고침 | 안전 | POST 중복 위험 |
외부 URL | 가능 | 불가 |
5. redirect를 사용하는 대표적 상황
1) ✅ POST 처리 후 화면 이동 (PRG 패턴)
doPost() {
// DB 저장
response.sendRedirect("list.do");
}- 새로고침 시 중복 INSERT 방지
- 실무에서 매우 중요
2) ✅ 로그인 성공/실패 후 이동
if (success) {
response.sendRedirect("main.do");
} else {
response.sendRedirect("login.jsp?error=true");
}3) ✅ 인증·권한 체크
if (session.getAttribute("user") == null) {
response.sendRedirect("login.jsp");
return;
}6️⃣ redirect 경로 규칙 (중요)
response.sendRedirect("/myapp/main.do");/기준: 서버 루트
- context path 포함 필수
response.sendRedirect(request.getContextPath() + "/main.do");7️⃣ forward와 redirect 선택 기준 (실무 기준)
✔ 화면 출력만 바뀐다 → forward
✔ 상태가 바뀐다(DB, 로그인, 결제) → redirect
8️⃣ 한 줄 요약
redirect는 클라이언트에게 “새 URL로 다시 요청하라”고 명령하는 응답 방식
9️⃣ 그림으로 이해하기

🔟 실습

package com.example.prodwebapp;
import java.io.IOException;
import com.example.prodwebapp.lib.View;
import com.example.prodwebapp.lib.ViewResolver;
import com.example.prodwebapp.product.ProductController;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
ProductController pc = new ProductController();
// localhost:8080/product.do?cmd=list
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 라우팅
String cmd = req.getParameter("cmd");
if ("list".equals(cmd)) {
String viewName = pc.list(req, resp);
ViewResolver.render(viewName).forward(req, resp);
} else if ("insert-form".equals(cmd)) {
String viewName = pc.insertForm(req, resp);
ViewResolver.render(viewName).forward(req, resp);
} else if ("detail".equals(cmd)) {
String viewName = pc.detail(req, resp);
ViewResolver.render(viewName).forward(req, resp);
}
}
// localhost:8080/product.do?cmd=insert
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 라우팅
String cmd = req.getParameter("cmd");
if ("insert".equals(cmd)) {
// url = /product.do?cmd=list
String url = pc.insert(req, resp);
// resp.sendRedirect(url);
// 리다이렉션(재요청) 아래 2개의 코드를 위의 sendRedirect가 한 번에 처리해 줌
resp.setStatus(302);
resp.setHeader("location", url);
}
}
}

Share article