관리 메뉴

거니의 velog

(11) <form> 태그 이용해 서블릿에 요청하기 본문

Java_Servlet

(11) <form> 태그 이용해 서블릿에 요청하기

Unlimited00 2023. 8. 22. 21:02

1. <form> 태그 이용해 서블릿에 요청하기

* JSP, ASP, PHP가 나오기 전에는 HTML, CSS, 자바스크립트를 이용해 웹 프로그램을 만들었다. 서블릿과 JSP는 이러한 HTML, CSS, 자바스크립트 같은 기존의 것을 버리는 것이 아니라 여기에 자신의 기능을 추가하여, 즉 서로 연동하여 동작한다. 특히 사용자의 요청은 HTML <form> 태그나 자바스크립트로부터 전송 받아서 처리한다.

* 클라이언트 웹 브라우저에서 서블릿에 요청하는 방법은 다음과 같다.

* 웹 브라우저에서 여러 가지 입력 서식을 이용해 전송을 클릭하면 사용자가 입력한 데이터가 서블릿으로 전송된다. 그러면 서블릿은 여러 가지 메서드를 이용해서 전송된 데이터를 받아 온다.


2.  <form> 태그의 여러 가지 속성

* 사용자가 자신의 ID와 비밀번호를 입력한 후 로그인을 클릭하면 <form> 태그의 action 속성은 데이터를 전송할 서블릿이나 JSP의 이름을 지정한다. 그러면 지정된 이름이 login인 서블릿으로 ID와 비밀번호를 전송한다.

* 다음은 로그인 창에서 로그인을 클릭했을 때 실제로 데이터가 전송되는 과정이다.

* 실제 데이터는 각 <input> 태그의 name 속성 값과 쌍으로 전송된다. 그럼 서블릿에서는 name 속성 값으로 같이 전송된 입력 데이터를 받아온다.

* <form> 태그와 관련된 여러 가지 속성

속성 기능
name - <form> 태그의 이름을 지정한다.
- 여러 개의 form이 존재할 경우 구분하는 역할을 한다.
- 자바스크립트에서 <form> 태그에 접근할 때 자주 사용한다.
method - <form> 태그 안에서 데이터를 전송할 때 전송 방법을 지정한다.
- GET 또는 POST로 지정한다(아무것도 지정하지 않으면 GET이다).
action - <form> 태그에서 데이터를 전송할 서블릿이나 JSP를 지정한다.
- 서블릿으로 전송할 때는 매핑 이름을 사용한다.
encType - <form> 태그에서 전송할 데이터의 encording 타입을 지정한다.
- 파일을 업로드할 때는 multipart/form-data로 지정한다.

3. 서블릿에서 클라이언트의 요청을 얻는 방법

* HttpServletRequest 클래스에서 <form> 태그로 전송된 데이터를 받아오는 데 사용하는 메서드는 다음이 있다. 이 중에서 가장 많이 사용되는 것이 getParameter() 메서드이다. 만약 같은 name으로 여러 개의 값이 전송되었을 때는 배열 형태로 값을 반환하는 getParameterValues() 메서드를 사용한다.

메서드 기능
String getParameter(String name) name의 값을 알고 있을 때 그리고 name에 대한 전송된 값을 받아오는 데 사용한다.
String[] getParameterValues(String name) 같은 name에 대해 여러 개의 값을 얻을 때 사용한다.
Enumeration getParameterNames() name 값을 모를 때 사용한다.

(1) HttpServletRequest로 요청 처리 실습

* 이번에는 실제로 이클립스에서 <form> 태그로 전송된 정보를 서블릿에서 받아 와서 출력하는 과정을 실습해 보자. 로그인창에서 ID와 비밀번호를 입력 받아 HttpServletRequest로 처리하는 간단한 프로그램이다.

1. pro06이라는 새 프로젝트를 생성한다. 그리고 톰캣의 servlet-api.jar를 클래스 패스에 지정한다.

2. WebContent 폴더 하위에 다음과 같이 사용자 정보를 입력 받을 login.html을 생성한다.

3. login.html 파일을 작성한다.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>로그인 창</title>
	</head>
	<body>
	
		<form name="frmLogin" method="get" action="login" encType="UTF-8">
			<span>아이디 : </span>
			<input type="text" name="user_id" />
			<br />
			
			<span>비밀번호 : </span>
			<input type="password" name="user_pw" />
			<br />
			
			<button type="submit">로그인</button>
			<button type="reset">다시입력</button>
		</form>
	
	</body>
</html>

4. sec01.ex01 패키지를 만들고 요청을 받을 서블릿인 LoginServlet 클래스를 생성한다.

5. 다음과 같이 LoginServlet.java를 작성한다.

package sec01.ex01;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/login") // 서블릿의 매핑 이름이 login이다.
public class LoginServlet extends HttpServlet {

	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메서드 호출");
	}

	// 웹 브라우저에서 전송한 정보를 톰캣 컨테이너가 HttpServletRequest 객체를 생성한 후 doGet()으로 넘겨준다.
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8"); // 전송된 데이터를 UTF-8로 인코딩한다.
		String user_id = request.getParameter("user_id"); // getParameter()를 이용해 <input> 태그의 name 속성 값으로 전송된 value를 받아온다.
		String user_pw = request.getParameter("user_pw");
		System.out.println("아이디 : " + user_id);
		System.out.println("비밀번호 : " + user_pw);
	}

	public void destroy() {
		System.out.println("destroy 메서드 호출");
	}
	
}

6. pro06 프로젝트를 톰캣에 등록하여 실행한 후 브라우저에서 http://localhost:8090/pro06/login.html을 요청한다.

7. 텍스트 박스에 ID와 비밀번호를 입력한 후 로그인을 클릭하면 서블릿이 ID와 비밀번호를 이클립스 콘솔에 출력한다.

* 단, 서블릿이 처리한 후의 응답 기능은 아직 구현하지 않았으므로 웹 브라우저에는 아무것도 출력되지 않는다.


(2) 여러 개의 값을 전송할 때의 요청 처리

* 이번에는 하나의 name으로 여러 값을 서블릿으로 요청하는 방법이다. 예를 들어 로그인 후 수강할 과목을 입력하되 한 번에 여러 과목을 입력해야 등록하는 예제이다. 그럼 서블릿에서는 각 과목에 대한 여러 개의 값을 처리해야 할 것이다.

1. 다음과 같이 input.html을 추가하고 InputServlet 클래스를 새로 만든다.

2. input.html 을 다음과 같이 작성한다. <input> 타입이 여러 개 일때는 체크박스(checkbox)를 사용해서 값을 설정하는 것이 좋다. 체크박스의 name 속성 값은 모두 subject이므로 서블릿으로 전송할 때 배열로 전송된다.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>여러 가지 input 타입 표시 창</title>
	</head>
	<body>
	
		<form name="frmInput" method="get" action="input">
		<!-- <form name="frmInput" method="get" action="input2"> -->
			<span>아이디 : </span>
			<input type="text" name="user_id" />
			<br />
			
			<span>비밀번호 : </span>
			<input type="password" name="user_pw" />
			<br />
			
			<input type="checkbox" name="subject" value="java" checked />
			<span>자바</span>
			<input type="checkbox" name="subject" value="C언어" />
			<span>C언어</span>
			<input type="checkbox" name="subject" value="JSP" />
			<span>JSP</span>
			<input type="checkbox" name="subject" value="Android" />
			<span>안드로이드</span>
			
			<br />
			<br />
			<button type="submit">전송</button>
			<button type="reset">초기화</button>
		</form>
	
	</body>
</html>

3. InputServlet 클래스를 다음과 같이 작성한다. getParameterValues()를 이용해 input.html에서 체크박스의 name인subject로 전송된 값들을 받아 와서 문자열 배열에 저장한다.

package sec01.ex01;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/input")
public class InputServlet extends HttpServlet {

	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메서드 호출");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String user_id = request.getParameter("user_id"); // 한 개씩 전송된 값은 getParameter()를 이용한다.
		String user_pw = request.getParameter("user_pw");
		System.out.println("아이디 : " + user_id);
		System.out.println("비밀번호 : " + user_pw);
		String[] subject = request.getParameterValues("subject"); // 하나의 name으로 여러 값을 전송하는 경우 getParameterValues()를 이용해 배열 형태로 반환된다.
		for(String str : subject) {
			System.out.println("선택한 과목 : " + str);
		}
	}
	
	public void destroy() {
		System.out.println("destroy 메서드 호출");
	}

}

4. 브라우저에서 http://localhost:8090/pro06/input.html로 요청한다.

5. 체크박스에서 여러 개의 값에 체크한 후 전송을 클릭하면 이클립스 콘솔에 해당 과목명이 출력된다.


(3) getParameterNames() 메서드를 이용한 요청 처리

* 하지만 보통 우리가 온라인 쇼핑몰에 회원으로 가입하려면 입력해야 할 회원 정보는 이름, 주소, 전화번호, 결제정보 등 최소 10개 이상, 많으면 20개 정도 된다. 그럼 이 정보를 서블릿에서 getParameter() 메서드를 이용해서 처리하려면 각 매개변수를 모두 알아야 한다.

* 이처럼 전송된 데이터가 많아 일일이 name의 값을 기억하기 힘들 때는 getParameterNames() 메서드를 이용하면 편리하다. 

1. sec01.ex01 패키지에 InputServlet2 클래스를 생성한다.

2. 그리고 input.html을 수정한다.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>여러 가지 input 타입 표시 창</title>
	</head>
	<body>
	
		<form name="frmInput" method="get" action="input2"> // 매핑 이름을 input2로 수정
			<span>아이디 : </span>
			<input type="text" name="user_id" />
			<br />
			
			<span>비밀번호 : </span>
			<input type="password" name="user_pw" />
			<br />
			
			<input type="checkbox" name="subject" value="java" checked />
			<span>자바</span>
			<input type="checkbox" name="subject" value="C언어" />
			<span>C언어</span>
			<input type="checkbox" name="subject" value="JSP" />
			<span>JSP</span>
			<input type="checkbox" name="subject" value="Android" />
			<span>안드로이드</span>
			
			<br />
			<br />
			<button type="submit">전송</button>
			<button type="reset">초기화</button>
		</form>
	
	</body>
</html>

3. inputServlet2 클래스를 다음과 같이 작성한다.

package sec01.ex01;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/input2")
public class InputServlet2 extends HttpServlet {

	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메서드 호출");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		Enumeration enu = request.getParameterNames(); // 전송되어온 name 속성들만 Enumeration 타입으로 받아온다.
		while(enu.hasMoreElements()) {
			String name = (String) enu.nextElement();
			String[] values = request.getParameterValues(name);
			for(String value : values) {
				System.out.println("name = " + name + ", value = " + value);
			} // 각 name을 하나씩 가져와 대응해서 전송되어 온 값을 출력한다.
		}
		
	}

	public void destroy() {
		System.out.println("destroy 메서드 호출");
	}
	
}

4. 브라우저에서 http://localhost:8090/pro06/input.html로 요청하고 값을 입력한 후 전송을 클릭한다. getParameterValues()를 이용해 전송된 name과 값이 모두 출력되는 것을 확인할 수 있다.