'프로그래밍 > JSP' 카테고리의 다른 글

jsp 322p 세션에 기록해 두는 토큰에 관해  (0) 2014.01.02
jsp ~ jdbc  (0) 2014.01.01
jsp에서 빈의 사용3  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
by givingsheart 2014. 1. 2. 17:03

http://blog.naver.com/PostView.nhn?blogId=tjdghkgkdl&logNo=10125259469


웹페이지에서 비지니스 도중 새로고침,뒤로가기.. 어떤 결과가 발생할까?
비지니스 요청이 중복해서 발생한다. 또한 트랜잭션처럼 하나의 비지니스가 
몇단계의 스텝으로 완료될때.. 그 정보들을 예외상황으로 부터 어떻게 지킬것
인가? 등에 대한 고민들..

예전에 서블릿 소스코드를 분석할때.. 살짝 본것 같기도하다. 현재의 요청이(new) 
이미 한번 접수된 요청(old)인가?...


'프로그래밍 > JSP' 카테고리의 다른 글

web-app.xml의 태그를 사용해 로그인및 권한 설정 방법  (0) 2014.01.02
jsp ~ jdbc  (0) 2014.01.01
jsp에서 빈의 사용3  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
by givingsheart 2014. 1. 2. 08:57

역사:jsp 설계자님들께서 jdbc를 jsp에서 사용하기로 결정하셨음;;

      그럼으로 jsp어플로 db조작하고 싶으면 jdbc api로 작성해서 디비 제작사가 공급하는 드라이버 클래스를 사용해야함;;
      (오라클 님들 java.sql.Driver interface 구현하느라 수고 많으셨음   ojdbc14.jar .. 앗 오라클 놈이나 자바 선놈이나 그놈이 그놈? 
       젠장.. 그래도 ㄳ)

기본전략:db접속 코드들은 전부 bean이나 서블릿에 때려 박고 jsp에선 요것들을 커스텀 태그등을 이용해 사용하여
             프리젠테이션 영역과 프로그램의 구현을 분리 시켜아함. (나도 원함)

초 간략 jdbc 사용방법(선생님의 명언.. 일반io나 db,net io나.. 매 한가지이다.)
1.오라클 jdbc 드라이버 로드
2.db connection 연결(한마디로 스트림 생성)
3.db와 대화를 나누기 위한 struct query language 준비
  3.1 Statement or PreparedStatement(내가 툴만들때 쓴거) or CallAbleStatement 객체 생성해서 쿼리 세팅
4.음..3번객체.excute()였나.. 하여튼 쿼리 실행(스트림을 통해 데이터 보내기)
5.결과값 받기 ResultSet으로...  (4번에서 db의 응답이 오기 전까지 무한 루프 돌리고 있으려나? 설마 그리 단순하게 하진 않았겠지..
  나중에 grepcode로 소스 확인)
6.볼일 종료했으니 스트림및 생성했던 객체들 소멸 (중요한것은 잦은 db커넥션에 부담을 가져야함. 그럼으로 db커넥션 풀링,
   마찬가지로 잦은 쿼리 수행도 부담스러움..  그럼으로 버퍼방식으로 모으고 모으던지.. 아니면 db가 알아서 트랜잭션 처리를
   하던지.. 그것도 아니면 서버측이 자주 접근하되, 수정되지 않는 데이터를 메모리에 띄워놓고 있던지.. 하여간 db는 너무 귀찮
   게 하면 곤란함.. 그나저나 트랜잭션.. 모아놨다가 조건 맞으면 commit, 아니면 rollback.. 하는 짓이 svn 닮았네?.. 지훈형님마저
   없으니.. 내 정신머리가 점점 폭주하는구나 OTL )

간단하게 구현을 반 의사코드로 적어보면..
1.드라이버 이름인 문자열 "오라클.jdbc.driver" 를 가지고
  1.1 Class.forName("드라이버이름") 을 통해 드라이버 클래스가 존재하는지 확인해야함.

2.커넥션 객체 생성위해 내가 열어둔 db의 url(내껀 로컬:8080), 로긴용 id , pw 를 가지고 
  2.1 java.sql.드라이버 매니저클래스님께 커넥션 객체 달라고 요청 

3."insert into xxx"던 "select from xxx"등의 문자열을 가지고 PreparedStatement(재사용가능하고 지정되지 않은 변수를 ?,? 식으로
   사용이 가능함 = 동적바인딩이 가능하단 얘기는 한마디로.. 실시간으로 유저의 입력을 받아서 세팅해줄 수 있단 의미일까? ) 
   객체를 생성해야 하는데.. (call어쩌구 statement는 db 내장 프로시저 호출해서 일시키는 것)
  3.1 요 역할은 2.1에서 얻은 커넥션 객체가 생성해줌.

4. 3.1에서 얻은 sql문장 객체에게 excute() 작업시키고 ResultSet 으로 결과 받을 준비 = db에 "요청" 전달 & "응답" 회신
(아..브라우저와 서버페이지(or서블렛)간 request/response와 오버랩되네.. 자바 프레임 워크 만만세!)

5. 결과값(ResultSet) 받았으면 요거에서 잘 추출해야함.. 테이블형의 자료구조기 때문에 행,열단위로 알아서 잘 추출
   (데이터 형식에 따라 행,열로 접근할 경운 이중 반복문 or map 자료구조의 entrySet처럼 키와 값들 두쌍의 데이터 집합이면..
    뭐 알아서 잘.. 너무 경우의 수가 많으니 일반화하기 어렵다. 물론 해본적도 없지만;;)
   5.1 db에 있던 데이터 내 app의 메모리상 xx객체에 세팅해놨으니.. 알아서 쓰면 됨
   (etc)결과값 내용이 많을 경우 모든 데이터(resultSet중 모든 row)를 메모리에 한번에 올려주진 않음..set객체가 묵시적
   으로 db와 커넥션을 유지하고 있음.. 버퍼링 방식으로.. (아마 게시판이 이런식으로 읽혀오지 않을까 싶다. 한번에 읽어
   와서 메모리에 띄우긴 너무 많잖아..)

6. 용건 끝났으니 커넥션 객체, 쿼리 문장 객체등 소멸   or  만약 커넥션 풀링 개념을 사용한다면.. 풀에 반납

***resultSet에서 커서로 제어한다는 컨셉***
 (여러번에 걸쳐 필요한 행을 읽어오고, 다음번엔 그 이후부터 읽어오는게 가능, 물론 각 데이터 필드에 접근할수 있는 get메서드
들도 있다)

 booleanabsolute (int row) 
          커서를 이 ResultSet 객체내의 지정된 행으로 이동합니다.
 voidafterLast () 
          커서를 이 ResultSet 객체의 끝, 즉 맨 마지막 줄의 직후로 이동합니다.
 voidbeforeFirst () 
          커서를 이 ResultSet 객체의 첨단, 즉 선두행의 직전으로 이동합니다.
 voidcancelRowUpdates () 
          이 ResultSet 객체의 현재의 행에 대해서 간 갱신을 취소합니다.
 voidclearWarnings () 
          이 ResultSet 객체에 관해서 보고된 모든 경고를 클리어 합니다.
 voidclose () 
          자동적으로 클로즈 될 때, 이것을 기다리는 것이 아니라, 즉시 ResultSet 객체의 데이타베이스와 JDBC 자원을 해제합니다.
 voiddeleteRow () 
          이 ResultSet 객체 및 기본으로 되는 데이타베이스로부터, 현재의 행을 삭제합니다.
 intfindColumn (String  columnLabel) 
          지정된 ResultSet 의 열라벨을 ResultSet 열인덱스에 매핑 합니다.
 booleanfirst () 
          커서를 이 ResultSet 객체내의 선두행으로 이동합니다.


by givingsheart 2014. 1. 1. 16:00

1.HttpSessionBindingListener 인터페이스의 중요성 (awt component 사용할때 내가 재정의해서 등록하는 리스너와 동일 )


(1) public void valueBound(HttpSessionBindingEvent event)
 :빈이 사용자의 세션에 처음 바인딩(useBean 통해 인스턴스화후에) 될때 호출됨 
(2)public void valueUnbound(HttpSessionBindingEvent event)
 :빈이 세션에서 제거될때 호출됨

=>즉 세션 바인딩 이벤트를 처리한다는 것은.. 빈의 인스턴스의 생성,소멸을 리퀘스트 단위가 아닌, 세션 단위로
   처리할수 있다는 의미가 된다.(내 요청마다 새로생성, 소멸..반복.. 낭비 아닌가?)


2. 빈의 리스너
(1)java.beans  인터페이스 PropertyChangeListener

public interface PropertyChangeListener extends EventListener 
PropertyChange 이벤트는, Bean 가 「바운드」프로퍼티을 변경할 때마다 트리거됩니다. 
바운드 프로퍼티의 갱신마다 통지를 보내도록(듯이), PropertyChangeListener 를 소스 Bean 에 
등록할 수 있습니다.
메소드의 개요 void propertyChange (PropertyChangeEvent  evt)

java.beans 
클래스 PropertyChangeEvent java.lang.Object  
java.beans.PropertyChangeEvent 모든 구현된 인터페이스:Serializable
직계의 기존의 서브 클래스: IndexedPropertyChangeEvent

생성자 의 개요PropertyChangeEvent (Object  source, String  propertyName, Object  oldValue, Object  newValue)
새로운 PropertyChangeEvent 를 구축합니다.



(2)java.beans 인터페이스 VetoableChangeListener
public interface VetoableChangeListener
extends EventListener

VetoableChange 이벤트는, Bean 가 「제약」프로퍼티을 변경할 때마다 트리거됩니다. 

제약 프로퍼티의 갱신마다 통지를 보내도록(듯이), VetoableChangeListener 를 소스 Bean 

에 등록할 수 있습니다.


메소드의 개요
 voidvetoableChange (PropertyChangeEvent  evt) 
          제약 프로퍼티의 변경시에 불려 갑니다.



(3) public interface ExceptionListener

ExceptionListener 는, 내부 예외의 통지를 받습니다.


메소드의 개요
 voidexceptionThrown (Exception  e) 
          이 메소드는, 회복 가능한 예외가 캐치 되었을 때에 불려 갑니다.





*************************************************************************


3.빈과 gui 합체 (비주얼 툴 만들기?)

java.beans   인터페이스 Customizer

public interface Customizer

카스타마이자크라스는, 타겟 Java Bean 를 커스터마이즈하기 위한 완전한 커스텀 GUI 를 제공합니다.

각 카스타마이자는, AWT 다이얼로그나 패널내에서 인스턴스를 생성할 수 있도록(듯이),java.awt.Component 클래스를 상속하지 않으면 안됩니다.

카스타마이자 마다 인수 없음의 생성자 이 필요합니다.


메소드의 개요
 voidaddPropertyChangeListener (PropertyChangeListener  listener) 
          PropertyChange 이벤트의 청취자를 등록합니다.
 voidremovePropertyChangeListener (PropertyChangeListener  listener) 
          PropertyChange 이벤트의 청취자를 삭제합니다.
 voidsetObject (Object  bean) 
          커스터마이즈 하는 객체를 설정합니다.


void setObject(Object  bean) :커스터마이즈 하는 객체를 설정합니다. 이 메소드는, Customizer 
를 친 AWT 컨테이너에 추가하기 전에 1 회만 호출하도록 해 주세요.파라미터: bean - 커스터
마이즈 되는 객체


java.beans 
인터페이스 PropertyEditor 기존의 구현 클래스의 일람: PropertyEditorSupport

public interface PropertyEditor PropertyEditor 클래스는, 사용자가 지정의 형태의 프로퍼티치를 편집하기 
위한 GUI 의 지원를 제공합니다. PropertyEditor 는, 프로퍼티치의 표시나 코우신에 도착해 다양한 방법을 
지원합니다. 대부분의 PropertyEditor 에서는, 이 API 로 사용할 수 있는 각종 옵션의 부분집합을 지원하는 것
만으로 충분합니다. 단순한 PropertyEditors 가 지원하는 것은 getAsText 와 setAsText 메소드만으로, paintValue 
이나 getCustomEditor 등의 지원는 불필요합니다. 

보다 복잡한 것으로는, getAsText 나 setAsText 는 지원할 수 없습니다만, 대신에 paintValue 과 getCustomEditor 
를 지원합니다. 각 propertyEditor 는, 다음의 3 개의 표시 스타일중 1 개(살) 이상을 반드시 지원할 필요가 있습
니다. 

즉, (1) isPaintable 의 지원, (2) getTags()로부터 null 가 아닌 String[] 를 돌려주어, 한편 getAsText 로부터
 null 가 아닌 값을 돌려준다, 또는 (3) 단지 getAsText()로부터 null 가 아닌 String 를 돌려주는, 의 3 개(살)
입니다. 

각 프로퍼티 에디터는, 인수 객체가 대응하는 propertyEditor 의 형태인 경우에, setValue 의 호출을 지원할 필요가
있습니다. 한층 더 각 프로퍼티 에디터는, 커스텀 에디터 또는 setAsText 의 어느 쪽인지를 지원할 필요가 있습니다.

각 PropertyEditor 는, 인수 없음의 생성자 을 가지지 않으면 안됩니다.


=>그니까.. 컴포넌트중 Frame이나 Window같은거 상속받은 담에.. implemets java.beans.Customizer 하면 어찌되나;; ㅎㄷㄷ


**************************************************************
사용한 빈 서버 app 메모리에서 날리기
session 스코프 : session.removeAttibute(name)  , HttpSession.removeAttribute(name)
request/page   : pageContext.removeAttribute(name) , ServletRequest.removeAttribute(name)
application    : application.removeAttribute(name) , ServletContext.removeAttribute(name)

******************************************************
request 객체를 빈태드로 엑세스하기:request도 빈처럼 다룰수 있다.
<jsp:getProperty name="request" property="remoteUser" />  

request빈의 프로퍼티들 (요청객체 임으로 getProperty만 가능하다)
authType : 들어온 요청의 인증 방식을 얻어내며, 모르면 null..
method   : 들어온 요청에서 행해진 http메소드(get,post,put)을 얻어낸다.
pathInfo : 들어온 요청의 url의 서블릿 경로 뒤에 붙지만, 질의 문자열 앞에 오는 추가 경로 정보 얻음
pathTranslated: 들어온 요청의 url의 서블릿 경로뒤,질의 문자열 앞에 오는 추가 경로를 얻어내 진짜 경로로 바꿈?
queryString : http요청 uri와 한몸으로 들어오는 질의 문자열 얻기
remoteUser : 요청을 보낸 원격 접속 사용자의 이름을 얻어냄. 사용자 이름은 http 인증과 함께 세팅됨
requestURI : 원래의 요청에 해당하는 URI를 얻음
characterEncoding: 캐릭터셋 얻음
contentType: 인터넷 미디어 타입을 얻음 (text/html , text/xml..)
protocol : 프로토콜과 버전을 얻음 <protocol>/<major version>.<minor version> 의 문자열로 얻음
remoteAddr : 요청 보낸 클라이언트의 ip주소 얻기
serverName: 요청 받은 웹 서버의 호스트 이름을 얻어냄
serverPort: 요청 받은 웹 서버의 포트번호
scheme: 들어온 요청의 url방식(scheme)를 얻어냄 (http,https,ftp..)
remoteHost: 요청을 보낸 에이전트(클라이언트)의 호스트 이름을 완전형태(fully qualified)로 얻어냄


'프로그래밍 > JSP' 카테고리의 다른 글

jsp 322p 세션에 기록해 두는 토큰에 관해  (0) 2014.01.02
jsp ~ jdbc  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
jsp 스크립트  (0) 2014.01.01
by givingsheart 2014. 1. 1. 15:58



자바 빈의 규약! 표준화


어째서 빈컨테이너는 공통상위 클래스(추상), 인터페이스 클래스 없이 빈 객체를 관리 할 수 있을까?

클래스의 메소드와 기능을 런타임에 노출 시킬 수 있게 하는 기능을 introspection이라 한다. 

그렇다면 introspection은 어떻게 구현되어 있나? 바로 java.lang.reflection 패키지를 사용한다.

빈 컨테이너는 자바빈즈에 api에서 정의된 기준에 맞는 public 메소드를 분석하여, 주어진 빈이 지원하는 프로퍼티를 알아낸다.

그럼으로 빈 클래스는 자신이 제공하는 프로퍼티에 대해서 
1.게터,세터를 제공해야 한다. (약속:set/get +프로퍼티이름 )
2.매개변수 없는 디폴트 생성자를 제공해야 한다. (분명 매개변수 있는 생성자도 reflect로 찾을수 있고 사용할수 있는데..? 
  표준화 하다 보니까 디폴트 생성자로 구현한건가?)
(etc)public 으로 노출해주는 것도.. modify 받아서 accesible인가를 바꿔주면 다 뚤을수 있음.. class를 구성하는 Class(타입)
      , modifyer(접근자), 각종 데이터, 각종 메서드가 모두 object 타입으로 포섭이 가능하니... 장점도 있지만, 단점도 있다.
  
      한마디로 reflect 이용하면 클래스를 사용(생성,세팅,메소드이용등)하거나 완전히 수정할수 있음
      (인터럽트해서 수정해서 악용한다. = 해킹이군.. 그럼으로 각종 보안 알고리즘(네트워크 송수신 데이터 암호화 rsa,des등),
      방화벽,중요데이터는 서버측에서 관리 등이 중요한 것임)

(ex) 자신이 생성된 시간을 기록해두는 빈 클래스

package ***;
import java.util.*;

public class CurrentTimeBean
{
  private int hours;
  private int minutes;

  public CurrentTimeBean()
  {
     Calendar now = Calendar.getInstance();
     this.hours = now.get(Calendar.HOUR_OF_DAY);
     this.minustes = now.get(Calendar.MINUTE);
   }

   public void setHours(int hours)
   {
      this.hours = hours;
   }
    
   public int getHours()
  {
     return this.hours
   }

public void setMinutes(int minutes)
   {
      this.minutes= minutes;
   }
    
   public int getMinutes()
  {
     return this.minutes;
   }

}

**********위 처럼 구현해 놓고************
<jsp:useBean id="time" class="CurrentTimeBean" />
<html> 
<body>
It is now <jsp:getProperty name="time" property="minutes" />
minutes past the hour.
</body>
</html>

=>물론 해당 빈의 모든 프로퍼티에 get,set 메서드를 제공해줄 필요는 없다.(읽기전용,쓰기전용,둘다혼용 따라서 구현)

=>프로퍼티 이름 지을때 소문자+낙타식으로 간다. xml에 대해선 어찌할 것인가? XML 보단 Xml이 일관성 있다.(첫자만 대문자)


*******************인덱스 프로퍼티를 정의하는 방법1**********************
1.전체 집합을 하나의 배열로 반환하는 겟,셋 메서드 구현 = 사용하는 사람이 알아서(스클립틀릿,태그) 전체 반복 작업을 해야한다.
2.인덱스 값을 받아서 해당 요소만 반환하는 겟,셋 메서드 구현 = 1에 비해 유용성이 높다.
3.전체 집합의 수를 돌려주는(length던지 size) 메서드 구현  
4.물론 특정 서비스(비지니스로직)를 제공한다면 해당 메서드도 구현해야 할것이다. (vo 클래스인지 따라)
5.아참.. 세터,게터로 일일히 jsp 페이지에서 세팅해야하니... init(String "intA,intB,intC")등의 메서드를 제공해도 좋을 것이다.
=> 1,2,3  +@로  제공하자 ^^//

=>인덱스 프로퍼티의 경우.. 안타깝게도 jsp 페이지 내부에 자바 코드(스클릿틀릿,표현식)을 사용해야 한다. 자바 코드를 지울수
  있는 수단은.. 짜잔~ "커스텀 태그"  <-- 얼렁 공부해야 할텐데...
  
 
(cf)jsp 표준 액션 태그의 경우.. 스탈라 프로퍼티만 다룰수 있다.(그럼으로 위의 5같은 메서드가 필요하다)

public void setNumbersList(String values)
{
  ArrayList<String> list = new ArrayList<String>();
  StringTokenizer tok = new StringTokenizer(values, ","); // ㅋㅋㅋ 내가 로또 클래스 문자열 매개변수로 처리할때 요거 썼지
  //일단 구분자로 잘라서 관리하고
  while(tok.hasNext())
  {
  list.add(tok.nextToken()); //매개변수 유효성 체크는 생략하나보다 ?
  }
  //구분자로 잘라낸 문자열들을 실제 사용할 타입으로 변환해서 저장
  numbers = new double[n.size()]; 
  for(int i=0; i<numbers.length; i++)
  {
  numbers[i] = Double.parseDouble( list.get(i) );
  }
}

public String getNumberList()
{
  String list = new String(); //스트링으로 반환하기 위한
  for( int i=0; i< numbers.length; i++)
  {
     if( i != numbers.length)
        list += numbers[i] + ","; // , , , col의 형식 만들어주기
     else 
       list += "" + numbers[i]; // row
   }
  return list;
}

=>jsp에서 사용시

<jsp;useBean id="stat" class="com.taglib.wdjsp.components.StatBean">
  <jsp:setProperty name="stat" property="numbersList" value="100,250,150,50,450" />
</jsp:useBean>

<html>
<body>
The average of <jsp:getProperty name="stat" property="numbersList" />
is eqaul to <jsp:getProperty name="stat" property="average" />
</body>
</html>

*******************인덱스 프로퍼티를 정의하는 방법2**********************
=> idea:인덱스에 대한 커서의 개념을 구현한다. JDBC의 ResultSet클래스 , JDBC2.0의 CachedRowSet 클래스
    즉 빈 클래스 안에 인덱스를 나타내는 인스턴스 변수를 넣고 이값을 증가,감소 시키는 것으로 인덱스 프로퍼티 액세스
    가능하게 하는것. (말 그대로 이터레이터 제공)

(ex) 
planets.jsp

<html>
<body bgcolor="white">
<jsp:useBean id="planet" class="wdjsp.PlanetBean" />
<table border="1"> //레이아웃 매니저를 떠올리면 될듯 (테이블 경계 1개 설정)
<tr> //테이블의 행(row)를 의미하는 듯
<th>Planet</th> //테이블의 열(col)을 세로(horizon)으로 표현한듯? <-- 헤더를 의미하는 키워드임.즉 테이블의 각 열의 대표이름
<th>Number of Moons</th>

<% while(planet.next() ) { %>  //이터레이터 처럼 반복자를 제공했긴 하지만, 스클립틀릿으로 자바코드 사용하는것은 유지보수
                                            //최악이다..나중에 커스텀 태그 쓰자! jsp:ForLoopList 같은걸로
<tr> //하나의 테이블 행에
<td> <jsp:getProperty name="planet" property="name" /></td>
<td align="center"> <jsp:getProperty name="planet" property="moons" /></td>
</tr>
<% } %>

</table>
</body>
</html>

=> 음.. html 문법에 대해 굳이 안찾아봐도 해석이 되고 있음...(happy)

PlanetBean.java

package wdjsp;

public class PlanetBean{
 private static final int numPlanets = 0;
 private static final String[] names = {
  "Mecury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus",
  "Neptune", "Pluto" };
 private static final int[] moons = {0,0,1,2,16,18,20,8,1};

private int index;

public PlanetBean(){
index = -1; //인덱스 초기 값
}

public void first(){
index = -1;
}

public boolean next(){
index++;
if(index >= numPlanets)
{
  index--;
  return false;
 }
else
{
  return true;
 }
}

public String getName(){
 return names[index];
}

public int getMoons(){
 return moons[index];
 }
}


*****jsp에서 프로퍼티의 타입이 전부 String 으로 넘어오는걸 기억할것!******

(1)primitive -> String
java.lang.Boolean.toString(boolean)
java.lang.Byte.toString(byte)
java.lang.Character.toString(char)
..
object = 객체의 toString() 호출   => 그럼으로 재정의가 필요함

(2)String -> primitive
java.lang.Boolean.valueOf(String);
java.lang.Integer.valueOf(String);
...
object의 경우 new String(String)   => 구현에 문제가 있다. 스트링에서 객체를 어떻게 구성할 것인가?
object = new object();
object.booleanA = Boolean.valueOf(String[0]);
object.intA = Integer.valueOf(String[1]);
... 식으로..

****매개변수의 유효성을 검증해주는 메서드 필요****
boolean isValidMyObject() 식으로

****아까 위에서 거론했지만.. 디폴트생성자가 기본임으로 디폴트생성자->매개변수생성자->init() 메서드 호출 필요***

(ex)
public A(){
 this(5)
}

public A(int a){
this.temp = temp;
init();
}

private void init(){
 maxTemp = this.temp + 10;
 ...
 if(maxTemp > 10)
    status = Status.Max;
 else
    status = Status.Normal;
}


****빈을 구현해본 자작 병신코드 OTL ***

package com.taglib.jsp.components;

import java.util.StringTokenizer;

//복리이자를 계산해주는 빈
// 복지 적용시 원금 계산
// 지불금액 = 원금* (1+이자율(요것도 연이율/기간))의 복리횟수(연도/기간)의제곱 (한마디로 등비 수열이었나??)
public class CompoundInterestBean  //아하하 implements Serializable 까먹음...
{
private double principal; //원금
private int years; //총기간
private int compound; //복지이자가 누적되는 단위기간
private double interestRate; //이자율
private double futureValue; //미래 금액
//타입이 달라서 컨테이너 보관이 안돼니.. 망할 ..ArrayList<Object> 로 처리할까 보다 -_-;
//1.디폴트 생성자
public CompoundInterestBean()
{
// super();
// this.principal = 0.d;
// this.years = 0;
// this.compound = 0;
// this.interestRate = 0.d;
// this.futureValue = 0.d;
this("1000.0,12,1,8.0"); //매개변수 있는 생성자 사용대신 super()를 사용 못하게됨 ㅠㅠ
}
//1.1매개변수 있는 생성자 (이놈 쓸라면 스클립틀릿 or 표현식 필요)
public CompoundInterestBean(String params)
{
//jvm 매개변수로 -ea 인가 필요
//assert init(params) == true : "CompoundInterestBean(String params)실패";
try
{
init(params);
}
catch(Exception e)
{
e.printStackTrace();
}
}
//입력 처리용 내부 메서드 (이걸 public 으로 풀어줄 필요가 있을까??? 내부 작업용 메서드인데..private로 하는게?)
private void init(String params) throws Exception //익셉션 클래스 따로 만들기 귀찮!
{
// 1.,로 구분되어 있다고 가정한다. 
// 2.필요한 토큰은 5개 (타입이 int와 double로 다름으로 반복문 사용 안됨)
// 3.토크나이저를 사용한다.
// 1.예외처리 (throw나 throws 선언은 안하기~) 
if((params.length() > 0) && (" ".equals(params)) == false)
{
//2.잘라내기 위해 토크나이저 생성
StringTokenizer tk = new StringTokenizer(params,",");
//3.토큰 갯수 검사
if(tk.hasMoreTokens() && tk.countTokens() == 4) //상수 때려받아서 죄송
{
//4.각각의 매개변수의 범위를 체크한다.
Double principal = Double.valueOf(tk.nextToken());
if(!isValidPrincipal(principal))
throw new Exception();
int years = Integer.valueOf(tk.nextToken());
if(!isValidYear(years))
throw new Exception();
int compound = Integer.valueOf(tk.nextToken());
if(!isValidCompound(compound))
throw new Exception();
Double interestRate = Double.valueOf(tk.nextToken());
if(!isValidInterestRate(interestRate))
throw new Exception();
//5.순서대로 변환해서 가져온다.
this.principal = principal;
this.years = years;
this.compound = compound;
this.interestRate = interestRate;
//6.미래 이자 계산도 여기서 해야할까?
//this.futureValue = getFutureValue();
this.futureValue = 0.d;
}
else
{
throw new Exception();
}
}
}
//2.게터세터
public double getPrincipal() {
return principal;
}

public void setPrincipal(double principal) {
this.principal = principal;
}

public int getYears() {
return years;
}

public void setYears(int years) {
this.years = years;
}

public int getCompound() {
return compound;
}

public void setCompound(int compound) {
this.compound = compound;
}

public double getInterestRate() {
return interestRate;
}

public void setInterestRate(double interestRate) {
this.interestRate = interestRate;
}

public double getFutureValue() 
{
//계산해야 한다. 계산해서 futureValue 초기화해줄 내부 메서드 추가
calcutateFutureValue();
return futureValue;
}

// public void setFutureValue(double futureValue) {
// this.futureValue = futureValue;
// }
//3.toString 구현 (모든 프로퍼티를 ,로 붙여서)
public String toString()
{
// String retVal = new String("");
// //갯수가 적으니 StringBuffer나 Builder 안쓰고 String으로 처리
// retVal += this.principal + ',' + this.years + ',' + this.compound + ','
//  + this.interestRate + ',' + this.futureValue + ',';
// //아 코드 드럽다.
// return retVal;
return "" + this.principal + ',' + this.years + ',' + this.compound + ','
 + this.interestRate; //futureValue는 리턴값임으로 제외
}
//4.요 빈의 특별 서비스 메서드  복리 계산해서 토탈 금액 반환해주기
private void calcutateFutureValue()
{
this.futureValue = this.principal * Math.pow(1+ this.interestRate / this.compound,
this.years / this.compound);
}
//5.매개변수 프로퍼티의 유효성을 체크 (이것들도 private가 맞지만.. jsp에서 사용할지도 모르니;; public으로 열어놨다!
public boolean isValidPrincipal(double principal)
{
boolean retVal = true;
//원금은 음수,0 일수 없다. double 범위 체크는 안해도 될듯..
if(principal <= 0.d)
{
retVal = false;
}
return retVal;
}
public boolean isValidYear(int year)
{
boolean retVal = true;
//연도는 음수,0일수 없다. 마찬가지로 int 범위체크 불필요
if(year <= 0)
{
retVal = false;
}
return retVal;
}
public boolean isValidCompound(int compound)
{
boolean retVal = true;
//이자율 계산 기간의 경우.. 1이면 1달마다 2면 2달마다  12면 1년마다 
//그럼으로 음수,0만 체크하면 된다?
if(compound <= 0)
{
retVal = false;
}
return retVal;
}
public boolean isValidInterestRate(double interestRate)
{
boolean retVal = true;
//이자율이야 고리대금이면.. 엄청 클수 있으니까.. 
//음수,0 체크만
if(interestRate <= 0.d)
{
retVal = false;
}
return retVal;
}
}


******************BeanInfo 인터페이스의 존재의미**********

<pre>public interface BeanInfo</pre>

Bean 의 구현자는, 이 BeanInfo 인터페이스를 구현하는 BeanInfo 클래스를 제공해, 자신의 Bean 의 메소드, 프로퍼티, 이벤트 등에 관한 명시적인 정보를 제공할 수가 있습니다.

Bean 의 구현자는, 명시적인 정보를 모두 제공할 필요는 없습니다. 제공하는 정보를 선택할 수가 있어 나머지는 Bean 클래스의 메소드의 저레벨 리플렉션을 사용한 자동 해석 및 표준의 디자인 패턴의 적용에 의해 취득할 수 있습니다.

사용자는, 각 Descriptor 클래스의 일부로서 매우 많은 종류의 정보를 제공할 기회가 주어지게 됩니다. 그러나, 각 생성자 이 필요로 하는 최소한의 코어 정보를 제공하는 것만으로도 충분합니다.

BeanInfo 클래스의 편리한 「무조작」base class를 제공하는 SimpleBeanInfo 클래스도 참조해 주세요. 이것을 사용하면(자), 명시적인 정보를 제공하고 싶은 특정의 개소를 오버라이드(override) 할 수 있습니다.

Bean 의 모든 동작에 대해 알려면 Introspector 클래스를 참조해 주세요.


=>기존에 만들어둔 자바 클래스에 요 인터페이스를 구현하면.. jsp 컴포넌트 개발 가능



<pre>public class SimpleBeanInfo
extends Object
implements BeanInfo
</pre>

사용자가 BeanInfo 클래스를 제공하기 쉬워지도록(듯이) 하는 지원 클래스입니다.

무조작 (noop) 정보의 제공을 디폴트로 설정합니다. 또, 선택한 토픽에 대한보다 명시적인 정보를 제공하기 위해서, 선택적으로 오버라이드(override) 되는 일이 있습니다. 인트로스페크타는 "noop" 치를 검출하면(자), 저레벨의 인트로스페크션 및 설계 패턴을 적용해, 타겟 Bean 를 자동적으로 해석합니다.



*****Serializable 인터페이스 구현하기 필요*****

서버가 동작 멈출때 파일,디비등에 빈정보 기억했다가 로드하거나,

트래픽이 많은 환경에서의 클러스트링(db에 쿼리쏠때 연결되는 작업지시를 버퍼에 담아두는

것)을 지원하는 서버에서 필요하다.



******스클립틀릿과 빈 태그 함께 쓰기*******


<jsp:useBean id="xxx" class="xxxBean" scope="page" />

xxx xxxx <jsp:getProperty name="xxx" property="a" />

<jsp:useBean id="xxx" class="xxxBean" scope="page" />

xxx xxx <%= xxx.getA() %> 

는 동일하다.


=>주의할점: getA()를 통해 리턴되는 타입이 String인지 확신할 수 없다!!!!


'프로그래밍 > JSP' 카테고리의 다른 글

jsp ~ jdbc  (0) 2014.01.01
jsp에서 빈의 사용3  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
jsp 스크립트  (0) 2014.01.01
part2(2013/11/27)  (0) 2014.01.01
by givingsheart 2014. 1. 1. 15:58
물론 빈과 태그를 이용해 컴포넌트 방식으로 app를 개발하는 방식에는 다양한 방법이 있을것이다.
ejb (엔터프라이즈 자바빈), 스프링 프레임웍, jsp 등등등.. 하여간 자바 프레임 워크는 정말로 엄청나다;;

(4)빈(bean) 관련 태그: 서버측 자바빈의 액션은 <jsp:useBean>, <jsp:setProperty>, <jsp:getProperty>가 존재하며
                                빈(컴포넌트)을 이용한 컴포넌트 중심의 설계는 프리젠테이션과 애플레케이션 로직을 나누어준다.

=>빈은 기능별로 a.비주얼 컴포넌트 빈 b.데이터 빈 c.서비스 빈(비지니스) 으로 나뉜다.

클래스와 마찬가지로 데이터 + 동작을 묶어서 외부에선 내부의 복잡한 구현을 몰라도 간단하게 인터페이스 메서드를 통해 지시
하면 된다. = 동작 원리의 추상화 (abstraction) 캡슐화 (encapsulation)

=>인터페이스를 통한, 다형성을 통한 상위 수준의 추상화 = 디자인 패턴들 = 설계

은행창구 사용자 인터페이스 <-> 계좌 관리 모듈 <-> db접근용 컴포넌트 <-> db


=>그럼으로 빈은 표준화된 타입이어야만 한다. ojbect만 상속받고, 데이터, 디폴트 생성자, 세터와 게터, toString, 
    eqaul, hashCode, 기록할 용도라면 직렬화 선언이 필요하다. (clone,compareTo등은 도메인오브젝트에서 제공안한다)
    (예전에 배웠던 do(vo,dto)가 또 나오네;;)


 태그기반의 컴포넌트(빈) 프로그래밍의 예

//빈 사용 선언
<jsp:useBean id="user" class="RegisteredUser" scope="session" /> //id는 각 빈인스턴스의 식별 역할
<jsp:useBean id="news" class="NewsReports" scope="request" />  //스코프(생존주기)의 차이 확인!
   //빈 초기화
  <jsp:setProperty name="news" property="category" value="financial" />  셋프로퍼티할때 name은 useBean시의 id와 같다
  <jsp:setProperty name="news" property="maxItems" value="5" />   xml문법에서 "" 를 주의할것
</jsp:useBean>

**********************************************
//setProperty사용시 기억할것은.. 사용자의 폼(브라우저)로부터 입력 받은 값은 request객체에 담겨오고 그것을 value=에 담아줄
//수도 있지만 사용자 폼에서 넘어오는 매개변수 이름과 빈에 설정된 프로퍼티 이름이 동일할 경우 param 키워드로 바로 가져올수
//있다. 물론 프로퍼티 이름과 매개변수 이름이 같을 경우 param 역시 생략이 가능하다.

<jsp:setProperty name="news" property="category" param="category" />
<jsp:setProperty name="news" property="category" value=' <%= request.getParameter("category") %> ' /> (표현식)은 동일하다.
<jsp:setPropertry name="news" property="category" /> 도 프로퍼티,매개변수이름이 같을때 위와 동일하다.
***********************************************


<html> //헤더는 생략 가능?
<body>
Welcome back <jsp:getProperty name="user" property="fullName" />,
your last visit was on <jsp:getProperty name="user" property="lastVisitDate" />,
Glad to see you again!
<P>  //이건 뭔지 아직 명확치 않지만, 라인 넥스트로 여겨진다. 개행
There are <jsp:getProperty name="news" property="newItems" /> new articles abailable for your reading pleasure.
Please enjoy your stay and come back soon.
</body>
</html>


//사용자가 보게되는 프리젠테이션 영역 페이지에선
<html>
<body>
<form action="UserInfoResults.jsp">
Category: <input type="text" name="category">
MaxItems: <input type="int?" name="maxItems">
...
<input type="submit" value="UserInfo Value"> //식으로 위의 빈 초기화 page에 전달할 것이다.
</form>
</body>
</html>

=>사용자 id,pw 같은 경우 은닉필드에 저장해서 주고 받아선 안됀다. (html 소스 보기하면 나오기 때문) 그럼으로
빈태그 , 스클립틀릿으로 작성된 jsp페이지에서 이런 민감한 정보를 관리해야한다.

=>setProperty 할때 <jsp:setProperty property="*"> 식으로 와일드 카드로 사용자로 부터 전달받은 매개변수를 빈에 간단히 
대입할 경우 위험성이 있다.

(ex) AccountBean 빈으로 계좌 정보를 출력해주는 온라인 뱅킹 애플리 케이션의 경우
AccountBean 클래스는 accountNumber(계좌번호) , balance(잔고), withdrawalAmount(인출액), transferAmount(이체액)
같은 계좌 거래에 대한 프로퍼티가 존재한다. 아래처럼 폼을 통해 사용자에게 인출액을 지정하게 하면 지정된 jsp 폼 핸들러
가 작동하여 실제 거래를 수행하고(프로퍼티 값 세팅의 부가 효과 발생) 그 결과를 출력한다고 가정했을때..

<jsp:useBean id="myAccount" class="AccountBean">
  <jsp:setProperty name="myAccount" property="*"/>   <--와일드 카드로 대입
=>일반적으로 디폴트 값을 명시적으로 세팅하는 이유는.. null값=valus의 대입을 방지하고, 다양한 방법으로 페이지를 엑세스 
할수 있게 하기 위함이다.
</jsp:useBean>
<html>
<head><title>Cash Withdrawal</title></head>
<body>
<p>
$ <jsp:getProperty name="myAccount" property="withdrawalAmount" /> has been withdrawn from Account
# <jsp:getProprtty name="myAccount" property="withdrawalAmount" /> . 
Your new balance is $<jsp:getProperty name="myAccount" property="balance" />.   <---잔고 프로퍼티가 노출됨
Thank you for patronizing us at the First Bank of Orange.

이 페이지의 URL이 withdraw.jsp 일때 , 사용자가 다음과 같은 request를 보냈을때 어찌할 것인가?
http://server/acount/withdraw.jsp?accountNumber=PH1L31N&balance=1000000000   

=> string의 경우 ..match("?!@#$%^&*") 식으로 처리해서 검증을 하는건 어떨까?

jsp 컨테이너는 withdraw.jsp 페이이지의 <jsp:setProperty> 태그를 처리하면서 이 매개변수와 동일한 이름을 가진 balance
프로퍼티를 찾아서 100000000을 넣어준다.  OTL

***************************************************************************

1.<jsp:useBean> 속성으론
(1)id : 주어진 페이지에서 해당 빈 인스턴스를 식별하는 역할
(2).scope : page, request, session, application
(3)class : 빈클래스의 효과적인 관리를 위해 일반적으로 패키지로 묶어 관리한다. 빈 클래스는 패키지명을 지정해줘야 하지만,
import  또는 <%@page %> 지시자 태그를 통해 클래스 이름만으로 사용이 가능하다.
(4)type : 수퍼클래스나 이 빈이 구현한 다른 인터페이스 타입으로 참조할 필요가 있을 경우 세팅
(5)beanName : 중요치 않음(매번 초기화가 복잡한 빈의 경우.. 직렬화를 이용해 사본을 db,file등에 넣어두고 beanName을 이용해
                      인스턴스화 시킴)
(6)태그 몸체 : <jsp:useBean>  </jsp:useBean> 사이에 존재하는 초기화 코드 조각

2.인덱스 프로퍼티 접근하기
<B>Tomorrow's Forecast </B>: <%= weather.getForecast(0) %>  //스클립틀릿중 표현식
<BR>
<B>The Rest of the Week</B>
<UL>
<% for(int index=1; index<5; index++) { %>
<LI> <%=weather.getForecast(index) %> (maybe)
<% } %>
</UL>

****************************************************************************

TimerBean 예제

//페이지 정의부
<%@ page import="com.taglib.wdjsp.components.*" %>  //페이지 지시자 스크립트로 라이브러리 임포트
<jsp:useBean id="timer" class="com.manning.jsp.TimerBean" scope="session" /> //빈 정의시 id , 빈 프로퍼티 사용시 name

//사용자에게 출력부
<html>
<body>
Elaped Time: <jsp:getProperty name="timer" property="elapedMinutes" /> minutes
</body>
</html>

=> 위의 기능을 모든 jsp페이지에 넣고 싶다면? = 원하는 페이지 파일에다 <jsp:include> 빈 태그를 넣어주면 된다.


***************************************************************
//웹기반의 온라인 퀴즈 프로그램에서 위의 개념(빈의 기능 include)을 이용해본다면?
<html>
<body>
//폼 액션 정의부
<form action="/servlet/processQuestions/6">  //페이지 컨트롤링할 서블릿 설정
<b>Question 6 </b><br> //<b>는 bold인듯 하고.. br은 아마 개행 아닐까 싶다..
What is the airspeed velocity of an unlaiden European swallo?
<br> <input type="text" name="answer"> //텍스트로 입력받고 입력 값 객체의 이름을 answer로 한다.
<br> <input type="submit" value="Submit Answer"> //서블릿에 제출할 입력으로 그 객체의 이름은 Submit Answer로 한다.
</form>

//연결할 jsp 페이지(저 위에 만들어놓은 빈을 import할) 정의
<jsp:include page="/footers/ElapsedTimeFooter.html" flush="true" /> //자동 출력한다.

</body>
</html>


//ElapedTimeFooter.html 파일의 구성
<jsp:useBean id="timer" class="com.manning.jsp.TimerBean" scope="session" />
<hr>
Remember, speed is a factor in this exam! <BR> //개행인듯..
Time Used: <jsp:getProperty name="timer" property="elapsedSeconds" /> seconds


*****************************************************************************
빈을 어플리케이션(jsp,리소스들 모음인 내가 사용자에게 제공할 프로그램) 스코프에 저장했을 경우 유용성
1.서버에 저장되는 빈 인스턴스는 오직 1개이다. (매번 요청,페이지 변경,세션 변경등 시에 새로 객체 생성할 필요가 없다)
2.여러 페이지에서 공유가 가능핟.(그럼으로 동기화 처리가 중요)
3.서버(jsp컨테이너)가 인스턴스가 없으면 알아서 생성하고.. 서버 꺼질때 기록하는등 귀찮은일을 알아서 해준다.

<jsp:useBean id="ship" class="com.mannig.ShipRateBean" scope="application">
//초기화 코드조각
</jsp:useBean>
<html>
<body>
Current shipping charges are: <jsp:getProperty name="ship" property="baseCharge" />
per shipment plus <jsp:getProperty name="ship" property="perItemCharge" />
per each item shipped.
</body>
</html>

******************************************************************************
scope와 빈의 type 속성
 대게 어떤 슈퍼클래스의 서브클래스로 만들어진 빈을 조작할 때에만 사용한다.
 어떤 빈이 현재의 스코프(request,session)에 있는데, 정확한 타입을 알 수 없을경우..
 type클래스에 저장된 속성을 사용하면 된다. 

 어떤 서블릿,jsp 페이지에서 빈 컬렉션을 세션에 저장했다고 가정했을때 해당 빈의 타입
 이 자바의 Collection 인터페이스에서 갈라져 나온 클래스인것을 알지만, List인지 Set인지
 정확히 모를경우 type속성에 저장해둔 Collection 속성으로 빈을 참조할수 있다. 한마디로
 type 속성은 다형성을 지원하는 개념이다.

<jsp:useBean id="elements" type="java.util.Collection" scope="session" />


'프로그래밍 > JSP' 카테고리의 다른 글

jsp에서 빈의 사용3  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
jsp 스크립트  (0) 2014.01.01
part2(2013/11/27)  (0) 2014.01.01
javax.servlet.http.HttpServlet 소스코드 part1 (2013/11/27)  (0) 2014.01.01
by givingsheart 2014. 1. 1. 15:57
**jsp태그 -> xml태그로 표현이 가능하다!**

1.jsp지시자(directive) 태그 (124p)    <%@ xxx xxx="xxx" %>   , <jsp:directive.page xxx="xxx"/>

 (1)page 지시자란? <%@ page %>
   info
   laguage                  language="java"
   contentType            contentType= "text/xml"  or  "text/html; charset=ISO-8859-1"
   pageEndcoding       pageEncoding= "UTF-8"
   extends                  jsp->컴파일->서블릿 클래스가 상속받을 슈퍼클래스 (디폴드로 사용할것. 컨테이너가 알아서 선택해줌)
   import                     import="java.net.URL"
   session                  session="true" (세션 관리에 참여할 페이지여야 추후 내부객체를 통해 세션 정보 다룰수 있음)
   buffer                      buffer="12kb" (디폴트 8kb면 충분)
   autoFulsh                autoFlush="true" (버퍼 차면 알아서 flush, 주의할 것은 일단 쏘면.. 더이상 처리,수정,조작 불가능.. 
                                 페이지가 생성하는 출력 양이 예측 어려우면 true로 하돼, 가급적 여러 작업들을 처리할 경우 false)
   isThreadSafe           isThreadSafe="true" (가급적 true로 할것, db등 리소스 접근시에 특별한 처리 db커넥션 풀의 활용이
                                 필요함)
   errorPage                errorPage="/park/error.jsp"
   isErroePage             errorPage="true"

 (2)include 지시자란?  <%@ include  %> , <jsp:directive.include xxx="xxx" />
                               주어진 파일(경로+파일명)을 페이지에 include 시킨다.  (c,c++ 인클루드와 동일)
                               <%@ include file="includes/park01.jsp" %>

 (3)taglib 지시자란? <%@ taglib uri = "tagLibraryURI" prefix="tagPrefix" %> <jsp:directive.taglib uri="xx" prefix="xx" />
                             다른 라이브러리 사용한다고 컴파일러에게 선언 (뒤에 prefix는 접두어-네임스페이스 역할)
                             url 이 아닌, 로컬의 uri인 이유는? = 보안 문제(세상에 믿을놈 없음..서버가 외부 데이터를 믿으면 안됌)

 2.스크립트 태그(scripting elements)
     (1)선언문 : 주어진 jsp페이지에서 사용할 변수와 메소드를 정의   <%! xxx %>  , <jsp:declaration> xxx </jsp:declaration>
                    (메소드 정의시 중괄호 조심)

                    jsp초기화 메서드 jspInit() , 소멸 메소드 jspDestroy()란 이름으로 제공함으로 구현해서 사용~

     (2)표현식: 값을 받아서 출력하는 용도  <%= 표현식 %>  ,  <jsp:expression> 표현식 </jsp:expression>
                   (숫자,문자,불린,스트링,자바객체 타입 사용가능.. 단 모든 표현식은 출력전에 문자열로 변환됨 toString() )

     (3)스클립틀릿: 자바 코드임 (변수,메서드,논리조건,반복조건,"예외처리")
                     <% 스클립틀릿 %> ,  <jsp:scriptlet> 스클립틀릿 </jsp:scriptlet>
                     {} 중괄호 블럭은 자바와 마찬가지로 지역 scope를 의미.

     => 스클립틀릿,표현식,정적컨텐츠,자바빈은 출력을 위해 사용된다. jsp->서블릿으로 컴파일 된후 서블릿의 _jspService()
         메소드를 구축한다.  표현식은 컴파일 되는데 비해, 스클립틀릿,자바빈은 컴파일(파싱) 없이 바로 사용됨
         아참 html은 브라우저에 바로 출력되기 위한 스크립트이고..

     => 스클립트 내에 정의하는 메서드에 throws 키워드를 선언후 콜러측이 try,catch 처리하게 하는등 .. 자바의 예외처리
         프로세스 동일하게 사용가능.

     =>단지 스클립틀릿을 jsp에 사용하면 코드의 유지및 웹디자이너와 업무 분담이 곤란해짐. 그럼으로 각종 태그를 사용

 
3..주석문  <!-- 컨텐츠주석으로 브라우저의 html보기를 통해 보여짐 -->  <%-- jsp주석문 --%> <% /*편하다*/ %>

4-1 내부 표준 객체 액션 (jsp가 디폴트로 제공하는 내부객체를 통한 표준액션)
 
 =>기능상 jsp페이지 서블릿에 관계된 객체, 페이지 입출력에 관계된 객체, jsp페이지가 처리되는 동안 외부 환경 정보를 제공
   하는 객체, 에러 때문에 생긴 객체로 나뉜다.  

  그중 request, session, application, pageContext 객체는 속성(attribute=String key, Object value)를 읽고 쓸수 있다.

  *********서블릿 관련 내부 객체************
  (1)page:페이지의 서블릿 인스턴스  (javax.servlet.jsp.HttpJspPage)
     <%@ page info="xxx" %>
      Page info: <%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %>

  (2)config:서블릿 구성데이터 (javax.servlet.ServletCofig)
      <%! static private DbConnectionPool pool = null;
            pulbic void jspInit()
            {
              if(pool == null)
              { 
                String username = config.getInitParameter("username");
                String password = config.getInitParameter("password");
                pool = DbConnectionPool.getPool(this, username, password);
              }
            }
       %>
  
  ********입/출력용 객체**********        
  (3)request:요청데이터 (java.servlet.http.HttpServletRequest)
     =>현재의 페이지 처리를 시작하게한 요청 정보를 가지고 있는 객체로 요청url,헤더,쿠키,그외 매개변수를 얻을수 있다.
     =>요청 매개변수를 액세스하기 위한 메서드, 요청 헤더,쿠키를 읽기위한 메서드,url등을 읽기위한 메서드가 있다.

  (4)response:응답데이터 (java.servlet.http.HttpServletResponse)
     =>회신용 컨텐츠의 타입(ContentType,Encoding)을 설정하는 메서드, 헤더를 세팅하기 위한 메서드, 응답 상태코드를
        설정하기 위한 메서드, utl 다시 쓰기를 위한 메서드가 있다.

  (5)out:페이지 컨텐츠 출력용 스트림 (javax.servlet.jsp.JspWriter)
      =>스클립틀릿을 통해 출력을 담당하며 (isAutoFlush(), getBufferSize(), getRemaining(), clearBuffer(), newLine(),
          clear(), flush(), close() 등의 java의 printwriter(내부적으로 버퍼 필터계열사용) 객체처럼 쓸수 있음)

      <P>counting eggs
       <% int count = 0;
            while(cartoon.hasNext())
            {
                count++;
                out.print(".");   <-- 바로 웹브라우저에 표시가 된다.(정적컨텐츠,jsp표현식 필요없이도)
             }
        %>
        <BR>
         There are <%= count %> eggs.
         </P>
  
  *************컨텍스트 객체*************
  (6)session:여러페이지에 대한 사용자 각각의 세션 정보(javax.servlet.http.HttpSession)
     =>세션 유지및 관리를 위해 필요한 정보를 세팅할 수 있는 메서드 제공 

  (7)application:프로그램자체(jsp묶음)로 모든 페이지가 공유하는 데이터(javax.servlet.ServletContext)
     =>application.setAttribute("xxx", xxx); 를 통해 jsp페이지들이 데이터를 공유가 가능 (ex: 디비연결pool 객체)

     => getSeverInfo() : 서블릿 컨테이너의 이름과 버전
         ...
         getMimeType(filename) : 지정된 파일의 mime 타입 반환 (text/html등)
         getResource(path): 매개변수 url패스의 컨텐트(네트워크,로컬)를 엑세스하느 객체 반환
         getResourceAsStream(path): url패스의 컨텐트를 읽어 올수 있는 입력 스트림 객체 반환
         getContext(path): url패스에 대한 애플리케이션의 외부 환경 정보를 반환
         getRequestDispatch(path): url패스에 대한 요청 전달자(dispatcher) 반환 
         ...
         log(message) : 로그 기록용
         log(message, exception): 로그 기록 + 스택 결과(printStackTrace())

  (8)pageContext:jsp페이지가 실행되는 시점에서 외부 환경 데이터 (javax.servlet.jsp.PageContext)
      =>모든 jsp 내부객체의 속성을 얻을수 있는 메소드 + 현재 페이지에서 다른 페이지로 흐름 제어를 넘길수 있음.
         (jsp 커스텀 태그를 구현할때 사용됨)
  
      =>getPage() : 현재 페이지에 대한 서블릿 인스턴스(page내부객체) 반환
         getRequest() : 현재 페이지의 요청 객체 반환
         getResponse() : 현재 페이지의 응답 객체 반환
         getOut() : 현재 페이지의 출력 스트림 객체 반환
         getSession() : 현재 페이지를 요청한 세션 객체 반환
         getServletConfig() : 서블릿 구성 객체(config내부객체) 반환
         getServletContext() : 현 페이지의 서블릿이 실행되는 외부 환경(context=매니저 객체) 즉 application 객체를 반환
         getException() : 에러 페이지가 있을 때 이 페이지에 넘겨지는 예외(exception 내부객체) 반환

         forward(path) : 요청 처리를 다른 로컬 url로 전달
         include(path) : 다른 로컬 url을 처리한 결과를 이 페이지에 포함

         setAttribute(key, value, scope) : 특정 스코프(page등) 정보 기록
         ...
         getAttributeNamesInScope(scope) : 특정 스코프에 있는 모든 속성의 이름을 뽑아냄
         getAttribute(key, scope) : 특정 스코프에 있는 key값에 해당하는 value 반환
         ...

        PageContext.SESSION_SCOPE, PageContext.APPLICATION_SCOPE, PageContext.REQUEST_SCOPE, ...

      =>어플리 케이션 스코프가 가장 수명이 길고, 그 담이 세션이다. 페이지,요청 스코프는 한번에 스레드 하나만 접근가능
         하지만, 어플레 케이션&세션 스코프는 그렇지 않기에 멀티스레딩 처리를 해야한다.

 ***********예외처리객체*************
  (9)exception:처리되지 않은 에러나 예외 (java.lang.Throwable)
     =>page 지시자(directive)에서 예외를 사용하겠다고 설정해야 사용이 가능한 내부 객체

     => getMessage() 
         printStackTrace(output)
         toString()

     <%@ page isErrorPage="true" %>
     <H1>경고 </H1>
     오류 발견~:<BR>
     <B><%= exception %></B><BR>
     <% exception.printStackTrace(new java.io.PrintWriter(out)); %>


4.2 jsp액션 
    =>페이지 사이를 전환하기 위해, 자바 애플릿의 설정, 자바진즈 컴포넌트를 사용할때 사용된다.
       모든 커스텀 태그는 jsp 액션의 형태를 뜨며, 액션의 경우 xml 문법만을 지원한다.

(1)forward 액션 태그    <jsp:forward page="localURL" /> (정적문서,cgi,서블릿,jsp로 제어권 넘김)
   =>일반적으로 조건 분기 코드에서 자주 쓰인다.
      <% if(!database.isAvailable()) {  %>
            <% 서버 유지 보수중이라 아웃 객체를 사용해 알리고 %>
            <jsp:forward page="db유지보수중.html" /> <--제어권 넘기고
           <% } %>
           <%-- 데이터베이스가 제대로 작동중 ~~ --%>

   =>제어권을 넘길때 기존 페이지의 출력 버퍼에 쌓인 내용들 모두 flush되고 close 된다. 
      a.그럼으로 <jsp:forward> 액션 사용전에 출력 버퍼가 비워지지 않게 한다. 
      b.버퍼 출력이 안되는 페이지의 경우 <jsp:forward> 액션을 컨텐트 출력 부분 앞에 둘것!

   =>요청 시점 속성값 (request-time attriute value)을 지원한다.

      <jsp:forward page= '<%= "message"  + statusCode  + " .html" %> ' />
       =>status값이 404이면 message404.html 이란 로컬 url로 제어가 넘어감

   =>제어가 넘어간 페이지는 pageContext가 새롭게 생성, request,session객체는 동일하게 유지, application도 옮긴 페이
      지가 같은 어플리케이션 이라면 유지됨. (일반적으로 페이지 전환시 요청,세션 객체에 정보를 기록)

    <jsp:forward page="로컬url">

       <jsp:param name="매개변수명1" value="매개변수값1" />
       <jsp:param name="매개변수명2" value="매개변수값2" />
       <jsp:param name="매개변수명3" value="매개변수값3" />
        ...
    </jsp:forward>


(2)include 액셔 태그: 제어권을 다른 페이지에 임시로 주는것.
    => 지시자 include에 비해 a.자동 재컴파일 b.작은 클래스 크기(여러 페이지에 코드 삽입x) c.매개변수 추가 기능
        d.요청 시점 속성값을 통한 더욱 유연한 제어 가능
         지시자 include의 경운 a.지역변수의 공유 b.조금 더 나은 실행시간 효율(제어권 이동x) c.출력 버퍼링에 제약x

    => 지시자(directive)를 통해 include 된 페이지: 원래의 페이지와 한몸
         액션 태그를 통해 include 된 페이지: 원래의 페이지의 바깥에서 요청을 넘겨받아, 그 처리결과를 원래의 페이지에 리턴
         (정적컨텐츠인 html, jsp 페이지, 서블릿, cgi 스크립트등 가른 형식의 파일까지 간접 인클루드 가능함)


    <jsp:include page="로컬url" flush="true">
      <jsp:param  name="매개변수이름1" value="매개변수값1" />
      <jsp:param  name="매개변수이름2" value="매개변수값2" />
      <jsp:param  name="매개변수이름3" value="매개변수값3" />
    </jsp:include>


(3)plug-in 액션 태그: <jsp:plugin> 액션은 자바 애플릿을 설정할수 있는 브라우저별 html 생성하는데 사용

(4)빈(bean) 관련 태그: 서버측 자바빈의 액션은 <jsp:useBean>, <jsp:setProperty>, <jsp:getProperty>가 존재하며
                                빈(컴포넌트)을 이용한 컴포넌트 중심의 설계는 프리젠테이션과 애플레케이션 로직을 나누어준다.


'프로그래밍 > JSP' 카테고리의 다른 글

jsp에서 빈의 사용3  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
part2(2013/11/27)  (0) 2014.01.01
javax.servlet.http.HttpServlet 소스코드 part1 (2013/11/27)  (0) 2014.01.01
by givingsheart 2014. 1. 1. 15:55
  
Called by the server (via the service method) to allow a servlet to handle a OPTIONS request. The OPTIONS request determines which HTTP methods the server supports and returns an appropriate header. For example, if a servlet overrides doGet, this method returns the following header:

Allow: GET, HEAD, TRACE, OPTIONS

There's no need to override this method unless the servlet implements new HTTP methods, beyond those implemented by HTTP 1.1.

Parameters:
req the HttpServletRequest object that contains the request the client made of the servlet
resp the HttpServletResponse object that contains the response the servlet returns to the client
Throws:
java.io.IOException if an input or output error occurs while the servlet is handling the OPTIONS request
javax.servlet.ServletException if the request for the OPTIONS cannot be handled
    protected void doOptions(HttpServletRequest reqHttpServletResponse resp)
        throws ServletExceptionIOException
    {
//아까 분석한 대로 내가 재정의한 HttpServlet 파생 클래스부터 HttpServelt 이전 까지 정의도니 내가
//"재정의한" 메서드들 리턴.
        Method[] methods = getAllDeclaredMethods(this.getClass());
        
        boolean ALLOW_GET = false;
        boolean ALLOW_HEAD = false;
        boolean ALLOW_POST = false;
        boolean ALLOW_PUT = false;
        boolean ALLOW_DELETE = false;
        boolean ALLOW_TRACE = true;
        boolean ALLOW_OPTIONS = true;
        
        for (int i=0; i<methods.lengthi++) {
            String methodName = methods[i].getName();

     //너무 직관적인 코드니 생략. get은 <a> <img>였나? 이미지나 문자 보낼때 자동으로
     //get메서드 실행되고, 그외엔 보안등 강점을 이유로 대부분 post로 사용한다고
    //했었던 기억이 뇌리를 스침..
            if (methodName.equals("doGet")) {
                ALLOW_GET = true;
                ALLOW_HEAD = true;
            } else if (methodName.equals("doPost")) {
                ALLOW_POST = true;
            } else if (methodName.equals("doPut")) {
                ALLOW_PUT = true;
            } else if (methodName.equals("doDelete")) {
                ALLOW_DELETE = true;
            }
            
        }
        
        // we know "allow" is not null as ALLOW_OPTIONS = true
        // when this method is invoked

//오 위에서 직관적이라 표현한 부분이 아래의 처리를 위해서 그런거였구나..
//내가 재정의한 메서드를 통해 나만의 스타일로 스크립트 문자열을 만들어주고 있는듯?
        StringBuilder allow = new StringBuilder();
        if (ALLOW_GET) {
            allow.append();
        }
        if (ALLOW_HEAD) {
            if (allow.length() > 0) {
                allow.append(", ");
            }
            allow.append();
        }
        if (ALLOW_POST) {
            if (allow.length() > 0) {
                allow.append(", ");
            }
            allow.append();
        }
        if (ALLOW_PUT) {
            if (allow.length() > 0) {
                allow.append(", ");
            }
            allow.append();
        }
        if (ALLOW_DELETE) {
            if (allow.length() > 0) {
                allow.append(", ");
            }
            allow.append();
        }
        if (ALLOW_TRACE) {
            if (allow.length() > 0) {
                allow.append(", ");
            }
            allow.append();
        }
        if (ALLOW_OPTIONS) {
            if (allow.length() > 0) {
                allow.append(", ");
            }
            allow.append();
        }
        
        resp.setHeader("Allow"allow.toString());
    }
    
    
    
Called by the server (via the service method) to allow a servlet to handle a TRACE request. A TRACE returns the headers sent with the TRACE request to the client, so that they can be used in debugging. There's no need to override this method.

Parameters:
req the HttpServletRequest object that contains the request the client made of the servlet
resp the HttpServletResponse object that contains the response the servlet returns to the client
Throws:
java.io.IOException if an input or output error occurs while the servlet is handling the TRACE request
javax.servlet.ServletException if the request for the TRACE cannot be handled
    protected void doTrace(HttpServletRequest reqHttpServletResponse resp
        throws ServletExceptionIOException
    {
        
        int responseLength;
//캐리지 리턴과 라인 넥스트의 조합? 한칸 내리고 제일 앞으로 땡기고? 타이핑?
// == 엔터키를 쳣을때 입력되는 값을 의미한다. (엔터치면 \r\n 이 들어옴)
        String CRLF = "\r\n";

// TRACE 도 스크립트 언어인듯함? 유저의 url주소 적어주고, 유저가 보낸 프로토콜(일반적으론 http)
//적어주고
        StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI())
            .append(" ").append(req.getProtocol());
//대충 .jsp파일 만들었을때 제일 앞에 위치하던.. 이 정보를 만드는 과정 아닐까? 싶은데..
//아직 기본개념및 이해가 부족하다...
/*
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

*/
        Enumeration<StringreqHeaderEnum = req.getHeaderNames();
        whilereqHeaderEnum.hasMoreElements() ) {
            String headerName = reqHeaderEnum.nextElement();
            buffer.append(CRLF).append(headerName).append(": ")
                .append(req.getHeader(headerName));
        }
        buffer.append(CRLF);
        responseLength = buffer.length();
        resp.setContentType("message/http");
        resp.setContentLength(responseLength);
        ServletOutputStream out = resp.getOutputStream();
        out.print(buffer.toString());
    }


    
Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class. This method is an HTTP-specific version of thejavax.servlet.Servlet.service(javax.servlet.ServletRequest,javax.servlet.ServletResponse) method. There's no need to override this method.

Parameters:
req the HttpServletRequest object that contains the request the client made of the servlet
resp the HttpServletResponse object that contains the response the servlet returns to the client
Throws:
java.io.IOException if an input or output error occurs while the servlet is handling the HTTP request
javax.servlet.ServletException if the HTTP request cannot be handled
See also:
javax.servlet.Servlet.service(javax.servlet.ServletRequest,javax.servlet.ServletResponse)
    protected void service(HttpServletRequest reqHttpServletResponse resp)
        throws ServletExceptionIOException
    {
//유저가 보낸 요청 메서드는 무엇이냐? get?post?
        String method = req.getMethod();
        if (method.equals()) {


//getLastModified가 뭐였지? part1에 있던건가.. part1에서 잘라왔음.
/*
<div class="line" id="line-245" style="font-family: 'Lucida Grande', Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: -2px 0px 0px; padding: 0px 0px 0px 10px; color: rgb(68, 29, 42); white-space: normal;"><div class="lnml" id="lnml-245" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px; display: inline;"></div><div class="ln" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px 6px; display: inline;">
245
</div><div class="lnmr" id="lnmr-245" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px; display: inline;"></div><pre style="margin-top: 0px; margin-bottom: 0px; display: inline;">    protected long getLastModified(HttpServletRequest req) {</pre></div><div class="line" id="line-246" style="font-family: 'Lucida Grande', Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: -2px 0px 0px; padding: 0px 0px 0px 10px; color: rgb(68, 29, 42); white-space: normal;"><div class="lnml" id="lnml-246" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px; display: inline;"></div><div class="ln" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px 6px; display: inline;">
246
</div><div class="lnmr" id="lnmr-246" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px; display: inline;"></div><pre style="margin-top: 0px; margin-bottom: 0px; display: inline;">        return -1;</pre></div><div class="line" id="line-247" style="font-family: 'Lucida Grande', Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: -2px 0px 0px; padding: 0px 0px 0px 10px; color: rgb(68, 29, 42); white-space: normal;"><div class="lnml" id="lnml-247" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px; display: inline;"></div><div class="ln" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px 6px; display: inline;">
247
</div><div class="lnmr" id="lnmr-247" style="font-family: 돋움, dotum, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: 0px; padding: 0px; display: inline;"></div><pre style="margin-top: 0px; margin-bottom: 0px; display: inline;">    }
</pre></div><div class="line" id="line-247" style="font-family: 'Lucida Grande', Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; list-style: none; margin: -2px 0px 0px; padding: 0px 0px 0px 10px; color: rgb(68, 29, 42); white-space: normal;"><pre style="margin-top: 0px; margin-bottom: 0px; display: inline;">*/</pre></div>


            long lastModified = getLastModified(req);
//수정된 서블릿은 부가적 작업을 건너뛰네?
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(reqresp);
            } else {
//어떤 경우에 일로 빠지는 거지? (maybeSetlastModified()가 변경하는건가?)
//나머진 내일 분석!!!!!
                long ifModifiedSince = req.getDateHeader();
                if (ifModifiedSince < lastModified) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resplastModified);
                    doGet(reqresp);
                } else {
                    resp.setStatus(.);
                }
            }
        } else if (method.equals()) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resplastModified);
            doHead(reqresp);
        } else if (method.equals()) {
            doPost(reqresp);
            
        } else if (method.equals()) {
            doPut(reqresp);
            
        } else if (method.equals()) {
            doDelete(reqresp);
            
        } else if (method.equals()) {
            doOptions(req,resp);
            
        } else if (method.equals()) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //
            String errMsg = .getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsgerrArgs);
            
            resp.sendError(.errMsg);
        }
    }
    
    /*
     * Sets the Last-Modified entity header field, if it has not
     * already been set and if the value is meaningful.  Called before
     * doGet, to ensure that headers are set before response data is
     * written.  A subclass might have set this header already, so we
     * check.
     */
    private void maybeSetLastModified(HttpServletResponse resp,
                                      long lastModified) {
        if (resp.containsHeader())
            return;
        if (lastModified >= 0)
            resp.setDateHeader(lastModified);
    }
   
    
    
Dispatches client requests to the protected service method. There's no need to override this method.

Parameters:
req the HttpServletRequest object that contains the request the client made of the servlet
res the HttpServletResponse object that contains the response the servlet returns to the client
Throws:
java.io.IOException if an input or output error occurs while the servlet is handling the HTTP request
javax.servlet.ServletException if the HTTP request cannot be handled
See also:
javax.servlet.Servlet.service(javax.servlet.ServletRequest,javax.servlet.ServletResponse)
    @Override
    public void service(ServletRequest reqServletResponse res)
        throws ServletExceptionIOException
    {
        HttpServletRequest  request;
        HttpServletResponse response;
        
        if (!(req instanceof HttpServletRequest &&
                res instanceof HttpServletResponse)) {
            throw new ServletException("non-HTTP request or response");
        }
        request = (HttpServletRequestreq;
        response = (HttpServletResponseres;
        service(requestresponse);
    }
/*
 * A response that includes no body, for use in (dumb) "HEAD" support.
 * This just swallows that body, counting the bytes in order to set
 * the content length appropriately.  All other methods delegate directly
 * to the wrapped HTTP Servlet Response object.
 */
// file private
    private static final ResourceBundle lStrings
        = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
    private NoBodyOutputStream noBody;
    private PrintWriter writer;
    private boolean didSetContentLength;
    private boolean usingOutputStream;
    // file private
        super(r);
         = new NoBodyOutputStream();
    }
    // file private
    void setContentLength() {
        if (!) {
            if ( != null) {
                .flush();
            }
            setContentLength(.getContentLength());
        }
    }
    @Override
    public void setContentLength(int len) {
        super.setContentLength(len);
         = true;
    }
    @Override
    public void setContentLengthLong(long len) {
        super.setContentLengthLong(len);
         = true;
    }
    @Override
    public void setHeader(String nameString value) {
        super.setHeader(namevalue);
        checkHeader(name);
    }
    @Override
    public void addHeader(String nameString value) {
        super.addHeader(namevalue);
        checkHeader(name);
    }
    @Override
    public void setIntHeader(String nameint value) {
        super.setIntHeader(namevalue);
        checkHeader(name);
    }
    @Override
    public void addIntHeader(String nameint value) {
        super.addIntHeader(namevalue);
        checkHeader(name);
    }
    private void checkHeader(String name) {
        if ("content-length".equalsIgnoreCase(name)) {
             = true;
        }
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if ( != null) {
            throw new IllegalStateException(
                .getString("err.ise.getOutputStream"));
        }
         = true;
        return ;
    }
    @Override
        if () {
            throw new IllegalStateException(
                .getString("err.ise.getWriter"));
        }
        if ( == null) {
            OutputStreamWriter w = new OutputStreamWriter(
                getCharacterEncoding());
             = new PrintWriter(w);
        }
        return ;
    }
/*
 * Servlet output stream that gobbles up all its data.
 */
// file private
    private static final String LSTRING_FILE =
        "javax.servlet.http.LocalStrings";
    private static ResourceBundle lStrings =
        ResourceBundle.getBundle();
    private int contentLength = 0;
    // file private
    NoBodyOutputStream() {}
    // file private
    int getContentLength() {
        return ;
    }
    @Override
    public void write(int b) {
        ++;
    }
    @Override
    public void write(byte buf[], int offsetint len)
        throws IOException
    {
        if (buf == null) {
            throw new NullPointerException(
                    .getString("err.io.nullArray"));
        }
        if (offset < 0 || len < 0 || offset+len > buf.length) {
            String msg = .getString("err.io.indexOutOfBounds");
            Object[] msgArgs = new Object[3];
            msgArgs[0] = Integer.valueOf(offset);
            msgArgs[1] = Integer.valueOf(len);
            msgArgs[2] = Integer.valueOf(buf.length);
            msg = MessageFormat.format(msgmsgArgs);
            throw new IndexOutOfBoundsException(msg);
        }
         += len;
    }
    public boolean isReady() {
        return false;
    }
    public void setWriteListener(WriteListener writeListener) {
    }


'프로그래밍 > JSP' 카테고리의 다른 글

jsp에서 빈의 사용3  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
jsp 스크립트  (0) 2014.01.01
javax.servlet.http.HttpServlet 소스코드 part1 (2013/11/27)  (0) 2014.01.01
by givingsheart 2014. 1. 1. 15:10


아하하.. 반갑다 java.lang.reflect 여기서도 보는구나  
아래 매개변수 선언은 상속 계층트리에 속하는 타입이라면 매개변수로 받을수 있다는
의미!  ( Class<? extends HttpServlet> <--요까지가 클래스 타입   c )
    private Method[] getAllDeclaredMethods(Class<? extends HttpServletc) {
        Class<?> clazz = c;
        Method[] allMethods = null;
//아래는 상속 계층에서 HttpServlet 계층 트리에 속한 내가 정의한 실제 구체적 타입 부터 
최대 HttpServlet 타입 바로전 까지 반복하는 작업 (간단하게 내가 정의한 클래스계층 -> HttpServlet 전까지 조회 한다는 의미)
        while (!clazz.equals(HttpServlet.class)) {
//이번 턴에 찾아낸 클래스에 정의된 모든 메서드 타입 객체(object에 상속받았으니 객체)를 가져와라~
            Method[] thisMethods = clazz.getDeclaredMethods();
//이미 찾은게 있냐?
            if (allMethods != null && allMethods.length > 0) {
//기존에 찾은 메소드를 임시변수인 서브클래스 메소드에 담아두고
                Method[] subClassMethods = allMethods;
//새로 찾은 메소드와 기존 메소드의 갯수를 합친 크기만큼 새롭게 저장 공간을 할당한다.
                allMethods =
                    new Method[thisMethods.length + subClassMethods.length];
//많이 보던 시스템 어레이카피 = 깊은 복사
//방금 찾은 따뜻한 메소드 부터 배열의 앞에 복사해준다.
                System.arraycopy(thisMethods, 0, allMethods, 0,
                                 thisMethods.length);
//기존에 찾았던 메소드들은 그 뒤에 복사해준다.
                System.arraycopy(subClassMethods, 0, allMethodsthisMethods.length,
                                 subClassMethods.length);
            } else {
//처음 찾은 메소드라면
                allMethods = thisMethods;
            }
//현재 클래스(http서블릿클래스의 파생 클래스)의 상위 클래스에 선언된 메서드도
//찾으러 가자
            clazz = clazz.getSuperclass();
        }
//찾은 메서드들 있으면 리턴, 못찾았으면 빈 메서드 생성해서 리턴
        return ((allMethods != null) ? allMethods : new Method[0]);
    }
//결국 내가 만든 클래스부터 최상위 클래스(httpServlet)전까지 정의된 모든 메서드들의 정보를 찾아냈다.
//이 의미는 httpServlet에 정의된 메서드중 무엇을 내가 재정의 했는지를 알 수 있게 해준다.


'프로그래밍 > JSP' 카테고리의 다른 글

jsp에서 빈의 사용3  (0) 2014.01.01
jsp에서 빈의 사용2  (0) 2014.01.01
빈을 이용한 컴포넌트 방식의 설계1  (0) 2014.01.01
jsp 스크립트  (0) 2014.01.01
part2(2013/11/27)  (0) 2014.01.01
by givingsheart 2014. 1. 1. 15:08
| 1 |