본문 바로가기
홍TV 홍TV

“POST 후 리다이렉트 (POST → Redirect → GET)”, 웹 개발자가 꼭 알아야 할 요청 처리 방식

홍TV 읽는 시간 약 9분
4.5
(300)

들어가며

웹사이트를 만들다 보면 게시글 등록, 회원가입, 로그인, 주문 처리처럼 POST 방식으로 데이터를 서버에 전달하는 기능을 자주 구현하게 됩니다.

그런데 한 가지 골치 아픈 문제가 있습니다.

사용자가 POST 요청을 보낸 뒤 서버에서 바로 HTML 페이지를 응답하면, 해당 페이지에서 새로고침을 했을 때 브라우저가 이전 POST 요청을 다시 실행하려고 할 수 있습니다. 이때 “양식 다시 제출” 같은 경고가 나타나기도 하고, 심하면 게시글이 두 번 등록되거나 주문이 중복 처리되는 문제까지 발생할 수 있습니다.

이런 문제를 해결하기 위해 많이 사용하는 방식이 바로 Post/Redirect/Get, 줄여서 PRG 패턴입니다.

POST 요청 후 바로 화면을 보여주면 왜 문제가 생길까?

예를 들어 게시판에서 사용자가 글을 작성하고 등록 버튼을 눌렀다고 생각해 보겠습니다.

일반적인 흐름은 다음과 같습니다.

사용자 → POST /board/write → 서버에서 글 저장 → 결과 페이지 반환

여기서 서버가 POST 요청에 대한 응답으로 바로 게시글 목록이나 완료 페이지를 반환하면, 브라우저 입장에서는 현재 페이지가 POST 요청의 결과로 만들어진 페이지가 됩니다.

이 상태에서 사용자가 새로고침을 누르면 브라우저는 이전에 수행했던 POST 요청을 다시 실행해야 하는 상황이 생깁니다.

즉,

POST → HTML 응답 → 새로고침 → POST 재전송

이라는 흐름이 만들어질 수 있습니다.

게시글 등록처럼 데이터가 변경되는 작업에서는 상당히 위험합니다.

Post/Redirect/Get이란?

PRG는 이름 그대로 POST 요청을 처리한 다음 Redirect를 수행하고, 최종 화면은 GET 요청으로 보여주는 방식입니다.

흐름은 다음과 같이 변경됩니다.

사용자 → POST /board/write

서버 → 데이터 저장

서버 → Redirect /board/list

브라우저 → GET /board/list

게시글 목록 화면 출력

핵심은 POST 요청의 결과를 직접 화면으로 반환하지 않고, 다른 URL로 리다이렉트한다는 것입니다.

이렇게 하면 사용자가 최종적으로 보고 있는 페이지는 GET 요청으로 만들어진 페이지가 됩니다.

따라서 해당 화면에서 새로고침을 하더라도 브라우저가 다시 POST 요청을 전송하는 것이 아니라 GET 요청을 다시 실행하게 됩니다.

JSP와 Servlet에서는 어떻게 사용할까?

Java Servlet을 예로 들어보겠습니다.

게시글 등록을 처리하는 Servlet에서 다음과 같은 형태로 작성할 수 있습니다.

@WebServlet("/board/write")
public class BoardWriteServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
            throws ServletException, IOException {

        String title = request.getParameter("title");
        String content = request.getParameter("content");

        // 게시글 저장
        boardService.insert(title, content);

        // POST 처리 후 목록 페이지로 이동
        response.sendRedirect(request.getContextPath() + "/board/list");
    }
}

여기서 중요한 부분은 sendRedirect()입니다.

게시글 저장이 끝난 후 JSP를 직접 forward()하는 대신 목록 페이지로 Redirect합니다.

그러면 브라우저에서는 다음과 같은 요청이 발생합니다.

POST /board/write
        ↓
게시글 저장
        ↓
302 Redirect
        ↓
GET /board/list
        ↓
게시글 목록 출력

이제 사용자가 목록 페이지에서 새로고침을 하더라도 /board/list에 대한 GET 요청만 다시 발생합니다.

forward와 redirect의 차이도 알아두자

PRG를 이해하려면 forward()sendRedirect()의 차이를 함께 알아두는 것이 좋습니다.

forward()는 서버 내부에서 다른 리소스로 요청을 넘기는 방식입니다.

request.getRequestDispatcher("/board/list.jsp")
       .forward(request, response);

반면 sendRedirect()는 브라우저에게 다른 주소로 다시 요청하라고 알려주는 방식입니다.

response.sendRedirect("/board/list");

그래서 PRG 패턴에서는 POST 처리 후 sendRedirect()를 사용합니다.

결과적으로 브라우저의 현재 요청 자체가 GET 방식으로 변경되기 때문입니다.

로그인에서도 PRG 패턴을 사용할 수 있다

PRG는 게시판에만 사용하는 것은 아닙니다.

회원가입, 로그인, 댓글 등록, 상품 등록, 검색 조건 저장 등 서버의 데이터를 변경하는 POST 작업이라면 다양한 곳에서 활용할 수 있습니다.

예를 들어 로그인 처리 후에는 다음과 같은 흐름을 만들 수 있습니다.

POST /login
   ↓
로그인 인증
   ↓
세션 저장
   ↓
Redirect
   ↓
GET /main

이렇게 하면 사용자가 메인 화면에서 새로고침을 하더라도 로그인 POST 요청이 다시 전송되지 않습니다.

그렇다면 POST 후 Redirect하면 데이터는 어떻게 전달할까?

여기서 초보 개발자가 자주 고민하는 부분이 있습니다.

POST 요청에서 처리한 결과를 JSP에 전달해야 하는데 Redirect를 사용하면 request 객체가 그대로 유지되지 않습니다.

이럴 때는 크게 세션이나 쿼리 파라미터 등을 활용할 수 있습니다.

예를 들어 저장 완료 메시지를 전달하고 싶다면 간단하게 URL 파라미터를 사용할 수 있습니다.

response.sendRedirect(
    request.getContextPath() + "/board/list?result=success"
);

그리고 GET 요청에서 result 값을 확인하여 메시지를 출력할 수 있습니다.

또 다른 방법으로는 세션에 일시적으로 메시지를 저장한 뒤 GET 요청에서 읽고 삭제하는 방식도 있습니다. 흔히 Flash Message와 비슷한 형태로 사용합니다.

PRG의 가장 큰 장점

PRG 패턴의 가장 큰 장점은 단순히 브라우저 경고 메시지를 없애는 것이 아닙니다.

사용자가 새로고침이나 뒤로가기 같은 브라우저 동작을 하더라도 데이터 변경 요청이 불필요하게 반복되는 상황을 줄여준다는 것입니다.

특히 게시글 등록이나 주문 처리처럼 한 번 실행될 때 데이터가 실제로 변경되는 작업에서는 매우 중요합니다.

다만 PRG를 적용했다고 해서 모든 중복 처리가 완벽하게 해결되는 것은 아닙니다.

네트워크 재전송, 사용자의 빠른 연속 클릭, 여러 브라우저 탭에서의 요청 등은 별도의 문제가 될 수 있습니다. 중요한 작업에서는 서버 측에서도 중복 요청 방지나 멱등성 처리를 함께 고려하는 것이 좋습니다.

마무리

Post/Redirect/Get은 복잡한 기술이라기보다는 POST로 데이터를 변경한 다음 Redirect를 통해 GET 화면으로 전환하는 간단한 설계 패턴입니다.

정리하면 핵심 흐름은 이것 하나만 기억하면 됩니다.

POST → 처리 → Redirect → GET

게시글 등록이라면

POST /board/write → 저장 → Redirect → GET /board/list

로그인이라면

POST /login → 인증 → Redirect → GET /main

과 같은 구조입니다.

웹 개발에서 POST 요청을 처리한 후 바로 JSP를 보여주는 방식이 익숙할 수 있지만, 데이터 변경 작업이라면 한 번쯤 PRG 패턴을 적용해 보는 것이 좋습니다.

특히 새로고침 시 중복 등록, 브라우저의 “양식 다시 제출” 경고, POST 요청 재전송 문제를 경험했다면 가장 먼저 떠올려볼 만한 패턴입니다.

화려한 기술은 아니지만 실제 서비스에서 꽤 자주 사용되는 기본기 중 하나입니다. 처음에는 단순히 “POST 다음에 Redirect를 하면 되는구나” 정도로 이해해도 충분합니다. 이후 세션 메시지, 중복 요청 방지, 멱등성까지 함께 익히면 훨씬 안정적인 웹 서비스를 설계할 수 있습니다.

이 게시물이 얼마나 유용했나요?

별점을 클릭하여 평가하세요!

평균 평점 4.5 / 5. 투표 수: 300

아직 투표가 없습니다! 첫 번째로 평가해보세요.

홍TV

홍TV
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.