You are using an outdated browser. Please upgrade your browser to improve your experience.

11/24 bitcamp-web-project ex01~이어서

ex01 - 서블릿 콘테이너가 관리하는 세 종류 메서드

  1. init()
  2. service()
  3. destroy()

톰캣에 있는 web server는 기능이 허접해서 다른 웹서버로 교체하는 일이 많고 톰캣의 기능은 보통 application server를 많이 쓴다.

큰 프로그램 안에 글쓰기 기능은 아주 작은 조각일 뿐임 = 그래서 servlet!

image

이 방법은 위험하다. 다른 개발자가 업로드 직전에 해킹 코드를 심으면 언제 심었는지 알 수 없기 때문이다. 그래서 직접 배포파일을 서버에 올리는 것은 좋지 않다.

image

바뀐 방법은 이와 같다. 깃의 구조와 동일함

Command객체들을 미리 만들어 두는 것은 메모리 낭비이므로 객체생성을 요청할 때 딱 한번 호출된 뒤 service()를 호출한다.

web.xml dd파일 만들어서 서블릿 배포하기

  <servlet>
    <servlet-name>s01</servlet-name>
    <servlet-class>com.eomcs.web.ex01.Servlet01</servlet-class>
  </servlet>
<!-- 서블릿 등록 -->
  <servlet>
    <servlet-name>s01</servlet-name>
    <servlet-class>com.eomcs.web.ex01.Servlet01</servlet-class>
  </servlet>

<!-- 서블릿을 실행할 때 사용할 URL path를 설정 -->
  <servlet-mapping>
    <servlet-name>s01</servlet-name>
    <url-pattern>/ohora/haha</url-pattern>
  </servlet-mapping>  

웹 브라우저에서 /ohora/haha로 실행해보면 정상적으로 실행되는 것을 알 수 있다.

ex02패키지

filter와 listener만들기

listener 애노테이션에는 이름을 안준다. 경로로 바로 실행하기 때문이다.

서블릿 컨테이너가 넘기는 것은 두개 -> 프로토콝과 관계없이 넘기기 위해서 -> service(ServletRequest, ServletResponse) 두개의 일반적인 파라미터를 넘김.

왜 귀찮게 항상 ` HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();` 처럼 HttpServlet으로 형변환 해줘야 하는가?

본래 기본 ServletRequest, ServletResponse두개의 값을 넘긴 것은 특정 파라미터에 종속되지 말도록 범용성을 위한 것이였지만 현대에 client는 무조건 web browser의 HTTP프로토콜을 사용하기 때문에 꼭 형변환을 붙여야 한다. 이유를 알고 쓰자.

@Override
  public void requestInitialized(ServletRequestEvent sre) {
    // 요청이 들어 왔을 때 호출된다.
    System.out.println("Listener02.requestInitialized()");
    HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
    System.out.println("클라이언트 IP: " + request.getRemoteAddr());
    System.out.println("요청 URL: " + request.getServletPath());
  }

IP를 출력하면 어디서 해킹을 시도햇는지 로그 기록을 넘길 수 있다. File로 만들어서 출력시키면 됨. Filter에서 해도 되지만 Listener는 조건없이 무조건 실행하기 때문에 취향껏..

Observer 패턴 : 특정 객체 상태가 변할 때 마다 보고받는 디자인 패턴 기법

// 필터 실행 순서 // => 필터의 실행 순서를 임의로 조정할 수 없다. // => 필터를 정의할 때 순서에 의존하는 방식으로 프로그래밍 하지 말라. // => 필터의 실행 순서에 상관없이 각 필터가 독립적으로 동작하도록 작성하라.

한글깨짐 처리하기

// 한글 깨짐 처리하기
    // => 출력 스트림을 꺼내기 전에
    //    출력스트림이 사용할 문자표(charset)를 지정하라.
    // => 반드시 출력 스트림을 얻기 전에 설정해야 한다.
    // res.setContentType("MIME Type;charset=문자표이름");
    //
    res.setContentType("text/plain;charset=UTF-8"); // UCS2(UTF-16) ==> UTF-8
    PrintWriter out = res.getWriter();

    // 한글이나 일본, 중국, 아랍문자는
    // UTF-8 문자표에 정의되어 있기 때문에
    // UTF-8 문자로 변환할 수 있다.
    out.println("Hello!");
    out.println("안녕하세요!");
    out.println("こんにちは");
    out.println("您好");
    out.println("مع السلامة؛ إلى اللقاء!");

    // MIME Type : Multi-purpose Internet Mail Extension
    // => 콘텐트의 형식을 표현
    // => 콘텐트타입/상세타입
    // => 예) text/plain, text/css, text/html 등
    // => 웹 브라우저는 콘텐트를 출력할 때 서버가 알려준 MIME 타입을 보고
    // 어떤 방식으로 출력할 지 결정한다.

MIME Type에 따라 출력형식이 달라지는데

plain일경우 텍스트를 생생하게 나열한다. 엔터까지 모두

html일경우 당연히 출력형식이 html이 아니기 때문에 오른쪽으로 쭉 나열해서 출력한다.

html은 렌더링 한다고 말한다.(화면에 뿌리는 것)