[JSP&Servlet] 기본적인 GET, POST 개념과 서블릿의 doGet, doPost 메서드 기본 작성법

Re_Go·2024년 7월 22일
0

JSP&Servlet

목록 보기
4/19
post-thumbnail

1. 서블릿의 do 메서드들의 역할

서블릿에서 클라이언트의 요청을 받고 처리하는 메서드들은 주로 do 접두어가 붙여진 메서드들이 처리를 하는데요. 그 중 doGet과 doPost 메서드는 사용자의 요청이 전송되는 형식에 따라 호출되어 정의된 코드를 실행함으로서 사용자의 요청을 처리하는 주요 메서드입니다.

(자료 출처 : https://velog.io/@zhyun1220/Servlet)

그 중 우선 doPost와 doGet에 대해서 알아볼건데요. 그 전에 우선 Post와 Get에 대해서 알아봐야겠죠?

2. Post, Get 방식이란?

HTTP 프로토콜의 전송 방식 중에는 크게 Post 방식과 Get 방식이 있는데요. 이 둘은 목적, 캐싱 여부, 길이 제한 등에 따라 차이를 보이는 방식들이랍니다.

Get 방식

클라이언트 측에서 서버에 정보를 요청할 때 주로 사용됩니다. 이 방식은 서버에 요청을 할 때 데이터를 URL 쿼리 문자열로 전송하는데요.

아래의 사진은 사용자가 특정 검색어로 유튜브 검색을 하고 있는 모습입니다.

그리고 요청(엔터)을 하게 되면 서버는 그걸 받아서 정보를 제공하는데요. 이때 나타나는 화면은 다음과 같고, 주소창을 잘 보시면 사용자가 전송한 정보가 주소창에 포함되어 있는 것을 확인할 수 있죠.

이처럼 단순히 서버쪽에서 공통의 정보를 제공하고자 할 때 클라이언트의 요청은 Get 방식을 사용하게 되는 것이죠. 추가로 Get 방식의 특징은 위에서 나열한 것들 외에도 아래의 사항들이 더 있습니다.

  • GET 요청은 URL에 데이터를 포함하기 때문에 캐싱이 가능하고, 그 덕에 브라우저 북마크에 저장할 수 있습니다.
  • 캐싱이 가능하다는 것은 동일한 요청을 반복할 경우 서버에 요청하지 않고 캐시된 데이터를 사용하기 때문에 서버 용량이나 실행 속도에 부담을 덜 줄 수 있습니다.
  • URL 길이에 제한이 있어, 보낼 수 있는 데이터의 양이 2000자로 제한이 되어있고, 그래서 주로 검색이나 작은 정보 요청과 같은 곳에 주로 쓰입니다.

Post 방식

클라이언트 측에서 서버에게 정보를 제공할 주로 사용됩니다. 이 방식은 서버에 정보를 전송할 때 URL에 해당 정보들이 포함되지 않고, 캐싱도 되지 않는 방식이므로 로그인, 특정 전자 문서 제출과 같이 주로 개인의 데이터를 서버로 전송할 때 사용됩니다.

아래의 사진은 네이버에서 사용자가 로그인을 할 때의 사진인데요.

일부 정보를 가려서 잘 보이시진 않으시겠지만, 로그인을 하는 순간 주소창을 잘 보시면 Get 방식과 같이 사용자가 입력한 정보가 주소창에 포함되어 있지 않는 듯 보이죠? 하지만 실제로는 사용자가 입력한 정보는 정상적으로 서버에 전송이 된 것입니다.

이처럼 앞서 말씀드린대로 민감한 개인 정보와 같은 데이터를 전송해야 할 때 사용되는 HTTP 프로토콜 전송 방식이 바로 POST 방식인데요. 이러한 POST 방식도 앞서 말씀드린 특징들 말고도 몇 개의 특징이 더 존재합니다.

  • 데이터는 HTTP 요청의 본문(body) 부분에 위치하며, URL에는 표시되지 않습니다.
  • 서버마다 받을 수 있는 데이터 양에 제한은 있겠으나, Get 방식보다 많은 양의 데이터를 전송할 수 있습니다.
  • 데이터가 기본적으로 캐싱되지 않으므로 보안에 유리하나, 정보가 저장되지 않으므로 데이터 전송마다 서버에서 직접 처리를 해야하므로 속도(부하)에 영향을 줄 수 있습니다.

이러한 POST 방식과 GET 방식은 아래의 두 그림으로도 요약이 가능할 것 같네요!

(자료 출처 : https://whales.tistory.com/120)

2. doGet, doPost 메서드 작성해보기

여러분들이 Get과 Post 방식에 대해서 아셨다면, 앞서 언급한 doGet, doPost 메서드의 역할도 얼추 아셨을거라 생각합니다. 해당 메서드들은 각각의 방식으로 사용자의 정보가 왔을 때 어떻게 처리를 할 것인지를 정의하는 메서드인데요.

service 메서드

이 메서드를 쓰기 전에, 우선적으로 해주어야 할 것은 앞전의 장에서 살펴본 service 메서드를 이용해 분기를 재정의 해주는 작업이 필요합니다. 즉 실행 될 메서드를 각각 타이밍에 따라 지정해주는 작업이죠.

@Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    	// req 객체의 getMethod 메서드를 이용해 POST 방식인지, GET 방식인지를 반환받은 뒤 method 변수에 저장
        String method = req.getMethod();

        // 전송 방식이 GET 이라면 doGost 메서드를 실행
        if ("GET".equalsIgnoreCase(method)) {
            doGet(req, res);
        }
        // 전송 방식이 POST 이라면 doPost 메서드를 실행
        else if ("POST".equalsIgnoreCase(method)) {
            doPost(req, res);
        }
        // 다른 HTTP 메서드(doHead, doPut, doTrace 등)에 대한 처리는 지금은 제외.
        else {
     		// get, post방식을 제외한 나머지 메서드 처리 요청은 setStatus로 불가 상수를 세팅한 뒤 사용자에게 불가 항목임을 출력함
			res.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            res.getWriter().println("HTTP method not supported.");
        }
    }

doGet, doPost 메서드

이제 doPost와 doGet 메서드를 아래와 같이 직접 써주면 되는데, 기본적으로 req 변수를 이용해 사용자가 입력한 정보의 값(Parameter)을 입력 받아 name에 저장하고,

사용자에게 보여질 화면의 콘텐츠 타입 인코딩 방식과 문자 인코딩 방식을 정해준 뒤 화면을 아래의 문자열 HTML 코드와 같이 작성해주면 됩니다.

	// doPost 메서드 오버라이딩
	@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 요청 인코딩 설정
        req.setCharacterEncoding("UTF-8");

        // 사용자가 요청할 때 보낸 입력 정보(name)을 받아오기
        String name = req.getParameter("name");

        // 보여질 컨텐츠의 인코딩 세팅
        resp.setContentType("text/html;charset=UTF-8");
        // 응답 인코딩 세팅
        resp.setCharacterEncoding("UTF-8");

        // 서블릿에서 사용자에게 데이터 출력을 위해 관례적으로 사용하는 출력 변수를 사용해 코드의 가독성을 높임
        PrintWriter out = resp.getWriter();       
        // 사용자에게 보여질 화면을 출력

        out.print("<head><title>Response</title></head>");
        out.print("<body>");
        out.print("<h1>Hello, " + name + "</h1>");
        out.print("<h1>This is from POST Page!</h1>");
        out.print("<form action='index.jsp' method='get'>");
        out.print("<button type='submit'>Go to Index</button>");
        out.print("</form>");
    }

	// doGet 메서드 오버라이딩
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// 요청 인코딩 설정
    	req.setCharacterEncoding("UTF-8");

    	// 사용자가 요청할 때 보낸 입력 정보(name)을 받아오기
    	String name = req.getParameter("name");

    	// 보여질 컨텐츠의 인코딩 세팅
    	resp.setContentType("text/html;charset=UTF-8");
    	// 응답 인코딩 세팅
    	resp.setCharacterEncoding("UTF-8");

    	// 서블릿에서 사용자에게 데이터 출력을 위해 관례적으로 사용하는 출력 변수를 사용해 코드의 가독성을 높임
    	PrintWriter out = resp.getWriter();       

    	// 사용자에게 보여질 화면을 출력
        out.print("<head><title>Response</title></head>");
        out.print("<body>");
        out.print("<h1>Hello, " + name + "</h1>");
        out.print("<h1>This is from GET Page!</h1>");
        out.print("<form action='index.jsp' method='get'>");
        out.print("<button type='submit'>Go to Index</button>");
        out.print("</form>");
    }

JSP 페이지

그리고 사용자에게 보여줄 JSP 페이지를 다음과 같이 작성해 주는데요. 이 때 해당 페이지에는 각각 전송 방식이 get과 post, 두 가지의 전송 방식에 대한 입력폼을 사용자에게 제공하게 됩니다.

<%@ 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>
    <h1>Hello You!</h1>
    <form action="page" method="post">
    	<h2>POST 송신</h2>
        <label for="name">Name:</label>
        <input type="text" id="name" name="name">
        <button type="submit">Submit</button>
    </form>
    <form action="page" method="get">
    	<h2>GET 송신</h2>
        <label for="name">Name:</label>
        <input type="text" id="name" name="name">
        <button type="submit">Submit</button>
    </form>
</body>
</html>

이때 코드를 자세히 보시면 제가 언급했던 method에는 각각 다른 키워드가 들어가 있는 모습과 함께 name = "name" 속성을 확인하실 수 있으실 겁니다.

이 name 속성은 서버가 값을 가져올 때 어느 DOM 요소, 그러니까 어느 부분으로부터 정보를 가져올지를 정할 때 사용되는 속성으로,

해당 속성에 지정한 값을 이용해 아까 doGet과 doPost 메서드가 req 변수를 이용해 사용자가 입력한 정보를 받아온 부분으로부터 정보를 가져올 수 있는 것이죠.

서버 실행

해당 코드까지 작성을 마친 뒤 이제 JSP 페이지에서 서버를 실행해 주는데요. 그 전에 8080 에러가 뜬다면 여기를 참조하시기를 바랍니다. 물론 자동으로 뜨는 이유는 auto 설정이 디폴트 값으로 선택되어있기 때문이기도 하죠. 그래서 만약 이클립스를 실행할 때마다 해당 8080 에러를 마주하고 싶지 않으시는 분들은auto 설정에서 Never publish 설정으로 바꾸면 됩니다.

그러나 이 경우 저장을 할 때마다 실시간으로 반영되는 화면을 확인하기 힘드니 선택은 여러분들의 몫이랍니다.

아무튼 서버를 실행하면 다음과 같은 창이 뜨는데요.

여기서 Post 송신 쪽에 이름을 적고 버튼을 눌러보겠습니다.

어떠신가요? POST 쪽에 정보를 제출하니 주소창에 정보가 노출되지 않고, doPost에 정의했던 HTML 정보(page)만 출력되죠? 이처럼 service에서 정한 분기, 그러니까 정보 제공 방식(method)에 따라 실행할 메서드가 적절히 호출되는 것을 보실 수 있습니다.

참고로 위의 정보는 개발자 도구(F12)에서 네트워크 탭에 표기되어 있는 헤더의 정보를 참고한 것으로, 헤더는 이후의 장에서 좀 더 자세히 살펴보도록 하죠!

그럼 이 참에 GET 방식도 한 번 해볼까요?

이번에는 주소창에 입력한 정보가 떴죠? 이처럼 POST와 GET 방식은 위의 사진들에서처럼 그 차이점을 알아보았고, 서블릿 컨테이너로 각 전송 방식에 따른 doPost와 doGet 메서드를 간단하게 정의해 보았습니다!

profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글