2013년 9월 7일 토요일

[Head First]Servlets & JSP 내용정리-4장

Chapter.04 서블릿은 평생을 서비스 클라이언트로 삶니다.

서블릿의 일생 (Web Container에 의해서)
  • Class Loading : class 찾아서 class loading 한다.
  • Servlet Instance : 서블릿의 생성자 실행(디폴트 생성자 실행)
  • init() : 전체 일생에서 단 한번만 실행됨. 반드시 service() 이전에 실행 되어야 함.
  • service() : 대부분의 시간을 보냄, 클라이어느 요청을 핸들링함. (doGet(), doPost() 실행하고
    요청이 들어 올때 마다 새로운 쓰레드에서 실행됨.
  • destory() : 죽기전에 모든 자원 해지 할 수 있는 기회를 줌.
Servlet 관련 주요 인터페이스 , 클래스
  • Servlet Interface (javax.servlet) : 생명주기 관련 메소드가 선언되어 있다.
    • service(ServletRequest,ServletResponse)
    • init(ServletConfig)
    • destory()
    • getServletConfig()
    • getServletInfo()
  • GenericServlet Class (java.servlet) : 추상화 클래스, 대부분의 서블릿 행위가 이 클래스에서 구현 되었다.
    • service(ServletRequest,ServletResponse)
    • init(ServletConfig)
    • init()
    • destory()
    • getServletConfig()
    • getServletInfo()
    • getInitParameter(String)
    • getInitParameterNames()
    • getServletContext()
    • log(String)
    • log(String,Throwable)
  • HttpServlet Class (javax.servlet.http) : 추상화 클래스, HTTP 관련 해서 service() 재정의 함.
    HttpServletRequest(Response) 만 파라미터로 받는 새로운 service()메소드를 구현함.
    • service(HttpServletRequest,HttpServletResponse)
    • service(ServletRequest,ServletResponse)
    • doGet(HttpServletRequest,HttpServletResponse)
    • doPost(HttpServletRequest,HttpServletResponse)
    • doHead(HttpServletRequest,HttpServletResponse)
    • doOptions(HttpServletRequest,HttpServletResponse)
    • doPut(HttpServletRequest,HttpServletResponse)
    • doTrace(HttpServletRequest,HttpServletResponse)
    • doDelete(HttpServletRequest,HttpServletResponse)
    • getLastModified(HttpServletRequest)
  • MyServlet : 여러분이 작성은 HTTP 관련 메소드만을 구현 하면 된다.
서블릿 Life Cycle 3 KEY Point
  • init() : 클라인언트의 요청을 처리하기 전에 서블릿을 초기화할 기회를 줌
    • 재정의 여부 : 초기화할 코드가 있는 초기화 함. (예, DB접속)
  • service() : 클라이언트의 HTTP 메소드를 참조 하여 doGet()을 호출하지 doPost() 호출할지 판단합니다.
    • 재정의 여부 : 거의 재정의 하지 않는다.
  • doGet() / doPost() : 웹 어플리케이션 실제 작업을 하는 곳
    • 재정의 여부 : 둘 중 하나는 반드시 재정의 해야 함.
컨테이너 - 서블릿 하나에 대한 다수의 요청을 처리하기 위해 다수의 스레드를 실행하지 다수의 인스턴스를 만들지 말아야 합니다.
  • 서블릿 초기화 시점 - 컨테이너 시작 할때(tomcat) , 관련 클래스를 찾아서 로딩 시킴.
  • 클래스 로딩 방법
  • - class finding & loading
  • - Just-In-Time (즉, 실행시 로딩하기
객체가 서블릿이 된다는 것은 :: 서블릿에 따라오는 고유한 권한을 가진다는 것을 의미합니다.

ServletConfig 객체
  • 서블릿당 ServletConfig 객체 하나
  • 배포시 설정된 정보를 서블릿에게 넘겨 주기 위해서(DB 나 EJB 참조)
  • ServletContext에 접근하기
  • 파라미터값은 배포 서술자(DD)에서 설정 가능
  • 서블릿이 배포하는 동안 수정되지 않는다. 만약 변경 되면 서블릿을 다시 배포 해야 한다.
ServletContext 객체
  • 웹 어플리케이션 당 하나
  • 웹 어플리케이션의 파라미터 정보를 읽어 오기 위하여 사용합니다.(DD 안에 설정됨)
  • 일종의 어플리케이션용 게시판이며 여기에 기록하면 다른 객체에서 참조 가능하다.
  • 서버 정보를 파악하기 위해 사용, 예) 컨테이너 이름 및 버젼, 지원하는 API 버젼등

Request / Response 주요 클래스 및 인터페이스
  • ServletRequest (javax.servlet) Interface :
    • getAttribute(String)
    • getContentLength()
    • getInputStream()
    • getLocalPort()
    • getParameter()
    • getParameterNames()
  • HttpServletRequest (javax.servlet.http) Interface : HTTP 관련 서비스를 제공 합니다.
    • getContextPath()
    • getCookies()
    • getHeader(String)
    • getQueryString()
    • getSession()
    • getMethod()
  • ServletResponse (javax.servlet) Interface :
    • getBufferSize()
    • setContentType()
    • getOutputStream()
    • getWriter()
    • getContentType()
  • HttpServletResponse (javax.servlet.http) Interface :
    • addCookie()
    • addHeader()
    • encodeRedirectURL()
    • sendError()
    • setStatus()

- HttpServletRequest  와 HttpServletResponse 는 누가 구현 하는가 - 컨테이너 , API로 구현된 클래스가 없음.
- GenerlcServlet 과 ServletRequest  와 ServletResponse  있는 이유는 HTTP 이외 사용될것 가정하여 설계 하였기 때문에 있음.

HTTP 메소드
  1. GET - URL로 자원 또는 파일 달라고 요청함.
  2. POST - 요청한 URL로 이 정보를 넘겨 주라고 요청함. 부가 정보를 가진 GET 이라고도 함.
  3. HEAD - 헤더 정보만 요청함. 이는 Response 몸체 정보가 없다는 것 빼고 GET과 동일함.
  4. TRACE - 요청한 메시지의 loopback 테스트를 요청함. 서버쪽에서 무엇을 받았는지 알고 싶을 때 하는 테스트
    테스트 목적혹은 문제 해결을 위해 사용함.
  5. PUT - 동봉한 몸체 정보를 요청한 URL로 올리기 위해 사용함.
  6. DELETE - 요청한 URL에 있는 자원이나 파일을 삭제하기 위해 사용
  7. OPTIONS - 요청한 URL이 응답할 수 있는 HTTP 메소드가 무엇인지 요청함.
  8. CONNECT - 터널링의 목적으로 연결을 요청함.

- 요청 멱등(Idempotent) 이란 - 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미
동일한 작업을 한 번이고 두 번이고 계속 해서 할 수 있습니다. 어떤 부작용도 없이

- method의 기본값 : 만약 <form>에서 method 속성을 생략할 경우는 기본적인 값을 “GET” 임.
- doGet() 과 doPost() 모든 지원 방안
public void doPost(...) throws{
  doGet(request,response);
}

- 파라미터 정보 얻는 메소드
  • 주어진 paraName에 대한 단일 값인 경우 : getParameter()
  • 주어진 paraName에 대한 여러 값인 경우 : getParameterValues() , 배열로 리턴함.

- Request 객체에 얻을 수 있는 정보
  • 클라이언트 플랫폼 정보 및 브라우저 정보 :getHeader(“User-Agent”)
    • getIntHeader() : 요청 정보의 응답값이 정수형인 경우를 보장한다.
  • 요청에 관련된 쿠기 정보 :getCookies();
  • 클라이언트의 세션 정보 : getSession();
  • Request의 HTTP 메소드 : getMethod();
  • Request의 입력 스트림 : getInputStream();
  • getRemotePort() : 요청을 보낸 클라이언트의 포트
  • getServerPort() : Request가 들어오는 포트 번호
  • getLocalPort() : 스레드를 처리 위한 포트
 
- Response 처리시 주의 사항
** setContentType를 설정 후 정보쓰기 작업을 수행 한다.

JAR를 내려받는 서블릿 코드 (잘 동작할까?)
doGet(...){
  response.setContentType(“application/jar”);
  ServletContext ctvx = getServletContext();
  inputStream is = ctx.getResourceAsStream(“/bookCode.jar”);
  int read = 0;
  byte[] bytes = new byte[1024];
  
  OutputStream os = response.getOutputStream();
  while((read = is.read(bytes) != -1){
      os.write(bytes,0,read);
  }
  os.flush();
  os.close();   

일반적인 MIME 타입
  • text/html
  • application/pdf
  • video/quicktime
  • application/java
  • image/jpeg
  • application/jar
  • application/octect-stream
  • application/x-zip

다른 URL로 이동 시키기

  • 서블릿 Redirect
    • 요청을 완전히 다른 URL로 방향을 바꾸는 것
    • 클라이언트에서 일어남.
    • 관련메소드 : response.sendRedirect(URLString);
    • 상대경로 사용가능
  • Request Dispatch
    • 다른 컴포넌트에게 위임을 하는 것
    • 서버에서 일어남
    • 관련코드 : request.getRequestDispathcher(“xxx.jsp”).forward(request,response);

자바 API 신규 기능 [Java 1.4 추가 기능 - assertion]

Java 1.4 추가 기능 - assertion

assertion를 사용한 프로그램밍
설명(공식설명사이트 영문, 한글)
단언을 시험할 때 사용한다고 볼 수 있다. 예를 들면 물은 위에서 반드시 아래로 떨어진다것은 반드시 사실이어야 한다.
형식
Format1
assert Expression1;
Format2
assert Expression1:Expression2;
Expression1는 boolean 식 , Expression2 값을 가지는 식, void로 선언되는 식을 사용 불가
Expression2 는 오류 출력시 오류 설명 문자열로 사용됨. 사용된다.
Exception in thread "main" java.lang.AssertionError: Expression2
at assert_test.AssertionTestDrive.testAssertion_01(AssertionTestDrive.java:25)
assertion을 사용하지 말아야 하는 경우
  • public 메소드의 내에 인수 체크
    • AssertionError는 Error 상속 한다. (주의) 일반적인 Exception으로 예외 처리 되지 않음.
  • 어플리케이션의 올바른 동작에 필요한 처리를 실행하기 위해서 assertion를 사용하지 말아 주세요.

사용예
  • 내부의 불변조건 : 반드시 될수 없는 조건
  • 제어 플로우의 불변 조건 : 제어 흐름상 올 수 없는 곳
  • 사전 조건,사후 조건, 및 클래스의 불변 조건
    • 사전 조건 - 메소드가 호출 되었때 반드시 만족 해야 한다.
      • 락 상태 사전 조건 : Thread.holdsLock():
    • 사후 조건 - 메소드가 호출 된 후 반드시 만족 해야 한다.
    • 클래스 불변 조건 - 내부 불변 조건의 일종
내부의 불편조건 예1)
for(int i = 0 ; i < 10 ; i++){
 if(i % 3 == 0){
   System.out.printf("%d는 3으로 떨어집니다.\n",i);
 }else if(i % 3 == 1){
   System.out.printf("%d의 나머지가 1입니다.\n",i);
 }else{
   System.out.printf("%d의 나머지가 2입니다.\n",i);
   assert i % 3 == 2 : i;
 }
}
내부의 불편조건 예2)
enum Suit{ CLUBS,DIAMONDS,HEARTS,SPADES }
for(Suit suit:Suit.values()){
 switch(suit){
 case CLUBS: System.out.println(suit); break;
 case DIAMONDS: System.out.println(suit); break;
 case HEARTS: System.out.println(suit); break;
 case SPADES: System.out.println(suit); break;
 //디폴드 값이 절대로 올수 없으므로
 default:
   throw new AssertionError(suit);
 // assert false:suit; //동일함.
 }
}
제어 플로우의 분편조건 예)
for(Suit suit:Suit.values()){
 if(suit == Suit.SPADES)
   return;
}
//Never reach this point!! -->
assert false;
사전 조건 예)
public void setRefreshRate(int rate){
 //precondition -- 이 부분에서 사용하지 않는 이유는 public
 //에서 파라미터 확인을 위해서 assertion을 사용하지 말라
 //그 이유는 throw 하지 않기 때문에
 if(rate <= 0 || rate > MAX_REFRESH_RATE)
   throw new IllegalArgumentException("Illegal rate: "+rate);
 setRefreshInterval(100/rate);
}
private void setRefreshInterval(int interval){
 assert interval > 0 && interval <= 100/MAX_REFRESH_RATE : interval;
}

assert 고도의 사용법
assert 클래스 파일로 부터 무효화 하기 : 이유는 프로그램 사이즈가 작아진다.
static final boolean asserts = false;
static void controlAssert(){
 if(asserts) assert false;
}
assertion 무조건 유효화 하기 : -ea을 활성해야 한다. 않그러면 정상적으로 동작 하지 않는다.
static{
 boolean assertEnabled = false;
 assert assertEnabled = true; //
 if(!assertEnabled) throw new RuntimeException("Asserts must be enabled!!!");
}

시작시 assert를 유효화 무효화 할 수 있음. 관련 기능
디폴트는 무효화 입니다.
  • 유효화 : -enableassertions 혹은 -ea
  • 무효화 : -disableassertions 혹은 -da
모든 시스템 클래스에 대한 유효/무효화
  • 유효화 : -enablesystemassertions 혹은 -esa
  • 무효화 : -disablesystemassertions 또는 -dsa
옵션 형식 :
  • 인수 없음 : 시스템 클래스를 제외한 모든 클래스내의 assertion를 유효 또는 무효로 한다
  • packageName... : 이름 첨부의 패키지내 및 임의의 서브 패키지내의 assertion를 유효 또는 무효로 합니다.
  • ... : 현재의 작업 디렉토리내의 이름이 없는 패키지내의 assertion를 유효 또는 무효로 한다
  • className : 지정한 클래스내의 assertion를 유효 또는 무효로 한다
사용예
  • 예1) java -ea:com.wombat.fruitbat... BatTutor
    • - 설명 : com.wombat.fruitbat 패키지와 그 서브 패키지내에서만 assertion를 유효하게 함. 실행프로그램 BatTutor
  • 예2) java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat BatTutor
    • - 설명 : com.wombat.fruitbat 패키지내의 assertion를 유효하게 하고,com.wombat.fruitbat.Brickbat 클래스내의 assertion를 무효로 시킨 후 BatTutor를 실행함

자바7 NIO.2 - 내용정리 1장

chapter 1. Path 클래스 사용하기

java.nio.file.Path


Path 클래스 두 가지 용도
  • 문법적인 용도로 파일시스템에 접근하지 않고 경로를 조작하는 작업에 주로 사용 (메모리상의 논리적인 조작)
  • 경로를 참조하는 파일에 대한 작업


파일시스템 - 하드 드라이브 같은 일정한 형태의 미디어에 파일을 저장하고 구조적으로 관리하며, 같은 방법으로 파일을 쉽게 가져올 수 있게 만든 것
java.nio.file.FileSystems 을 사용하여 접근할 수 있다.
중요 메소드
  • getDefault() : JVM에 기본 FileSystem(운영체제의 기본 파일시스템)을 반환하는 static 메소드
  • getFileSystem(URI uri) : 인자의 URI 스키마와 일치하는 파일시스템 제공자(provider) 목록에서 파일시스템을 반환하는 static 메소드. 메모리 , 네트워크 , 가상 파일시스템에서 가져 올 수 있다.


FileSystems.getDefault().getPath(""); 의 단축 표기 법은 Paths.get(""); 이다.
Path.normalize(); --> 중복되는 부분을 정리한다.
URI 파일 예 : file:///rafaelnadal/tournaments/2009/BNP.txt
1.2 경로 정의 하기
  • 절대 경로 정의 : Paths.get(“절대경로”);
  • 상대 경로 정의 : Paths.get(“상대경로");
  • 작업 폴더에서 상태 경로 정의 :
  • 단축을 이용한 경로 정의 : . , .. 사용가능 , normalize() 중복 부분 제거
  • URI에서 경로 정의 하기 : URI.create()이용하여


1.3 경로에 관한 정보 가져오기
  • getFileName() : 경로가 가리키는 파일/디렉토리를 반환함.
  • getRoot() : 경로에서 루트를 가져옵니다.(만약 경로에 root가 없다면 null)
  • getParent() : 현재 경로의 부모를 가져옵니다.
  • getNameCount() : 경로에 있는 요소 개수를 가져 온다.
  • getName(int index) : 각 요소의 이름 가져오기
  • subpath(start,end) : 상대경로를 추출할 수 있다. 시작 인텍스와 끝 인덱스를 주면 해당 범위 요소를 반환함.


주요 메소드들
1.4 Path의 변환 관련 메소드
  • toString() : 문자열 변환
  • toUri() : URI로 변환
  • toAbsolutePath() : 절대 경로 변환
  • toRealPath() : 실제 경로 변환 (아래 추가 설명)
  • toFile() : 파일 객체로 변환
  • FileInstance.toPath() : 파일 객체를 Path 객체로 변환
실제 경로를 반환하는 메소드
  • toRealPath(Options..); 설명
실재 파일(existing file)의 실제 경로(real path)를 반환 한다. 여기서 실재 파일이라는 의미는 파일이 진짜로 있어야 한다는 뜻이다. 하지만 toAbsolutePath() 메소드를 사용할 때는 실재 파일일 필요가 없다. 심볼 링크를 지원하는 파일시스템에서는 toRealPath() 메소드에 어떤 인자를 전달하지 않는다면 경로에 있는 모든 심볼 링크를 실제 경로로 풀이한다. 변환과정에서 심볼링크를 제외하고 싶다면 메서드에 LinkOption.NOFOLLOW_LINKs enum 상수를 전달해야 한다. 또한 상대 경로를 전달하면 절대 경로를 반환하며, 경로에 중복 요소가 있다면 이를 제거한 경로 반환한다.
만약 toRealPath() 메소드는 파일이 없거나 파일에 접근할 수 없다면 IOException 예외를 던진다.


1.5 두 경로를 조합하기
  • resolve() : 고정 경로에 부분경로 추가
  • resolveSibling() : 형제 경로에서 부분경로 추가


1.6 두 위치 사이의 경로 생성하기
  • relativize() : 한쪽 위치에서 다른 위치까지의 경로를 만들기
** 주의사항 : 만약 루트 패스가 한쪽에 있는 경우에는 정상적으로 패스를 만들지 못한다. (모두 있어야 한다.)


1.7 두 경로 비교하기
  • equals() : 두 경로의 동등성은 비교 한다.
    • 파일 시스템에 접근하지 않는다.
    • 비교하는 경로로 실재 하지 않아도 된다.
    • 경로가 파일인지 검사하지 않는다.
    • OS에 따라 대소문자를 비교를 여부를 따진다.
    • 상대경로와 절대경로는 같은 패스를 가르쳐도 동등하지 않는다.
  • java.nio.file.Files.isSameFile() : 두개의 경로가 같은 파일/폴더인지만 검사한다. 내부에서 Path.equals를 사용하고 만약 false인 경우 이중 체크 작업 즉 파일시스템에 실재해야 한다. 만약 그렇지 않으면 IOException 예외를 던진다.
  • Path는 Comparable 인터페이스 구현 하였음. 정렬은 사전편찬식 작은은 0 보다 작은값 크면 0 보다 큰값
  • 부분비교 : startsWith() ,endsWith()


1.8 경로의 이름 요소 반복하기
Path는 Iterable 인터페이스 구현하고 있음. 명시적인 이터레이터를 사용하거나 foreach 루프를 사용할 수 있다.

- 참고 문헌 : 한빛미디어 , 자바7 NIO.2 파일&네트워크 프로그램밍

2013년 9월 6일 금요일

[Head First]Servlets & JSP 내용정리-3장

Chapter.03 MVC 웹 애플리케이션 만들어서 배포해봅시다.

url-pattern 양식 설명
  • URL 입력 패턴 : /Beer-v/SelectBeer.do
    • /  : 서버의 루트 디렉토리
    • Beer-v : web-application 컨텍스트 루트(환경)
    • /SelectBeer.do : 자원에 대한 논리적인 이름
JSP 설명
  • 파일 확장자 jsp
  • page 지시자(directive) <%@ … %>


forward 구문 : servlet에서 JSP를 호출하기

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


 String c = request.getParameter("color");
 BeerExpert beerexpert = new BeerExpert();
 List<String> result = beerexpert.getBrands(c);


 request.setAttribute("styles",result);
 ------------------------------------------------
 JSP가 나중에 읽을 수 있도록 Request객체의 속성값을 설정한다.


 RequestDispatcher view = request.getRequestDispatcher("result.jsp");
 --------------------------------------------------------------------
 JSP로 작업을 부탁할 클래스 RequestDispatcher 객체를 생성한다.
 view.forward(request,response);
 ------------------------------
 RequestDispatcher는 컨테이너에게 JSP를 준비하라고 요청하고 그 다음 JSP에게
 request와 response 객체를 전달한다.