ex01 - 서블릿 콘테이너가 관리하는 세 종류 메서드
톰캣에 있는 web server는 기능이 허접해서 다른 웹서버로 교체하는 일이 많고 톰캣의 기능은 보통 application server를 많이 쓴다.
큰 프로그램 안에 글쓰기 기능은 아주 작은 조각일 뿐임 = 그래서 servlet!
이 방법은 위험하다. 다른 개발자가 업로드 직전에 해킹 코드를 심으면 언제 심었는지 알 수 없기 때문이다. 그래서 직접 배포파일을 서버에 올리는 것은 좋지 않다.
바뀐 방법은 이와 같다. 깃의 구조와 동일함
Command객체들을 미리 만들어 두는 것은 메모리 낭비이므로 객체생성을 요청할 때 딱 한번 호출된 뒤 service()를 호출한다.
<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로 실행해보면 정상적으로 실행되는 것을 알 수 있다.
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은 렌더링 한다고 말한다.(화면에 뿌리는 것)