안녕하세요! 오늘은 Java 웹 개발의 가장 기본적인 두 기둥, JSP와 Servlet이 어떻게 서로 데이터를 주고받는지 알아보겠습니다.
사용자가 HTML Form에 정보를 입력하고 '전송' 버튼을 눌렀을 때, 그 데이터가 서버로 넘어가 처리되고, 다시 사용자에게 결과 페이지로 보여지는 전체 과정을 예제 코드와 함께 쉽게 따라가 보겠습니다.
여기서 사용된 방식은 "Model 1" 아키텍처라고 불리는데요, 비즈니스 로직(데이터 처리)과 프레젠테이션 로직(화면 표시)이 하나의 JSP나 Servlet 파일에 함께 작성된 구조를 말합니다.
전체 동작 흐름
데이터는 다음과 같은 3단계를 거쳐 이동합니다.
- 입력 (View): 사용자가 웹페이지에서 정보를 입력합니다. (
input_member.html
) - 처리 (Controller & Model): 서버(서블릿)가 사용자의 데이터를 받아서 가공합니다. (
MemberRegisterAction.java
) - 출력 (View): 처리된 결과가 새로운 웹페이지에 표시됩니다. (
result_member.jsp
)
1. 사용자 입력 페이지 (input_member.html
)
모든 과정의 시작입니다. 사용자는 이 HTML 페이지의 폼을 통해 회원가입 정보를 입력합니다.
가장 중요한 부분은 <form>
태그입니다.
action="member_register.do"
: 폼 데이터가 전송될 목적지(서블릿의 URL)를 지정합니다.method="POST"
: 데이터를 HTTP Body에 숨겨서 안전하게 전송하는 방식을 지정합니다.name="..."
: 각<input>
태그의name
속성은 서버에서 데이터를 구분하는 열쇠(Key)가 됩니다. 이name
을 기준으로 서블릿이 값을 꺼내게 됩니다.
<!-- input_member.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>회원가입</title>
<style>
label {
display: inline-block;
width: 120px;
}
</style>
<script type="text/javascript">
// 간단한 유효성 검사 함수
function send(f) {
let name = f.name.value.trim();
if (name == "") {
alert("이름을 입력하세요!");
f.name.focus();
return;
}
// ... (다른 필드 검사) ...
f.submit(); // form 전송
}
</script>
</head>
<body>
<form action="member_register.do" method="POST">
<label>*이름:</label>
<input type="text" name="name" placeholder="이름을 입력하세요" required><br>
<label>*아이디:</label>
<input type="text" name="id" placeholder="ID를 입력하세요" required><br>
<label>*비번:</label>
<input type="password" name="pwd" placeholder="비밀번호를 입력하세요" required><br>
<label>이메일:</label>
<input type="email" name="email" required><br>
<label>성별:</label>
<input type="radio" name="gender" value="남자" checked="checked">남자
<input type="radio" name="gender" value="여자">여자
<br>
<label>취미:</label>
<input type="checkbox" name="hobby" value="독서">독서
<input type="checkbox" name="hobby" value="운동">운동
<input type="checkbox" name="hobby" value="영화">영화
<br>
<label>친구1: <input type="text" name="friend"></label><br>
<label>친구2: <input type="text" name="friend"></label><br>
<br>
<label>혈액형:</label>
<select name="blood">
<option value="A">A</option>
<option value="B">B</option>
</select>
<br>
<label>*자기소개:</label><br>
<textarea name="intro" rows="5"></textarea>
<br>
<input type="submit" value="회원가입(Servlet으로 보내기)">
</form>
</body>
</html>
2. 데이터 처리 서블릿 (MemberRegisterAction.java
)
input_member.html
에서 전송된 데이터는 이제 서버의 서블릿으로 도착합니다. 이 서블릿은 서버의 '두뇌' 역할을 합니다.
@WebServlet("/member_register.do")
: 이 Annotation 덕분에member_register.do
라는 URL 요청을 이 서블릿이 처리할 수 있게 됩니다.request.setCharacterEncoding("UTF-8")
: 한글 파라미터가 깨지지 않도록 인코딩을 설정합니다. 거의 모든 웹에서 UTF-8 형식의 인코딩을 사용하고 있으므로, 국제적인 사이트를 만들기 위해서 이 설정 코드는 꼭 필요합니다.request.getParameter("name")
:name
속성이 'name'인 input의value
를 가져옵니다. 하나의 값을 받을 때 사용합니다.request.getParameterValues("hobby")
:name
속성이 'hobby'인 input들의value
를 배열(Array)로 가져옵니다. '취미'처럼 여러 개를 선택할 수 있는 체크박스나, '친구'처럼 동일한 이름의 입력 필드가 여러 개일 때 사용합니다.
아래 코드에서 비즈니스 로직(데이터 가공)이 끝나고, PrintWriter
를 사용해 직접 HTML 코드를 문자열로 만들어 응답(Response)하는 부분을 주목해 주세요.
// MemberRegisterAction.java
package Action;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/member_register.do")
public class MemberRegisterAction extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 1. 수신 인코딩 설정
request.setCharacterEncoding("UTF-8");
// 2. 파라미터 받기 (Business Logic)
String name = request.getParameter("name");
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String email = request.getParameter("email");
String gender = request.getParameter("gender");
String blood = request.getParameter("blood");
String intro = request.getParameter("intro");
// 동일한 name으로 여러 개의 파라미터가 넘어오는 경우 배열로 받는다.
String[] hobby_array = request.getParameterValues("hobby");
String[] friend_array = request.getParameterValues("friend");
// 받은 취미 배열을 하나의 문자열로 가공
String hobby_list = "취미 없음";
if (hobby_array != null) {
StringBuffer sbHb = new StringBuffer();
for (String hobby : hobby_array) {
sbHb.append("[" + hobby + "]");
}
hobby_list = sbHb.toString();
}
// 받은 친구 배열을 하나의 문자열로 가공
StringBuffer sbFr = new StringBuffer();
for(String friend : friend_array) {
sbFr.append(friend);
sbFr.append(" ");
}
String friend_list = sbFr.toString().trim();
if(friend_list.isEmpty()) { // "" 대신 .isEmpty() 사용을 권장합니다.
friend_list = "친구 없음";
}
// 3. 응답 페이지 만들기 (Presentation Logic)
response.setContentType("text/html; charset=UTF-8;");
PrintWriter out = response.getWriter();
StringBuffer sb = new StringBuffer();
sb.append("<html>");
sb.append("<body>");
sb.append("<table width='400' border='1'>");
sb.append("<caption>:::: 회원 정보 (Servlet) ::::</caption>");
sb.append(String.format("<tr><th>이름</th><td>%s</td></tr>", name));
sb.append(String.format("<tr><th>ID</th><td>%s</td></tr>", id));
sb.append(String.format("<tr><th>성별</th><td>%s</td></tr>", gender));
sb.append(String.format("<tr><th>취미</th><td>%s</td></tr>", hobby_list));
sb.append(String.format("<tr><th>친구목록</th><td>%s</td></tr>", friend_list));
sb.append("</table>");
sb.append("<a href='input_member.html'>다시하기</a>");
sb.append("</body>");
sb.append("</html>");
// 4. 응답하기
out.print(sb.toString());
}
}
서블릿으로 화면을 만드니 어떤가요? sb.append()
를 반복하며 HTML 태그를 문자열로 조립하는 과정이 꽤 번거롭고 가독성도 떨어집니다. 이 불편함을 해결하기 위해 JSP가 등장했습니다!
3. 결과 출력 페이지 (result_member.jsp
)
JSP는 HTML 코드 안에 Java 코드를 넣어 동적인 페이지를 만드는 기술입니다. 서블릿과 정반대의 접근 방식이죠!
<% ... %>
(Scriptlet): 이 태그 안에는 순수한 Java 코드를 작성합니다. 서블릿에서 파라미터를 받던 로직이 그대로 들어왔습니다.<%= ... %>
(Expression): 이 태그는 변수의 값을 화면에 출력할 때 사용합니다.out.print()
와 동일한 역할을 합니다.
서블릿 예제와 비교해 보세요. HTML 뼈대 안에 필요한 데이터만 <%= ... %>
로 쏙쏙 집어넣으니 코드가 훨씬 깔끔하고 직관적입니다. 이것이 바로 JSP를 View단에서 사용하는 가장 큰 이유입니다!
<!-- result_member.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 1. 수신 인코딩 설정 (JSP도 동일하게 필요)
request.setCharacterEncoding("UTF-8");
// 2. 파라미터 받기 (Business Logic)
String name = request.getParameter("name");
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String email = request.getParameter("email");
String gender = request.getParameter("gender");
String blood = request.getParameter("blood");
String intro = request.getParameter("intro");
String [] hobby_array = request.getParameterValues("hobby");
String [] friend_array = request.getParameterValues("friend");
String hobby_list = "취미 없음";
if(hobby_array != null) {
StringBuffer sbHb = new StringBuffer();
for(String hobby : hobby_array) {
sbHb.append("[" + hobby + "]");
}
hobby_list = sbHb.toString();
}
StringBuffer sbFr = new StringBuffer();
for(String friend : friend_array) {
sbFr.append(friend);
sbFr.append(" ");
}
String friend_list = sbFr.toString().trim();
if(friend_list.isEmpty()){
friend_list = "친구 없음";
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입 결과</title>
</head>
<body>
<!-- 3. 응답 페이지 만들기 (Presentation Logic) -->
<table width='400' border='1'>
<caption>:::: 회원 정보 (JSP) ::::</caption>
<tr>
<th>이름</th>
<td><%= name %></td>
</tr>
<tr>
<th>ID</th>
<td><%= id %></td>
</tr>
<tr>
<th>PW</th>
<td><%= pwd %></td>
</tr>
<tr>
<th>이메일</th>
<td><%= email %></td>
</tr>
<tr>
<th>성별</th>
<td><%= gender %></td>
</tr>
<tr>
<th>혈액형</th>
<td><%= blood %></td>
</tr>
<tr>
<th>취미</th>
<td><%= hobby_list %></td>
</tr>
<tr>
<th>친구목록</th>
<td><%= friend_list %></td>
</tr>
<tr>
<th>자기소개</th>
<td><%= intro %></td>
</tr>
<tr>
<td colspan='2' align='center'>
<a href='input_member.html'>다시하기</a>
</td>
</tr>
</table>
</body>
</html>
요점
오늘은 Model 1 방식을 통해 HTML 폼에서 서블릿, 그리고 JSP로 파라미터가 전달되고 처리되는 과정을 살펴보았습니다.
- 서블릿은 데이터를 처리하는 로직에 강점이 있지만, 화면을 그리는 데는 번거롭습니다.
- JSP는 HTML과 유사한 구조 덕분에 동적인 화면을 만드는 데 매우 편리합니다.
이 둘의 장점을 결합하여 로직은 서블릿이, 화면은 JSP가 담당하도록 역할을 분리하는 형태를 Model 2(MVC) 패턴이라고 합니다. 이는 다음 포스팅에서 다뤄보고자 합니다.
'Servlet, JSP' 카테고리의 다른 글
JSP EL(Expression Language)에 대해 (2) | 2025.08.26 |
---|---|
JSP란? 그리고 JSP와 Servlet의 차이는? (0) | 2025.08.19 |
Servlet의 작동구조 (0) | 2025.08.19 |
Servlet 생명주기(Lifecycle) 이해하기 (2) | 2025.08.19 |