[JSP&Servlet] 메소드 방식에 따라 클라이언트의 정보 추출 메서드

Re_Go·2024년 7월 29일
0

JSP&Servlet

목록 보기
6/19
post-thumbnail
post-custom-banner

1. 기본 코드 구조

GET, POST 방식에 따른 클라이언트의 제공 정보를 추출하기에 앞서 JSP 구조를 다음과 같이 짜보도록 하겠습니다.

  1. JSP 페이지
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/style.css">
<title>Insert title here</title>
</head>
<body>
    <h1>회원 가입</h1>
    <form action="page" method="get">
    	<fieldset>
    		<legend class="screen-out">개인 정보</legend>
    		<ul>
    			<li>
			        <label for="id" class="title">아이디 : </label>
			        <input type="text" id="id" name="id" class="input">
		        </li>
		        <li>
			        <label for="pwd" class="title">패스워드 : </label>
			        <input type="password" id="pwd" name="pwd" class="input">
		        </li>        
		        <li>
			        <label for="name" class="title">이름 : </label>
			        <input type="text" id="name" name="name" class="input">
		        </li>
		        <li>
		       		<label class="title">취미 : </label>
			        <input type="checkbox" class="habit" name="hobby" value="등산">등산
			        <input type="checkbox" class="habit" name="hobby" value="운동">운동
			        <input type="checkbox" class="habit" name="hobby" value="독서">독서
			        <input type="checkbox" class="habit" name="hobby" value="여행">여행
			        <input type="checkbox" class="habit" name="hobby" value="없음">없음
		        </li>
		        <li>
		        	<label class="title">성별 : </label>
			        <input type="radio" class="gender" name="gender" value="male">남자
			        <input type="radio" class="gender" name="gender" value="female">여자
		        </li>
		        <li>
			        <label for = "religion" class="title">종교 : </label>
			        <select id = "religion" name = "religion">
			        	<option value = "christian">기독교</option>
			        	<option value = "catholic">천주교</option>
			        	<option value = "buddhism">불교</option>
			        	<option value = "wonbuddhism">원불교</option>
			        	<option value = "none">없음</option>
			        </select>
		        </li>
		        <li>
			        <label for = "introduce" class="title">자기 소개</label>
			        <textarea id="introduce" name="introduce" rows="10" cols="50">
			    	</textarea>
		    	</li>
	    	</ul>
	    	<div class = "button-group">
		    	<input type = "submit" id = "submit" value = "전송하기">
		    	<input type = "submit" id = "initial" value = "모두 지우기">
	    	</div>
    	</fieldset>
    </form>
</body>
</html>
  1. CSS 파일
h1{
	text-align: center;
}
body{
	width: 100vw;
	height: 100vh;
}
fieldset{
	width: 300px;
	height: 500px;
	margin: auto;
}
legend{
	text-align: center;
}
ul {
  padding: 0;
  list-style-type: none;
}
ul li {
  margin-bottom: 15px;
}
label.title{
	text-align: left;
}
input.input{
	width: 300px;
	float: right;
}
textarea {
    display: block;
    margin: 10px 0; 
}
.button-group{
	text-align: center;
}
  1. 서블릿 파일
package com.practice.test;

import java.io.*;
import java.util.Arrays;

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

@WebServlet("/page")
public class ServletContainer extends HttpServlet {

    @Override
    public void init() throws ServletException {
    	// DB 연결이나 파일 로딩, 기타 작업을 초기화 하는 구역입니다.
        System.out.println("초기화 완료");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        String method = req.getMethod();
       
        // GET 요청 처리
        if ("GET".equalsIgnoreCase(method)) {
            doGet(req, res);
        }
        // POST 요청 처리
        else if ("POST".equalsIgnoreCase(method)) {
            doPost(req, res);
        }
        // 다른 HTTP 메서드에 대한 처리 추가
        else {
           res.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            res.getWriter().println("HTTP method not supported.");
        }
    }

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

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

        // 서블릿에서 사용자에게 데이터 출력을 위해 관례적으로 사용하는 출력 변수를 사용해 코드의 가독성을 높임
        PrintWriter out = resp.getWriter();
       
        // 요청 파라미터 추출
        String id = req.getParameter("id");
        String pw = req.getParameter("pwd");
        String name = req.getParameter("name");
        String[] hobbies = req.getParameterValues("hobby");
        String gender = req.getParameter("gender");
        String religion = req.getParameter("religion");
        String introduce = req.getParameter("introduce");

        // 사용자에게 보여질 화면 출력
        out.print("<head><title>요청 결과</title></head>");
        out.print("<body>");
        out.print("<h1>요청 결과</h1>");
        out.print("<p>ID : " + id + "</p>");
        out.print("<p>PASSWORD : " + pw + "</p>");
        out.print("<p>이름 : " + name + "</p>");
        out.print("<p>취미 : " + Arrays.toString(hobbies) + "</p>");
        out.print("<p>성별 : " + gender + "</p>");
        out.print("<p>종교 : " + religion + "</p>");
        out.print("<p>소감 : " + introduce + "</p>");
        out.print("<form action='index.jsp' method='get'>");
        out.print("<button type='submit'>돌아가기</button>");
        out.print("</form>");
        out.print("</body></html>");
    }
  
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// 요청 인코딩 설정
    	req.setCharacterEncoding("UTF-8");
   	
    	// 보여질 컨텐츠의 인코딩 세팅
    	resp.setContentType("text/html;charset=UTF-8");
    	// 응답 인코딩 세팅
    	resp.setCharacterEncoding("UTF-8");

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

    	String id = req.getParameter("id");
    	String pw = req.getParameter("pwd");
    	String name = req.getParameter("name");
    	String[] hobbies = req.getParameterValues("hobby");
    	String gender = req.getParameter("gender");
    	String religion = req.getParameter("religion");
    	String introduce = req.getParameter("introduce");
    	String queryInfo = req.getQueryString();

        out.print("<head><title>요청 결과</title></head>");
        out.print("<body>");
        out.print("<p>" + "total : " + queryInfo + "</p>");
        out.print("<h1>요청 결과</h1>");
        out.print("<p>" + "ID : " + id + "</p>");
        out.print("<p>" + "PASSWORD : " + pw + "</p>");
        out.print("<p>" + "이름 : " + name + "</p>");
        out.print("<p>" + "취미 : " + Arrays.toString(hobbies) + "</p>");
        out.print("<p>" + "취미 : " + String.join(", ", hobbies) + "</p>");
        out.print("<p>" + "성별 : " + gender + "</p>");
        out.print("<p>" + "종교 : " + religion + "</p>");
        out.print("<p>" + "소감 : " + introduce + "</p>");
        out.print("<form action='index.jsp' method='get'>");
        out.print("<button type='submit'>돌아가기</button>");
        out.print("</form>");
    }
}

2. getParameter

getParameter는 사용자가 입력한 단일 정보를 추출하는대 사용되는데요. 서블릿과 연결된 JSP 페이지에서 제출 된 사용자의 정보들 중 단일 정보를 가져오며, 이때 가져오는 정보의 형태는 속성은 name이라는 이름과 value라는 이름의 값으로 구성이 됩니다.

HTML에서 name은 id이고 value는 사용자의 입력값이므로

<input type="text" id="id" name="id" class="input">

request 객체의 getParameter 메서드로 input의 name이 id인 요소의 값(value)를 추출해 id 변수에 담아 출력하면

String id = req.getParameter("id");
System.out.println(id);

다음과 같이 콘솔창과 웹페이지 창에서 해당 정보를 확인할 수 있습니다.

3. getParameterValues

getParameterValues는 사용자가 입력한 다중 정보를 추출하는대 사용되는데요. 이 방식은 name이 같은 이름인 요소들의 값을 배열 형태로 전달 받아 활용할 수 있습니다.

checkbox 형태의 input은 다중 선택이 가능하기 때문에 name이 hobby인 것을 기준으로 배열 형태로 받을 수 있습니다.

<label class="title">취미 : </label>
<input type="checkbox" class="habit" name="hobby" value="등산">등산
<input type="checkbox" class="habit" name="hobby" value="운동">운동
<input type="checkbox" class="habit" name="hobby" value="독서">독서
<input type="checkbox" class="habit" name="hobby" value="여행">여행
<input type="checkbox" class="habit" name="hobby" value="없음">없음

다음과 같이 배열에 값들을 전달한 뒤 배열 형태와 문자열 형태로 반환하면 다음과 같이 확인할 수 있습니다.

String[] hobbies = req.getParameterValues("hobby");
out.print("<p>" + "취미 : " + Arrays.toString(hobbies) + "</p>");
out.print("<p>" + "취미 : " + String.join(", ", hobbies) + "</p>");

4. getQueryString

getQueryString 메서드는 사용자의 입력값을 주소 형태로 받아오는 메서드인데요. get 방식에는 주소값에 사용자의 입력값이 포함되어 있기 때문에 POST 방식에는 사용이 불가능하고, GET 방식에서만 활용 가능한 메서드입니다.

서블릿에 다음과 같이 쿼리를 구해와 출력을 할 경우

String queryInfo = req.getQueryString();
out.print("<p>" + "total : " + queryInfo + "</p>");

다음과 같이 쿼리값 자체를 출력할 수 있습니다.

5. getInputStream

getInputStream 메서드는 클라이언트의 요청 정보가 담긴 몸체와 연결된 입력스트림을 생성한 뒤 반환하는 메서드로, 요청정보 몸체에 있는 데이터들을 읽어오고 싶을 때 사용하는데요. 즉 이 메서드는 POST 방식을 위한 메서드라는 말이기도 합니다.

getInputStream 인스턴스를 하나 생성한 후 컨텐츠 길이 만큼을 len 변수에 저장을 해줍니다. (getContentLength 메서드 이용)

그 다음 byte 타입의 배열을 해당 len의 길이만큼 생성하는데, 여기서 byte 배열을 사용하는 이유는 HTTP 요청 본문은 텍스트 뿐만 아니라 바이너리 데이터도 포함될 수 있기에 텍스트와 이진 데이터를 모두 저장 가능한 byte 배열을 사용한 것입니다. 물론 String으로 변환하기 위한 목적도 가지고 있고요.

아무튼 위 작업을 수행한 뒤 read 메서드를 이용해 각각 저장소(b)와 저장 시작 위치(0), 저장할 문자열의 길이(len)을 지정해 읽어줍니다.

그 다음 마지막으로 저장소 b를 문자열로 변환 후 출력을 해줍니다.

ServletInputStream input = req.getInputStream();
int len = req.getContentLength();
byte[] b = new byte[len];
input.read(b, 0, len);
String str = new String(b)
out.print("전체 문자열 : " + str);

그럼 다음과 같이 데이터가 잘 출력되는데요. 여기서 의외인건 POST 방식에서 getParameter 메서드를 사용하면 null, 즉 값이 없음을 의미한다는 겁니다.

그 이유는 getInputStream으로 요청 본문을 직접 읽으면, getParameter 메서드는 더 이상 폼 데이터에 접근할 수 없는데, getInputStream과 getParameter는 서로 다른 데이터 읽기 방식을 사용하기 때문에, 하나의 요청 본문에서 둘 다 사용하려고 하면 충돌이 발생하여 getParameter에서 제대로 값을 읽어오지 못했기 때문이죠.

하지만 그 말인 즉 getInputStream을 사용하지 않으면 getParameter도 정상적으로 사용할 수 있다는 의미이므로 왠만해서는 getParameter로 사용하면 됩니다.

getInputStream 부분을 지우고 나니 잘 되는군요!

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

0개의 댓글