7. 서블릿

2023. 3. 27. 17:42Lang/JSP

728x90
반응형

1. 서블릿의 동작 원리

  • 서블릿
    • 자바의 클래스 중 오직 서버에서만 해석되어 실행되는 클래스
    • 서블릿 규약에 따라 만든 클래스
    • 최초 브라우저 접속에 의해 인스턴스가 메모리에 올라간다
  • 서블릿 생성
    • 서블릿 API 이용
    • 패키지 이용
      • javax.servlet
        • 프로토콜에 독립적인 서블릿을 만들기 위한 클래스
      • javax.servlet.http
        • http 프로토콜의 고유 기능 (get, post 등) 을 제공하는 서블릿을 만들기 위한 클래스
  • 서블릿 구현
    • GenericSevlet 이나 HTTPServlet 중 하나를 상속받아 구현
    • main()메서드가 없다
    • 서블릿의 특정 메서드는 웹 컨테이너(서버)가 호출한다
    • 서버가 서블릿에 요청을 전달할 때마다 서블릿의 service() 메서드 호출
    • GenericServlet
      • 요청을 처리하기 위해 자신의 service() 메서드를 오버라이드해야한다
      • service()메서드
        • 두 개의 매개변수(request, response)
    • HttpServlet
      • doGet(), doPost() 메서드를 오버라이드한다

2. 서블릿 작성

  • 서블릿 이용 개발 과정
    • 서블릿 소스코드를 저장할 디렉토리 생성
    • 클래스 파일을 저장할 WEB-INF\classes 디렉토리 생성
    • CLASSPATH 환경변수 설정
      • 톸캣설치지렉토리\lib\servlet-api.jar
    • 서블릿 소스코드 작성
    • 소스코드 컴파일 후 생성된 클래스 파일을 classes 디렉토리에 복사
    • web.xml 파일에 서블릿 정보 설정
    • 웹컨테이너 시작
    • 웹브라우저 테스트
package com.mystudy.serv;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;


@WebServlet("/NowServ")
public class NowServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html; charset=utf-8");
        Date now = new Date();
        PrintWriter writer = response.getWriter();
        writer.println("<html>");
        writer.println("<head><title>현재 시간</title></head>");
        writer.println("<body>");
        writer.println("<b>현재 날짜는:</b>");
        writer.println(now.toString());
        writer.println("<hr></body>");
        writer.println("</html>");
        writer.close();
    }
}

get방식으로 데이터 전송

html

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<BODY>
    <!--GET방식으로 데이터 전송
    사용자가 입력한 데이터는 action에 지정된 GetServlet이라는
    서블릿 페이지로 전달됨-->

    <form action="/mystudy/GetServ" method="GET" >
        아이디: <INPUT TYPE="text" NAME="id"><br>
        비밀번호:<INPUT TYPE="password" NAME="pwd"><br>
        <INPUT TYPE="submit" value="로그인"><INPUT TYPE="reset" value="취소">
    </form>
</BODY>
</html>

서블릿

package com.mystudy.serv;

import java.io.IOException;
import java.io.PrintWriter;

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("/GetServ")
public class GetServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //응답문서에 대한 ContentType 지정
        response.setContentType("text/html;charset=euc-kr");

        //출력스트림
        PrintWriter out = response.getWriter();

        //1.
        String id = request.getParameter("id");
        String pwd = request.getParameter("pwd");

        //2

        //3
        out.print("<html><head><title>get~servlet연습</title></head>");

        out.print("<body>");
        out.print("<h1>요청 파라미터 값</h1>");
        out.print("<p>id : "+id+"</p");
        out.print("<p>pwd : "+pwd+"</p");
        out.print("</body>");

        out.close();

    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

}

post 방식으로 데이터 전송

html

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<BODY>
    <!--GET방식으로 데이터 전송
    사용자가 입력한 데이터는 action에 지정된 GetServlet이라는
    서블릿 페이지로 전달됨-->

    <form action="/mystudy/PostServ" method="POST" >
        아이디: <INPUT TYPE="text" NAME="id"><br>
        비밀번호:<INPUT TYPE="password" NAME="pwd"><br>
        <INPUT TYPE="submit" value="로그인"><INPUT TYPE="reset" value="취소">
    </form>
</BODY>
</html>

서블릿

package com.mystudy.serv;

import java.io.IOException;
import java.io.PrintWriter;

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("/PostServ")
public class PostServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //응답문서에 대한 ContentType 지정
        response.setContentType("text/html;charset=euc-kr");
        request.setCharacterEncoding("euc-kr");

        //출력스트림
        PrintWriter out = response.getWriter();

        //1.
        String id = request.getParameter("id");
        String pwd = request.getParameter("pwd");

        //2

        //3
        out.print("<html><head><title>get~servlet연습</title></head>");

        out.print("<body>");
        out.print("<h1>요청 파라미터 값</h1>");
        out.print("<p>id : "+id+"</p");
        out.print("<p>pwd : "+pwd+"</p");
        out.print("</body>");

        out.close();
    }

}

3. 웹 컨테이너

  • 사용자가 서블릿에 대한 링크를 클릭
  • 웹 컨테이너는 들어온 요청이 서블릿이라는 것을 파악
    • HttpServletResponse 와 HttpServletRequest 객체를 생성
  • 사용자가 보낸 URL을 분석, 어떤 서블릿에 대한 요청인지 파악
    • DD : web.xml 참조
    • 해당 서블릿 스레드를 생성, Request / Response 객체를 인자로 넘긴다
  • 웹 컨테이너는 서블릿 service() 메서드 호출
    • 요청에 지정한 방식에 따라 doGet() / doPost() 호출 결정
  • doGet() / doPost() 메서드는 동적인 페이지 생성
    • 이를 Response 객체에 실어 전송
    • 보낸 후에도 웹컨테이너는 Response 객체에 대한 참조값 보유
  • 스레드 작업 종료 후 웹 컨테이너는 Response 객체를 HTTP Response로 전환하여 클라이언트로 전송
    • 마지막으로 Request와 Response 객체를 소멸

4. 서블릿 라이프 사이클

캡처

  • 서블릿이 처음 로드 되면 init()메서드 호출
    • 서블릿이 서비스하기 위해 필요한 초기화작업 수행
    • service()메서드 호출
  • 초기화된 서블릿은 클라이언트의 요청이 있을 때마다 쓰레드 생성
    • 병행적으로 service()메서드 실행
  • 서블릿은 더이상 서비스하지 않을 경우 서블릿 엔진에 의해 메모리에서 unload
    • unload 되기 전 destroy()메서드 실행

라이프 사이클 확인

package com.mystudy.serv;

import java.io.IOException;
import java.io.PrintWriter;

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("/LifeCycle")
public class LifeCycle extends HttpServlet {

    private static final long serialVersionUID = 1L;


    public LifeCycle() {
        super();
        System.out.println("생성자 호출");
    }

    @Override
    public void destroy() {
        System.out.println("destroy() 호출");
    }


    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init() 호출");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 서블릿은 클라이언트의 요청이 있을 때마다 쓰레드가 생성되어 병행적으로 service()메서드 실행

        System.out.println("doGet()호출");
        response.setContentType("text/html;charset=euc-kr");
        PrintWriter out = response.getWriter();

        out.print("<html><head><title>서블릿 생명주기</title></head>");
        out.print("<body>");
        out.print("<h1>현재 쓰레드이름</h1>");
        out.print("<p>"+Thread.currentThread().getName()+"<p>");
        out.print("</body></html>");
    }



    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

}

5. 서블릿의 호출

  • 어노테이션
    • @webServlet("/경로명")
    • 경로명 요청 시 해당 어노테이션 아래 서블릿 클래스로 처리
@WebServlet("/InsertServ")
public class InsertServlet extends HttpServlet {}

//http://localhost:9090/mystudy/InsertServ 요청 시
//InsertServlet 클래스로 처리
  • web.xml 수정
    • web-inf 폴더 내 web.xml로 매핑
      <servlet>
        <servlet-name>listServ</servlet-name>
        <servlet-class>com.mystudy.pd.serv.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>listServ</servlet-name>
        <url-pattern>/ListServ</url-pattern>
    </servlet-mapping>

6. 서블릿 예제

registerPd.html

<HTML>
<HEAD>
<TITLE> registerPd.html </TITLE> 
</HEAD>
<BODY>
    <form name="frm" method="POST" action="/mystudy/InsertServ">
        상품명: <INPUT TYPE="text" NAME="pdName"><br>
        가격:<INPUT TYPE="text" NAME="price"><br>
        <INPUT TYPE="submit" value="등록">
        <INPUT TYPE="reset" value="취소">
    </form>
</BODY>
</HTML>

insertServ.java 서블릿

package com.mystudy.pd.serv;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

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

import com.mystudy.pd.model.PdDAO;
import com.mystudy.pd.model.PdDTO;

/**
 * Servlet implementation class InsertServlet
 */
@WebServlet("/InsertServ")
public class InsertServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //응답 문서에 대한 타입 지정
        response.setContentType("text/html;charset=euc-kr");

        //출력스트림 업어도기
        PrintWriter out = response.getWriter();

        //1 요청파라미터
        request.setCharacterEncoding("euc-kr");

        String pdName = request.getParameter("pdName");
        String price = request.getParameter("price");

        //2 db작업
        PdDAO dao = new PdDAO();
        PdDTO dto = new PdDTO();

        dto.setPrice(Integer.parseInt(price));
        dto.setPdName(pdName);

        try {
            int cnt = dao.insertPd(dto);

            //3 결과처리
            if(cnt>0) {
                response.sendRedirect("/mystudy/ListServ");
            }else {
                System.out.println("등록 실패");
                out.println("등록 실패");
                response.sendRedirect("/mystudy/servTest/registerPd.html");

            }
        }catch(SQLException e){
            e.printStackTrace();
        }

        out.close();
    }
}

ListServ.java

package com.mystudy.pd.serv;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mystudy.pd.model.PdDAO;
import com.mystudy.pd.model.PdDTO;

//@WebServlet("/ListServ")
public class ListServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 응답문서에 대한 콘텐츠 타입 지정
        response.setContentType("text/html;charset=euc-kr");

        // 출력스트림 얻어오기
        PrintWriter out = response.getWriter();

        //1

        //2
        PdDAO dao = new PdDAO();
        PdDTO dto = new PdDTO();
        List<PdDTO> list = null;
        DecimalFormat df = new DecimalFormat("#,###");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        try {
            list = dao.selectAll();

        }catch(SQLException e) {
            e.printStackTrace();
        }    
        //3

        out.print("<html><head><title>상품 목록</title></head>");
        out.print("<body>");
        out.print("<table border='1'>");
        out.print("<tr><th>번호</th><th>상품명</th><th>가격</th><th>등록일</th></tr>");
        for(int i=0; i<list.size(); i++) {
            dto = list.get(i);

            out.print("<tr>");
            out.print("<td>"+dto.getNo()+"</td>");
            out.print("<td><a href='/mystudy/DetailServ?no="+dto.getNo()+"'>"+dto.getPdName()+"</td>");
            out.print("<td>"+df.format(dto.getPrice())+"</td>");
            out.print("<td>"+sdf.format(dto.getRegdate())+"</td>");
            out.print("</tr>");
        }
        out.print("</table>");
        out.print("<a href='/mystudy/servTest/registerPd.html'>상품 등록</a>");
        out.print("</body></html>");
        out.close();


    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

}
728x90
반응형

'Lang > JSP' 카테고리의 다른 글

9. 커넥션풀, 싱글톤패턴  (0) 2023.03.27
8. 게시판 만들기  (0) 2023.03.27
6. jsp 와 jdbc  (0) 2023.03.27
5. http, get과 post  (0) 2023.03.27
3. JSP 페이지의 구성 요소  (0) 2023.03.27