본문 바로가기
기초 및 언어/▶ Java&JSP

27. Servlet

by 류딩이 2025. 9. 16.

Servlet 서블릿이란?

  • 자바 클래스 형태의 웹 어플리케이션
  • 웹 응용프로그램을 만들어내기 위한 자바 클래스 기술
  • 클라이언트(보통 웹 브라우저) 요청을 받아서 처리하고, 그 결과를 응답으로 돌려주는 역할
  • Tomcat과 같은 WAS(Web Application Server)위에서 동작

✅ JSP → Servlet 변환 경로

JSP 파일 (Ex01.jsp)
      ↓   [톰캣 변환]
서블릿 파일 (Ex01_jsp.java)
      ↓   [컴파일]
클래스 파일 (Ex01_jsp.class)
      ↓   [실행 - JVM]
브라우저에 HTML 결과 출력

 

 

C:\JSP_ljr\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost

 

서블릿 파일 경로 : 

C:\JSP_ljr\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\07_EL_JSTL\org\apache\jsp

C:\JSP_ljr\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\
   └─ work\
      └─ Catalina\
         └─ localhost\
            └─ 07_EL_JSTL\        ← 프로젝트(웹 애플리케이션) 컨텍스트 루트
               └─ org\
                  └─ apache\
                     └─ jsp\
                        Ex06_005fresult_jsp.java   ← 변환된 서블릿 파일
                        Ex06_005fresult_jsp.class  ← 컴파일된 클래스 파일

 

 

더보기

서블릿 컴파일

 

JSB ==> JAVA

컴파일이 되어 class확장자(기계언어)로 바뀜

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.80
 * Generated at: 2025-09-16 06:17:07 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class Ex06_005fform_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP들은 오직 GET, POST 또는 HEAD 메소드만을 허용합니다. Jasper는 OPTIONS 메소드 또한 허용합니다.");
        return;
      }
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("    \r\n");
      out.write("    \r\n");
      out.write("<form action=\"Ex06_result.jsp\">\r\n");
      out.write("    <input type=\"checkbox\" name=\"fruit\" value=\"포도\" checked=\"checked\">포도\r\n");
      out.write("    <input type=\"checkbox\" name=\"fruit\" value=\"사과\" checked=\"checked\">사과\r\n");
      out.write("    <input type=\"checkbox\" name=\"fruit\" value=\"수박\">수박\r\n");
      out.write("    <input type=\"submit\" value=\"전송\">\r\n");
      out.write("</form>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

 

1. Servlet파일 생성하기

 

 

 

2. Servlet파일 실행

Servlet은 Run As로 실행해야한다.

 

 

2. Servlet파일 실행 - url mapping

 

Servlet 생명주기 전체 그림 (생성자 → init → doGet/doPost → destroy)

최초 요청:   생성자 → init() → doGet()/doPost()
이후 요청:   doGet()/doPost()만 실행
코드 변경:   destroy() 호출 → 객체 소멸
다시 요청:   새 객체 생성 → init() 실행 → doGet()/doPost()
package myPkg;

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;

/**
 * Servlet implementation class HelloServlet
 */
@WebServlet("/hi") // 요청명 (url mapping)
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * Default constructor. 
     */
    public HelloServlet() {
        System.out.println("HelloServlet() 생성자");
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		 System.out.println("init 메서드");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		 System.out.println("destroy 메서드");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 System.out.println("doGet() 메서드");
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost() 메서드");
	}

}

 


 

서블릿 파일

Test.java

@WebServlet("/test.do")

 

package myPkg;

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;

/**
 * Servlet implementation class Test
 */

// @:annotaion
@WebServlet("/test.do")
public class Test extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Test() {
        super();
        System.out.println("Test");
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		 System.out.println("init");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		 System.out.println("destroy");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 System.out.println("doGet");
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost");
		doGet(request, response);
	}

}

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	function movePage(){
		location.href = "test.do";
	}
</script>

<a href="test.do">링크</a><br>
<br><hr>

<input type="button" value="요청" onClick="movePage()">

<form method="get" action="test.do">
	<input type="submit" value="호출1">
</form>

<form method="post" action="test.do">
	<input type="submit" value="호출2">
</form>

 

Servlet get방식 목록 📌 Servlet GET 방식 요청 방법
1. 1. <a> 태그 (HTML 하이퍼링크) :  a태그 <a href="helloServlet?name=iu&age=30">링크 클릭</a>
2. 주소창에 요청명 직접 쓰기 http://localhost:8080/myweb/helloServlet?name=iu&age=30
3. location 객체를 통한 요청  location.href = "helloServlet?name=iu&age=30";
4. form method = "get" <form method="get">

 

 


🌈 Servlet 예제: insertServlet (데이터 전달 → JSP 출력) - 예제1

insertform.jsp (입력폼)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

    <form action="insert.per" method="post"> 
    	이름 : <input type="text" name="name"><br>
    	<input type="submit" value="전송">
    </form>
    
   <!--  servlet으로 넘어갔다 => 응답형태로 console로 출력 -->

insertForm에서 정보를 입력하면 ==> servalet 으로 이동 ==> p 변수를 통해  result.jsp에 출력

insertServlet.java  (서블릿파일)

@WebServlet("/insert.per")
public class insertServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// 1) 한글 인코딩 처리
		request.setCharacterEncoding("UTF-8");

		// 2) 파라미터 가져오기
		String name = request.getParameter("name");
		System.out.println("name : " + name);

		// 3) 브라우저로 직접 출력 (PrintWriter)
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter pw = response.getWriter();
		pw.print("이름 : " + name);

		// 4) 자바 객체 생성 → request에 저장
		Person per = new Person("태연", 30, 178.3);
		request.setAttribute("p", per);

		// 5) result.jsp로 포워딩
		RequestDispatcher dispatcher = request.getRequestDispatcher("result.jsp");
		dispatcher.forward(request, response);
	}
}

 

 

⚫  request.setCharacterEncoding("UTF-8") → 서블릿 파일에서 POST 한글 처리 필수

⚫  request.getParameter("name") → form에서 넘어온 값 읽기

⚫  request.setAttribute("p", per) → JSP로 객체 전달

⚫  dispatcher.forward(request, response) → 같은 request 객체를 공유하며 이동


result.jsp

<%@page import="myPkg.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
result.jsp<br>
insertForm.jsp => InsertServlet => result.jsp<br>

<!-- Servlet에서 사용한 request객체를 공유한다. == forward Action태그와 같다.  -->  

<!-- 1) 파라미터 직접 읽기 -->
result.jsp name1 : <%=request.getParameter("name") %> <p>   

<%
    // 2) Servlet에서 setAttribute("p", per)로 전달한 객체 꺼내기
    Person obj = (Person)request.getAttribute("p");
    System.out.println("obj.getName : " + obj.getName());
%>

<!-- 3) Person 객체 출력 -->
Person name : <%= obj.getName() %> <p>
Person age : <%= obj.getAge() %><p>
Person height : <%= obj.getHeight() %><p>

 

⚫ request.getParameter("name")
→ form에서 넘어온 단일 입력값을 그대로 읽음

→ 단, forward 된 경우에도 유지됨

 

⚫ request.getAttribute("p")

→ Servlet이 만든 Person 객체를 JSP에서 받음
→ EL 문법을 쓰면 더 간단하게 출력 가능:

 

 

⚫  forward
→ request와 response를 그대로 넘기기 때문에 파라미터와 속성을 둘 다 사용할 수 있음

 

 

🌈 RequestDispatcher vs sendRedirect

  • dispatcher.forward()
    • 서버 내부 이동 (URL 안 바뀜)
    • request / response 객체 그대로 전달
    • equest를 result.jsp와 공유한다. ==>  result.jsp 그대로 전달
    •  "p" 속성도 그대로 살아있음
  • response.sendRedirect()
    • 클라이언트에게 새 요청 보내도록 지시 (URL 바뀜)
    • request 초기화됨 → 데이터 유지 불가

 


 

결과출력

✅예제1 정리

  1. Servlet에서 DB 조회나 로직 처리 → 결과를 per 객체에 담음
  2. request.setAttribute("p", per); 로 JSP에 보낼 데이터 저장
  3. dispatcher.forward(request, response); 로 result.jsp에 포워드
  4. result.jsp에서 ${p} EL로 데이터 출력

 


🌈 Servlet 예제: insertServlet (데이터 전달 → JSP 출력) - 예제2

요청 흐름 : form에 입력한 값 insertServlet → result.jsp

 

 

1. form.jsp (입력 폼 method="post")

프로젝트 파일 Run As --> 주소창에 요청명 입력 --> http://localhost:8080/09_Servlet/form 

 

🔽전체코드

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
form.jsp<br>


<form method="post" action="insertProc">
	<table border="1">
        <tr>
            <td>이름</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>나이</td>
            <td><input type="text" name="age">
        </tr>
        <tr>
            <td>성별</td>
            <td><input type="radio" name="gender" value="남자">남자 <input
                type="radio" name="gender" value="여자">여자</td>
        </tr>
        <tr>
            <td>취미</td>
            <td><input type="checkbox" name="hobby" value="독서">독서 
            <input type="checkbox" name="hobby" value="등산">등산 
            <input type="checkbox" name="hobby" value="운동">운동 
            <input type="checkbox" name="hobby" value="낚시">낚시</td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="submit" value="전송">
                <input type="reset" value="취소">
            </td>
        </tr>
    </table>

</form>

 

2. insertServlet.java (서블릿 파일)

@WebServlet("/insertProc")   // url-pattern 지정
public class insertServlet extends HttpServlet {

    // 기본 생성자
    public insertServlet() {
        super();
    }

    // init() : 최초 요청 시 1번 실행 (초기화 작업)
    public void init(ServletConfig config) throws ServletException {
    }

    // destroy() : 서버 종료 시 실행 (자원 해제)
    public void destroy() {
    }

    // doGet() : GET 방식 요청 처리
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    // doPost() : POST 방식 요청 처리
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        // 1) 한글 인코딩 처리
        request.setCharacterEncoding("UTF-8");

        // 2) 클라이언트가 보낸 데이터 받기
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String gender = request.getParameter("gender");
        String[] hobby = request.getParameterValues("hobby"); // 체크박스 여러 값

        // 3) MemberBean 객체 생성
        MemberBean mb = new MemberBean(name, age, gender, hobby);

        // 4) request 객체에 저장 (공유)
        request.setAttribute("mb", mb);

        // 5) JSP로 포워딩
        RequestDispatcher dispatcher = request.getRequestDispatcher("result.jsp");
        dispatcher.forward(request, response);
    }
}

 

2. result.jsp

⚫ Servlet에서 전달된 데이터

  • insertServlet → MemberBean 객체(mb)를 request.setAttribute("mb", mb) 로 전달
  • result.jsp에서 request.getAttribute로 객체 꺼내기
  • 또한 form 파라미터(name, hobby)도 함께 넘어옴
<%@page import="myPkg.MemberBean"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

result.jsp<br>

<%
    // form에서 넘어온 파라미터 배열 (체크박스 같은 경우)
    String[] hobby = request.getParameterValues("hobby");

    // Servlet에서 setAttribute 한 객체 꺼내기
    MemberBean member = (MemberBean)request.getAttribute("mb");

    // JSP의 pageContext에 저장 → EL에서 ${member} 로 접근 가능
    pageContext.setAttribute("member", member);
%>

 

출력방식

✅ 스크립트릿 방식 (Java 코드 직접 사용)

name1: <%= member.getName() %> <br>
name2: <%= request.getParameter("name") %> <br>

✅ EL(Expression Language) 방식

name3: ${param.name} <br>        <!-- 파라미터 바로 출력 -->
name4: ${param['name']} <br>    <!-- 파라미터 대괄호 방식 -->
name5: ${member.name} <br>      <!-- MemberBean getter 호출 -->
name6: ${member['name']} <br>   <!-- Bean 프로퍼티 대괄호 방식 -->

 

✅ hobby 출력 비교 (체크박스)

<!-- 1) 스크립트릿 for문 -->
hobby1 :
<%
    for(String h : hobby){
        out.print(h + " ");
    }
%>

<!-- 2) EL (배열 자체 출력: 주소값 느낌) -->
hobby2 : ${paramValues.hobby} <br>

<!-- 3) JSTL forEach -->
hobby3 :
<c:forEach var="h" items="${paramValues.hobby}" varStatus="ss">
    ${h}
    <c:if test="${not ss.last}">,</c:if>   <!-- 마지막이 아니면 , 출력 -->
</c:forEach>

 

✅핵심 정리

  • 스크립트릿 방식: Java 코드 직접 작성 → 오래된 방식, 지양
  • EL 방식: request 파라미터, 속성, Bean 프로퍼티 접근 가능 → 간결
  • JSTL forEach: 배열·List 반복 처리할 때 가장 깔끔