Servlet doGet(), doPost() 메소드 구현과 질의 문자열 추출
이전 포스팅 https://kgvovc.tistory.com/32과 이어집니다.
서블릿 작성
웹에서는 클라이언트가 전달하는 모든 정보들은 HTTP의 요청정보에 포함되어 서버로 전달되어 처리됩니다. 그래서 서버 프로그램을 구현하면서 서비스를 요청한 클라이언트에 관한 정보가 필요하다면 HTTP의 요청정보에서 추출하여 사용합니다.
이처럼 클라이언트가 보낸 정보들은 HTTP의 요청정보에 담겨서 전달되고, 서버에서 요청정보를 처리할 때 사용하는 객체는 HttpServletRequest입니다. 이번 절에서는 HttpServletRequest 객체를 사용해 클라이언트로부터 전달된 질의 문자열을 추출하는 방법을 알아보겠습니다.
메소드 구현
QueryTestServlet.java 서블릿 소스 파일을 작성합니다.
package com.edu.test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/queryTest")
public class QueryTestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("<html><head><title>Query 문자열 테스트</title></head>");
out.print("<body>");
out.print("<h1>GET 방식으로 요청되었습니다.</h1>");
out.print("</body></html>");
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("<html><head><title>Query 문자열 테스트</title></head>");
out.print("<body>");
out.print("<h1>POST 방식으로 요청되었습니다.</h1>");
out.print("</body></html>");
out.close();
}
}
서블릿 연결
QueryTestServlet.java 소스에서 doGet()과 doPost() 메소드를 재정의하여 서블릿 소스를 완성하였습니다. 이제 member.html과 QueryTestServlet을 연결해서 실행해보겠습니다. member.html에서 폼의 데이터를 전달해서 처리할 서버 프로그램으로 QueryTestServlet을 실행하려면 다음과 같이 member.html 소스에서 <form> 태그의 action 속성에 QueryTestServlet과 매핑되는 정보를 지정합니다.
~생략~
<body>
<h3>회원 정보</h3>
<form action="queryTest" method="get">
~생략~
action 속성값으로 "queryTest"를 지정했는데요. 이는 상대 경로로 주소(URI)를 지정한 것입니다. 현재 member.html 파일이 속한 웹 어플리케이션의 경로는 /edu이고, 파일은 /(루트) 디렉터리에 있으므로 실제 요청되는 URI는 /edu/queryTest입니다. action 속성값을 "queryTest"로 지정한 이유는 QueryTestServlet.java에서 서블릿 매핑정보를 @WebServlet("/queryTest")로 지정하였기 때문입니다.
QueryTestServlet이 속한 웹 애플리케이션의 경로는 /edu이고, @WebServlet 값을 "/queryTest"로 지정했으므로 실제 지정되는 URI는 /edu/queryTest입니다. 이는 member.html에서 <form> 태그의 action 속성값과 일치합니다. 따라서 member.html에서 전송 버튼을 클릭하면 QueryTestServlet이 실행됩니다.
그럼, queryTest를 GET 방식과 POST 방식으로 모두 테스트해보겠습니다.
GET 방식
member.html에서 <form> 태그의 method 속성값을 "get"으로 지정합니다.
<form action="queryTest" method="get">
member.html을 실행한 후 전송을 클릭합니다. QueryTestServlet의 doGet() 메소드가 호출됩니다.
POST 방식
member.html에서 <form> 태그의 method 속성값을 "post"으로 지정합니다.
<form action="queryTest" method="post">
member.html을 실행한 후 전송을 클릭합니다. QueryTestServlet의 doPost() 메소드가 호출됩니다.
질의 문자열 추출
질의 문자열은 어떠한 방식으로 요청하였든지 HTTP의 요청 정보에 포함되어 전달됩니다. HTTP의 요청 정보에 대한 값을 추출하는 기능을 가지고 있는 객체는 HttpServletRequest입니다. 질의 문자열 추출 또한 HttpServletRequest에서 제공하는 메소드를 이용합니다.
-
String getParameter(String name)
이 메소드는 질의 문자열로 넘어온 값을 하나씩 추출할 때 사용합니다. 질의 문자열에서 name이 중복되지 않고 유일하게 하나만 넘어올 때 사용합니다.
ex) id=guest&pwd=amy&age=23 -> name이 중복되지 않으므로 getParameter() 메소드를 씀.
color=red&color=blue&color=yellow -> name이 중복되므로 getParameter() 메소드를 쓰지 않음.
-
String[] getParameterValues
이 메소드는 같은 이름으로 여러 개의 변수가 전달되었을 때 한번에 모든 값을 추출하여 String 타입의 배열로 받고 싶을 때 사용합니다.
-
String getQueryString()
이 메소드는 클라이언트가 전달한 질의 문자열 전체를 하나의 String으로 추출해줍니다. 그런데 이 메소드는 GET 방식 요청에서만 사용할 수 있습니다. 왜냐하면, HTTP 요청정보의 URI 정보에서 ? 다음에 나오는 문자열들을 추출해주기 때문입니다.
-
ServletInputStream getInputStream() throws IOException
이 메소드는 HTTP의 요청정보 몸체와 연결된 입력스트림을 생성하여 반환합니다. 서블릿 프로그램에서 요청정보 몸체에 있는 데이터들을 읽어오고 싶을 때 getInputStream()에서 반환한 ServletInputStream으로 읽어올 수 있습니다. POST 방식의 질의 문자열 전체를 한번에 추출할 때 사용할 수 있는 메소드입니다.
이와 같은 HttpServletRequest의 메소드들을 사용하여 질의 문자열을 추출하는 예제를 작성해 보겠습니다. 먼저 GET 방식으로 처리해보겠습니다.
// QueryTestServlet.java
~ 생략 ~
public class QueryTestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
String id = req.getParameter("id");
String password = req.getParameter("pwd");
String name = req.getParameter("name");
String[] hobbies = req.getParameterValues("hobby");
String gender = req.getParameter("gender");
String religion = req.getParameter("religion");
String intro = req.getParameter("introduction");
out.print("ID: " + id + "<br/>");
out.print("비밀번호: "+ password + "<br/>");
out.print("이름: " + name + "<br/>");
out.print("취미: ");
for(int i = 0 ; i < hobbies.length; i++) {
out.print(hobbies[i] + " ");
}
out.print("<br/>");
out.print("성별: " + gender + "<br/>");
out.print("종교: " + religion + "<br/>");
out.print("소개: " + intro + "<br/>");
out.print("전체 질의 문자열: " + req.getQueryString());
out.close();
}
~ 생략 ~
[실행 결과]
이번에는 POST 방식으로 처리해보겠습니다.
~생략~
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
String id = req.getParameter("id");
String password = req.getParameter("pwd");
String name = req.getParameter("name");
String[] hobbies = req.getParameterValues("hobby");
String gender = req.getParameter("gender");
String religion = req.getParameter("religion");
String intro = req.getParameter("introduction");
out.print("ID: " + id + "<br/>");
out.print("비밀번호: "+ password + "<br/>");
out.print("이름: " + name + "<br/>");
out.print("취미: ");
for(int i = 0 ; i < hobbies.length; i++) {
out.print(hobbies[i] + " ");
}
out.print("<br/>");
out.print("성별: " + gender + "<br/>");
out.print("종교: " + religion + "<br/>");
out.print("소개: " + intro + "<br/>");
out.close();
}
[실행 결과]
doPost() 메소드에서 질의 문자열을 추출하는 작업은 doGet() 메소드에서 사용했던 메소드를 동일하게 사용하고 있음을 알 수 있습니다. 질의 문자열을 name 단위로 추출할 때는 GET 방식과 POST 방식 모두 HttpServletRequest의 getParameter() 또는 getParameterValues() 메소드를 사용하여 추출하면 됩니다.
이제 POST 방식에서 질의 문자열 전체를 추출하는 예제를 작성해 보겠습니다. GET 방식에서는 getQueryString() 메소드를 사용하지만, POST 방식에서는 프로그램 내의 요청정보에서 직접 읽어와야 합니다.
~생략~
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("<html><head><title>Query 문자열 테스트</title></head>");
out.print("<body>");
out.print("<h1>POST 방식 질의 문자열 추출</h1>");
ServletInputStream input = req.getInputStream();
int len = req.getContentLength();
byte[] buf = new byte[len];
input.readLine(buf, 0, len);
String s = new String(buf);
out.print("전체 문자열: " + s);
out.println("</body></html>");
out.close();
}
~생략~
[실행 결과]