[Servlet] POST 요청 처리

Bam·2024년 4월 28일
0

Spring

목록 보기
17/48
post-thumbnail

지난 포스트에서 만들었던 요청/응답 처리는 GET 방식으로 요청을 받아서 처리했었습니다. 이번에는 POST 요청 처리를 하는 방법에 대해서 알아보려고 합니다.

지난 포스트의 프로젝트 구성이 이어지기 때문에 프로젝트 생성은 지난 포스트에서 참조해주세요.


GET, POST 방식

지난 포스트에서 사용했던 GET 방식을 사용하여 요청을 보내게 되면 URL에 다음 이미지처럼 정보가 그대로 노출이 됩니다.위와같은 로그인 페이지같은 경우에 요청 데이터가 URL에 노출이 되면 보안상으로 위험하게 됩니다. 그래서 데이터를 숨기고자 할 때는 POST 요청 메소드를 사용하게 됩니다.

GET, POST 두 가지 요청 메소드를 비교하면 다음과 같습니다.

GETPOST
데이터가 URL에 name=value 형태로 표시됨데이터가 <body>에 숨겨져서 전송되어 URL에 드러나지 않음
&로 여러 데이터를 구분
보안에 취약좋은 보안성
최대 255글자의 데이터 전송전송 데이터 크기가 무제한
POST에 비해 빠른 속도GET보다 느린 속도
가장 간단한 기본 전송 방법
브라우저에 직접 입력해서 요청 가능

간단하게 비교 정리하자면 데이터가 노출되어도 상관이 없다면 GET으로, 보안이 중요한 데이터를 전송한다면 POST를 사용하게 됩니다.


POST 요청 처리

그러면 POST 요청을 서블릿으로 처리해보겠습니다.

먼저 login.html의 form의 요청 메소드를 변경해주어야합니다. 폼의 요청 방식과 서블릿의 doXxxxx()가 일치하지 않는다면 에러를 발생시키니 반드시 일치시켜주세요.

<body>
<!-- method를 post로 변경 + action도 login3으로 매핑 변경 -->
<form name="loginForm" method="post" action="login3" enctype="UTF-8">
    <fieldset>
        <legend>Login</legend>
        <label>아이디 </label>
        <input type="text" name="id"><br/>
        <label>비밀번호 </label>
        <input type="text" name="password"><br/>
        <input type="submit" value="login">
    </fieldset>
</form>
</body>

그리고 다음과 같이 LoginServlet3.java를 작성합니다.

package com.example.helloservlet.formexample;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/login3")	//login3로 서블릿 매핑
public class LoginServlet3 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("init() method called");
    }
    
    //POST 요청을 위해 doPost() 사용
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        PrintWriter out = resp.getWriter();
        String id = req.getParameter("id");
        String password = req.getParameter("password");

        String outputData = "<html><body>" +
                "아이디: " + id + "<br/>" +
                "비밀번호: " + password +
                "</body></html>";

        out.print(outputData);
    }
}

작성 후 http://localhost:8090/HelloServlet_war_exploded/login.html에 접속하여 로그인을 합니다.GET 방식과는 다르게 URL에 데이터가 노출되지 않죠?


GET, POST 동시 처리

하나의 서블릿으로 GET과 POST를 동시에 처리하고자 한다면 doGet(), doPost()를 둘 다 오버라이딩해서 사용해야합니다. 이때 동작이 동일하다면 두 개의 do 메소드에 동일 코드를 작성하는 것은 효율이 나쁘겠죠.

따라서 이런 경우에는 공통되는 메소드로 빼내서 하나의 메소드를 만든 후 doGet, doPost에서 요청이 들어오면 메소드를 호출하게 만들어서 동작하게 만들어주면 편리합니다.

다시 login.html을 변경해줍니다.

<form name="loginForm" method="get" action="login4" enctype="UTF-8">

그리고 LoginServlet4.java를 만들어서 다음 코드대로 작성합니다.

package com.example.helloservlet.formexample;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/login4")
public class LoginServlet4 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("init() method called");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doGet() method called");
        doHandle(req, resp);	//작업 메소드 호출
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doPost() method called");
        doHandle(req, resp);	//작업 메소드 호출
    }
    
    //공통 작업은 별개의 메소드로 분리
    private void doHandle(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        PrintWriter out = resp.getWriter();
        String id = req.getParameter("id");
        String password = req.getParameter("password");

        String outputData = "<html><body>" +
                "아이디: " + id + "<br/>" +
                "비밀번호: " + password +
                "</body></html>";

        out.print(outputData);
    }
}

위와 같이 작성했다면 GET 요청이 들어왔을 때는 같은 작업을 doGet()을 호출해서 처리할 것이고, POST 요청이 들어오면 doPost()를 호출해서 작업을 처리하게 될 것입니다.

위에서 GET 요청으로 처리하도록 했으니 먼저 실행해보겠습니다.

다시 login.html을 수정하고 서버를 실행하고 로그인을 수행합니다.

<form name="loginForm" method="post" action="login4" enctype="UTF-8">

위와 같이 메소드 분리를 통해서 두 개의 요청을 하나의 서블릿에서 동시에 처리할 수 있게 됩니다.

0개의 댓글