• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java EE 정리 02

26 Feb 2019

Reading time ~5 minutes

Java EE 정리 02 - Servlet 요청처리, Servlet Life Cycle, Class Life Cycle Servlet 호출


Servlet 요청처리(전체 흐름)

01

  1. HDD에 Web 서비스할 폴더를 등록한다.(server.xml)
  2. Source Code(Servlet) 작성
  3. DD(Deployement Descriptor, web.xml)에 작성한 Servlet을 기술(Servlet Mapping)
  4. 요청 대기
  5. 클라이언트가 웹 브라우저를 통해 요청
  6. 요청한 URL을 웹컨테이너가 분석
  7. 응답
  8. 웹 브라우저가 HTML을 응답받아 화면에 그림

Servlet 요청 처리(네트워크 관점)

02

  1. 서버 포트 열기
  2. 서비스되는 폴더를 Mapping(server.xml)
  3. DD Loading(web.xml)
  4. 대기
  5. 웹브라우저 실행
  6. URL 입력
  7. 접속자가 접속하면서 생성된 Socket으로부터 RequestFacade, ResponseFacade가 생성
  8. 요청을 처리하는 서블릿 객체 생성
  9. 요청 방식(GET/POST)에 맞는 method 호출
  10. 요청 방식에 맞는 doGet 또는 doPost 호출
  11. HttpServletResponse 객체 변수를 이용 MIME Type 설정
  12. ResponseFacade로부터 스트림을 얻음
  13. 얻은 스트림에 응답내용을 누적
  14. HTML을 응답
  15. 클라이언트는 응답받은 HTML을 웹브라우저 그림

Servlet Life Cycle

  • 객체의 생성, 사용, 소멸 단계
  • Lifecycle은 Container가 관리
  • GenericServlet이 Lifecycle에 대한 method를 제공
    • init()
      • 생성자의 역할을 하는 method
      • 최초 접속자에 의해서 1번 호출됨
      • 객체생성 시 초기화되어야할 값을 설정하거나 실행되어야할 코드를 정의
    • service, doGet, doPost
      • 업무처리(요청, 응답처리)
      • 접속자에게 보여줄 페이지 생성
      • 접속한 접속자 수대로 수행
    • destroy()
      • 객체가 소멸될 때 호출되는 method
      • Web Container Instance가 사라질 때 호출됨
        • 접속자가 연결을 끊는다고 호출되는게 아님!
      • 가장 마지막에 1번 호출됨
  • 첫번째 접속하는 사람은 요청한 서블릿 객체를 생성되고 응답받기 때문에 가장 느리다.
    • 두번째 접속하는 사람은 서블릿 객체가 객체가 생성되어 있기 때문에 빠르게 응답을 받는다.

03

  • Servlet Life Cycle 예
    • 콘솔창에서 Terminate로 서버를 종료시키면 비정상 종료이므로 destroy()가 불리지 않음
      • Server 탭에서 Stop으로 서버를 정상 종료시키면 destroy()가 호출됨
// 1. HttpServlet 상속
@SuppressWarnings("serial")
public class LifeCycle extends HttpServlet {
     
     // 생명주기 method
     public void init() {
           System.out.println("===> init method : 최초 접속자에  의해 1번 호출(생성자 역할) ");
     }
     
     public void destroy() {
           System.out.println("===> destroy method : Web  Container가 종료될 때 객체가 사라지면서 1번 호출");
     }

     // 2. 응답방식에 대한 처리 method를 Override
     @Override
     protected void doGet(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           
           // 3. 응답방식 설정(MIME-TYPE 설정)
           resp.setContentType("text/html;charset=UTF-8");
           
           // 4. 출력스트림 얻기
           PrintWriter out = resp.getWriter();
           
           // 5. 응답내용 생성
           out.println("<strong>방문자 정보</strong><br/>");
           out.print("<strong>접속자 ip : </strong>");
           out.print(req.getRemoteAddr());
           out.println("에서 접속하셨습니다.");
           out.flush();
           
           System.out.println("---> service, doGet, doPost :  모든 접속자에게 호출. 여러번 호출 "+req.getRemoteAddr());
     }
}

04

Class Life Cycle

  • 생성->method->소멸
    • 생성 - 생성자
    • method - 정의한 method
    • 소멸 - Object.finalize()
      • C에서는 개발자가 직접 소멸자를 사용해서 소멸시킴
      • Java에서는 Gabage Collector(GC)가 heap에 생성된 객체를 소멸시킴
        • GC가 소멸시키는 기준
          • 참조되지 않는 객체
          • 일정기간 사용하지 않아 앞으로도 사용될 확률이 없는 객체
        • 자동동작(언제 동작하는지는 알 수 없음)
        • 개발자가 호출가능(System.gc())
          • GC가 동작하면 시스템에 부하가 걸린다.
          • 직접 호출은 비권장

05

  • finalize() 예
public class Person {
     private String name;
     
     public Person(String name) {
           this.name = name;
           System.out.println("신입사원 "+name+"님  입사하셨습니다.");
     }
     
     @Override
     protected void finalize() throws Throwable { // GC에 의해  객체가 소멸될 때 호출된다.
           System.out.println(name+"님이 퇴사하셨습니다.");
     }
     
     public String getName() {
           return name;
     }
}
/**
* Garbage Collector를 호출하여 객체를 소멸시키기
* (메모리의 여유공간 확보)
* 이재현 사원의 모함으로 다른 사원들은 모두 짤려버림
* @author owner
*/
public class UseGarbageCollector {
     
     public static void main(String[] args) {
           
           Person p = new Person("이재찬");
           p = new Person("김정윤");
           p = new Person("정택성");
           p = new Person("공선의");
           p = new Person("이재현");
           
           System.gc(); // GC 호출
           
           System.out.println("남은 사원 : "+p.getName());
     }
}

06

Servlet 호출

  • GET방식
    • doGet method에서 업무처리
<!-- 링크 호출 -> GET -->
<a href="서블릿 url-mapping명">
// JavaScript 호출 -> GET
location.href="서블릿 url-mapping명";
<!-- form 호출 -> GET, method 생략하면 기본이 GET방식 -->
<form method="get" action="서블릿 url-mapping명">
    ...
    <input type="submit">
</form>
  • POST방식
    • doPost method에서 업무처리
<!-- POST방식은 form 호출 방식만 가능 -->
<form method="post" action="서블릿 url-mapping명">
    ....
    <input type="submit">
</form>

GET/POST 방식 Servlet 호출 예

  • TestCall.java(Servlet)
// 1. HttpServlet 상속
@SuppressWarnings("serial")
public class TestCall extends HttpServlet {

     // 2. 요청방식을 처리할 수 있는 method Override
     protected void doGet(HttpServletRequest request,  HttpServletResponse response) throws ServletException,  IOException {
          // 3. 응답방식 설정
          response.setContentType("text/html;charset=UTF-8");
          
          // 4. 출력스트림 얻기
          PrintWriter out = response.getWriter();
          
          // 5. 출력 내용 생성
          out.println("<!DOCTYPE html>");
          out.println("<html>");
          out.println("<head>");
          out.println("<title>GET 방식의  요청처리</title>");
          out.println("<style type='text/css'>");
          out.println("span { font-weight:bold;  font-size:20px; color:#0000FF } ");
          out.println("</style>");
          out.println("</head>");
          out.println("<body>");
          out.println("<span>GET방식  요청처리</span><br/>");
          out.println("<a  href='date0226/call_servlet.html'>뒤로</a>");
          out.println("</body>");
          out.println("</html>");
     }

     // 2. 요청방식을 처리할 수 있는 method Override
     protected void doPost(HttpServletRequest request,  HttpServletResponse response) throws ServletException,  IOException {
          // 3. 응답방식 설정
          response.setContentType("text/html;charset=UTF-8");
          
          // 4. 출력스트림 얻기
          PrintWriter out = response.getWriter();
          
          // 5. 출력 내용 생성
          out.println("<!DOCTYPE html>");
          out.println("<html>");
          out.println("<head>");
          out.println("<title>POST 방식의  요청처리</title>");
          out.println("<style type='text/css'>");
          out.println("span { font-weight:bold;  font-size:15px; color:#FF0000 } ");
          out.println("</style>");
          out.println("</head>");
          out.println("<body>");
          out.println("<span>POST방식  요청처리</span><br/>");
          out.println("<a  href='javascript:history.back()'>뒤로</a>");
          out.println("</body>");
          out.println("</html>");
     }
}
  • call_servlet.html
<body>
<div id="wrap">
<!--
     서블릿 요청 URL :  http://localhost:8080/servlet_prj/test_call
     HTML 요청 URL :  http://localhost:8080/servlet_prj/date0226/call_servlet.html
     -->
     
     <div id="get">
          <strong>GET방식 요청</strong>
          <div>
               <ul>
                    <li>&lt;a&gt;태그 : <a  href="../test_call">요청</a></li>
                    <li>
                    location.href 요청 : <a href="#void"  class="link">JavaScript 요청</a>
                    <input type="button"  value="JavaScript 요청" class="btn" id="btnJSGet">
                    </li>
                    <li>
                    <!-- JavaScript에서 method와  action을 설정하여 이동 -->
                    <form name="getFrm">
                         <input type="submit" value="get  요청" class="btn" id="btnGet"/>
                    </form>
                    </li>
               </ul>
          </div>
     </div>
     <div id="post">
          <strong>POST방식 요청</strong>
          <div>
               <form action="../test_call" method="post"  id="postFrm">
               <input type="button" value="post 요청"  class="btn" id="btnPost"/>
               </form>
          </div>
     </div>
</div>
</body>
#wrap {
     width: 500px;
     height: 400px;
     margin:0px auto;
}
#get {
     width: 220px;
     height: 150px;
     border: 1px solid #333;
     border-radius: 10px;
     box-shadow: 10px 10px 10px #333;
     float: left;
     padding-top:10px;
     padding-left:5px;
}
#post {
     width: 220px;
     height: 150px;
     border: 1px solid #333;
     border-radius: 10px;
     box-shadow: 10px 10px 10px #333;
     float: right;
     padding-top:10px;
     padding-left:5px;
}
$(document).ready(function() {
     
     $(".link").click(function() {
           movePage();
     });
     
     $("#btnJSGet").click(function() {
           movePage();
     });
     
     $("#btnGet").click(function() {
           // JavaScript에서 action과 method를 변경
           
           // JavaScript로 속성 변경
           var obj = document.getFrm;
           // method 변경 : obj.method="변경할 method";
           // action 변경 : obj.action = "변경할 action"
           
           obj.method="get";
           obj.action="../test_call";
           
           /*// jQuery로 속성변경
           var obj = $("[name='getFrm']");
           obj.prop("method","get");
           obj.prop("action","../test_call"); */
           
           obj.submit();
     });
     
     $("#btnPost").click(function() {
           $("#postFrm").submit();
     });
});
function movePage() {
     if(confirm("이동하시겠습니까?")) {
           // location.href="../test_call"; // 뒤로가기 가능
           location.replace("../test_call");
     }
}

07



Java EEServlet