본문 바로가기

Java For All/eClipse

Eclipse, WTP, Derby로 웹 애플리케이션 구현하기

2005 년 9 월 01 일

동적인 웹 애플리케이션은 Web Tools Platform(WTP) for Eclipse, Derby, Jakarta-Tomcat을 사용하면 쉽게 구현할 수 있다. 필요한 오픈 소스 컴포넌트를 설치 및 설정하는 방법을 배우고 JSP와 서블릿을 사용하는 완벽한 웹 애플리케이션을 구현하여 Derby 데이터베이스에서 정보를 저장 및 가져올 수 있다.

머리말

Eclipse는 자바를 사용하여 웹 애플리케이션을 구현하는데 이상적인 플랫폼이다. 동적 웹 애플리케이션을 구현하는 3-티어 디자인은 Apache Jakarta Tomcat 같은 서블릿 컨테이너에서 실행되는 JSP와 서블릿과 함께 사용하기에 알맞다. 영속적인 데이터 레이어는 Derby 데이터베이스가 능히 제공할 수 있다. Eclipse Web Tools Platform(WTP) 프로젝트 툴 세트는 Derby Eclipse 플러그인과 함께 J2EE와 웹 애플리케이션을 구현하기에 알맞으며 빠르고 간단한 웹 개발이 가능하다.

이 글에서는 WTP, Derby 데이터베이스 플러그인의 기능과 JSP, JavaServer Pages Standard Tag Library(JSTL), 서블릿을 사용하는 샘플 애플리케이션을 설명한다. 샘플 애플리케이션은 가상 항공 예약 시스템으로 한다.

이 글을 제대로 이해하기 위해서는 JSP, JSTL, 서블릿 기술의 기초와 간단한 SQL, 그리고 Eclipse에 대해 알아두는 것이 좋다. 이 글에서 WTP의 몇몇 기능을 설명하지만 WTP 튜토리얼은 아니라는 점을 명심하기 바란다. 이 주제에 관련해서는 아래 참고자료 섹션을 참고하라. WTP의 배경에 대해 이미 알고 있고 필요한 소프트웨어를 다운로드 하고 싶다면 소프트웨어 요구사항 섹션을 건너뛰어도 좋다. 그렇지 않다면 다음 섹션에서 WTP가 무엇이고 Eclipse 내에서 어떻게 이들 컴포넌트가 사용되어 샘플 애플리케이션을 만드는지를 배우기 바란다.

IBM Cloudscape는 Apache Derby 오픈 소스 데이터베이스의 상용 버전이다. 이 글에서 명칭이 번갈아 가며 사용된다.




위로


Eclipse WTP Project

Eclipse Web Tools Platform(WTP) 프로젝트에서는 Eclipse 사용자가 J2EE 웹 애플리케이션을 개발할 수 있다. 멀티 에디터, 그래픽 에디터, NATURE, 빌더, 웹 서비스 위자드, 데이터베이스 액세스 및 쿼리 툴, 기타 컴포넌트들이 포함되어 있다. 이 프로젝트는 여러 가지 툴을 제공한다. 이들 툴 중 일부만이 백엔드 데이터베이스로서 Derby를 사용하는 웹 애플리케이션 구현과 관련되어 있다.

www.eclipse.org/webtools에 따르면, WTP란 "소프트웨어 공급자가 웹 실행 애플리케이션을 만들어내기 위한 특화 및 차별화 된 오퍼링을 만들 수 있는 일반적이고 확장 가능한 표준 기반의 툴 플랫폼과 유용한 툴을 구현하는 것이다." 이 글에서는 이 플랫폼을 위한 새로운 툴을 구현하는 것을 설명하는 대신, 오픈 플랫폼으로서 오픈 소스 컴포넌트들을 사용하여 웹 애플리케이션을 구현하는 방법을 설명하겠다.

Web Standard Tools와 J2EE Standard Tools

WTP는 두 개의 하위 프로젝트로 나뉜다. Web Standard Tools와 J2EE Standard Tools이다. Web Standard Tools(WST) 프로젝트는 멀티 티어 웹 애플리케이션을 목표로 하는 일반 인프라를 제공한다. Eclipse에서 만들어진 리소스들을 퍼블리시하고 이를 서버에서 실행할 수 있도록 서버 뷰를 제공한다. WST에는 자바를 위한 툴이나 웹 프레임웍 기술을 위한 툴이 없다.

J2EE Standard Tools(JST) 프로젝트는 J2EE API, EJB, 서블릿, JSP, JDBC, 웹 서비스의 개발을 간단히 할 수 있는 툴을 제공한다. J2EE Standard Tools Project는 서블릿과 EJB 컴포넌트를 포함하여 Web Standard Tools Project에서 제공하는 서버 툴의 지원을 받는다.

다음 섹션에서는 샘플 애플리케이션을 구현하여 실행하는데 필요한 모든 소프트웨어 컴포넌트들을 설명하겠다.




위로


웹 애플리케이션의 컴포넌트

샘플 애플리케이션은 다음의 소프트웨어 컴포넌트와 기술을 사용한다.

  • Eclipse
    • IDE를 사용하여 샘플 애플리케이션을 작성 및 실행한다. 자바 애플리케이션을 구현하는 토대가 된다.
    • Eclipse에 포함된 Java Development Tools(JDT)을 사용하여 애플리케이션의 일부인 자바 클래스를 컴파일 한다.
  • WTP
    • JSP 파일을 생성하는 에디터이다. 이 에디터에는 JSP 구문에 대한 컨텐트 지원이 포함되어 있다.
    • 서버 뷰를 사용하여 외부 Jakarta Tomcat 서블릿 엔진을 시작 및 중지한다.
    • J2EE 뷰를 사용하여 동적 웹 애플리케이션을 구현한다. 이 애플리케이션은 J2EE 웹 애플리케이션을 정렬 및 설정하고, 모든 J2EE 웹 애플리케이션에 공통으로 적용되는 표준 구조와 전개 디스크립터를 설정한다.
    • Database Explorer 뷰를 통해 Derby 데이터베이스로 연결한다.
  • Derby 플러그인
    • Derby NATURE를 동적 웹 프로젝트에 추가하여 프로젝트에 JAR 파일을 포함시킨다.
    • 애플리케이션을 개발하는 동안 Derby 네트워크 서버를 시작 및 중지시킨다.
    • ij SQL 쿼리 툴을 사용하여 SQL 쿼리를 테스트 및 실행한다.
    • derby.system.home 속성이 데이터베이스를 가리키도록 설정한다.
  • JavaServer Pages Standard Tag Library(JSTL)
    • 이 태그 라이브러리로 인해 JSP 기반 애플리케이션이 표준 태그 라이브러리를 사용하여 일반적인 태스크를 수행할 수 있다. 샘플 애플리케이션은 이 태그들을 사용하여 반복과 데이터베이스 액세스 같은 태스크를 수행한다. Expression Language(EL) 역시 JSP에서 사용된다.
  • Apache Jakarta Tomcat 서블릿 엔진
    • JSP와 서블릿으로 구성된 웹 애플리케이션을 실행한다.
    • EL을 비롯하여 Servlet 2.4와 JSP 2.0 API를 지원한다.
    • 웹 애플리케이션의 전개 디스크립터에서 데이터 소스로서 Derby 데이터베이스를 정의하도록 지원한다.




위로


소프트웨어 요구사항

이 섹션에서 소개되는 소프트웨어는 무료로 다운로드 할 수 있으며 애플리케이션을 실행하고 샘플 웹 애플리케이션을 구현하기 전에 설치되어야 한다.

다음은 자바 개발 키트이다.

  • IBM SDK version 1.4.2 및 이후 버전
  • Sun JDK version 1.4.2 및 이후 버전

Eclipse and WTP. Eclipse SDK, 모든 WTP 사전 조건들, WTP가 포함된 ZIP 파일을 다운로드 하라. Windows의 경우 이 파일은 wtp-all-in-one-0.7-win32.zip 이다. 리눅스의 경우는 wtp-all-in-one-0.7-linux-gtk.tar.gz이다. eclipse.org에서 이 파일들 중 하나를 다운로드 하라. (참고자료)

Eclipse를 이미 설치했거나 WTP용 사전조건 일부를 이미 설치했다면 wtp-all-in-one zip 파일에 포함된 플러그인 버전들은 아래와 같다. 비교해 보기 바란다. 또한, 다운로드 페이지에는 0.7 WTP에 대한 사전 조건들을 간추려 놓았다. 여러분의 컴포넌트가 어떤 버전인지를 확인하라. 버전들을 다운로드 할 수 있다면 WTP 사이트에서 추천하는 버전을 다운로드 하기 바란다.

  • Eclipse 3.1, for Windows: eclipse-SDK-3.1-win32.zip
  • EMF SDK: emf-sdo-xsd-SDK-2.1.0.zip
  • GEF SDK: GEF-SDK-3.1.zip
  • Java EMF Model Runtime: JEM-SDK-1.1.zip
  • Web Tools Platform: wtp-0.7.zip

Derby database Eclipse 플러그인 (apache.org as zip 파일 -- 참고자료) Apache Derby 데이터베이스는 최근 데이터베이스 엔진 버전 10.1을 릴리스 했다. Eclipse 3.1에서 실행하려면 플러그인 버전은 다음과 같다.

  • Derby Core plug-in, Version 10.1.1
  • Derby UI plug-in, Version 1.1.0

Apache Jakarta Tomcat Version 5.0.28을 다운로드 하라. (참고자료)

JavaServer Pages Standard Tag Library(JSTL) Apache Jakarta Project에서 Standard 1.1 Taglib인 jakarta-taglibs-standard-1.1.2.zip을 다운로드 하라. (참고자료)

샘플 애플리케이션 소스 코드와 WAR 파일:

  • WAR 파일은 Web Application Archive이고 표준 패키징 단위이며 J2EE 웹 애플리케이션을 전개한다. 모든 J2EE 순응 서블릿 컨테이너들은 WAR 파일을 허용하고 이들을 전개한다. LowFareAir.war 파일을 파일 시스템에 다운로드 한다. (다운로드)
  • LowFareDataSQL.zip 파일을 다운로드 한다. airlinesDB 데이터베이스에 액세스하는 Derby 데이터베이스와 샘플 SQL 파일이 포함되어 있다. (다운로드)




위로


소프트웨어 설정

모든 필요한 컴포넌트들을 다운로드 했다면 이들을 설정하여 애플리케이션을 구현한다.

JDK 설치

JDK Version 1.4.2 또는 이후 버전이 없다면 설치하라. JDK가 필요하다.

Eclipse와 WTP 설치

wtp-all-in-one-0.7-win32.zip을 Eclipse가 있는 곳에서 압축을 푼다. Eclipse가 이미 설치되어 있고 위에 나열된 개별 컴포넌트를 다운로드 했다면 이들을 Eclipse 홈 디렉토리에 압축을 푼다. 이들은 모두 플러그인이고 Eclipse의 플러그인 디렉토리에 설치될 것이기 때문이다.

Jakarta Tomcat 설치 및 설정

Jakarta Tomcat을 Eclipse 설치 디렉토리 외 다른 디렉토리에 설치한다.

이제 Eclipse를 설정하여 WTP를 사용하는 Eclipse 내에서 서버로서 Tomcat을 실행하도록 한다.

  • http://www.eclipse.org/webtools/로 가서 WTP Community 섹션 밑에 있는 튜토리얼 링크를 선택한다.
  • 튜토리얼 페이지에서 "Building a School Schedule Web Application" 튜토리얼을 선택한다.
  • "Installing the Tomcat Runtime in Eclipse" 섹션을 참고한다. 샘플 웹 애플리케이션을 위해 전체 튜토리얼을 공부할 필요는 없다.

Derby 플러그인 설치

두 파일(Derby Core와 UI 플러그인 zip 파일) 모두 압축을 풀어 플러그인 디렉토리에 둔다. Derby 플러그인에는 튜토리얼과 기능 사용 예제도 함께 제공된다. 도움말을 보려면 Help > Help Contents > Derby Plug-ins User Guide를 선택한다.




위로


애플리케이션 디자인

LowFareAir 웹 애플리케이션은 표준 3-티어 디자인 모델을 따른다. 이 디자인 모델은 표현 레이어, 비즈니스 로직과 제어 레이어, 데이터 또는 영속성 레이어로 구성된다. JSTL 태그 라이브러리를 포함하여 JSP는 UI 또는 표현 레이어를 제공한다. 서블릿과 자바 클래스들은 비즈니스 로직을 제공하고 애플리케이션의 흐름을 제어한다. Derby 데이터베이스와 JavaBeans는 데이터 레이어를 제공한다. 아래 다이어그램을 보자.


그림 1. 샘플 애플리케이션 디자인
Application Design 

Presentation Layer에서 Data Layer로 접근하기

JSP가 제공하는 표현 레이어는 일반적으로 데이터 레이어와 직접 인터랙팅 하지 않으므로 데이터베이스 쿼리도 만들지 않는다. 이 애플리케이션 디자인은 같은 패러다임을 따르고 있다. 하지만 첫 번째 JSP는 예외이다. 빠른 프로토타이핑을 위해 뷰 레이어에서 데이터베이스 액세스를 결합하는 것이 허용되고, 데이터와 뷰를 엄격하게 분리한다. 첫 번째 JSP인 Welcome.jsp는 표현 레이어와 데이터 레이어 모두를 차지한다. JSTL SQL 라이브러리를 사용하여 페이지에서 SQL 쿼리를 만들어 낸다.

다른 JSP들은 표현 레이어 전용이다. 모든 데이터 핸들링 책임을 서블릿으로 보낸다. 서블릿이 Derby 데이터베이스와 인터랙팅한다. 앞으로의 웹 애플리케이션의 프로토타이핑에 이 방법을 사용할 경우 JSTL SQL 라이브러리 예제가 있지만 제품 환경에서는 권할만한 사항이 아니다.




위로


LowFare Air 샘플 애플리케이션

이 샘플 애플리케이션은 새로운 사용자들에게 등록 기회가 주어지거나 기존 사용자들이 이 애플리케이션에 로그온 할 수 있다. 사용자가 로그인 하면 많은 항공사들이 제공된다. 단 직항만 제공되기 때문에 선택된 항공기는 출발지와 도착지에 직항이 가능한지를 체크하게 된다. 가능하다면 사용자는 그 항공편을 예약할 수 있다. 마지막으로 사용자는 LowFare Air에 예약된 모든 항공편 기록을 볼 수 있다.

샘플 애플리케이션의 흐름은 다음과 같다.

  • 사용자 등록 및 확인
    • 이 부분에 사용되는 JSP는 Welcome.jsp, Login.jsp, Register.jsp이다.
    • LoginServlet는 컨트롤러로서 작동한다. 사용자 이름이 Derby 데이터베이스에 있는 APP.USERS 테이블에서 검사되거나 테이블에 삽입된다.
    • 등록이 성공하면 영속성 쿠키가 설정되고, 로그인이 성공하면 클라이언트의 사용자 ID가 세션에 추가된다.
  • 플라이트 검색과 선택
    • Welcome.jsp는 항공편을 선택하는데 사용되고 GetFlights.jsp는 항공편을 검색하는데 사용된다.
    • CheckFlightsServlet은 컨트롤러로서 작동한다. 두 개의 선택 도시들간 플라이트가 있다면 플라이트 정보가 GetFlights.jsp로 전달된다. 그렇지 않으면 사용자는 Welcome.jsp로 리턴되어 또 다른 항공편을 선택하게 된다.
    • 항공편이 있으면 DerbyDatabase 클래스는 데이터베이스에서 검색된 항공편 정보를 FlightsBean 이라고 하는 JavaBean에 둔다.
  • 항공편 히스토리를 업데이트 하여 사용자의 항공편 예약하기
    • BookFlights.jsp와 GoodBye.jsp가 사용된다. BookFlights.jsp는 사용자에게 그들이 예약하기 원하는 항공편을 최종 확인할 것을 요청한다. GoodBye.jsp는 Derby Airlines로 사용자가 예약한 모든 항공편을 디스플레이 한다.
    • UpdateHistoryServlet은 사용자 이름과 막 예약한 항공편으로 APP.FlightHistory 테이블을 업데이트 한다. 이 요청은 GoodBye.jsp로 전달된다.
  • 사용자 로그아웃
    • 이 애플리케이션의 마지막 단계는 로그아웃 이거나 또 다른 항공편을 예약하는 것이다. 사용되는 JSP는 LoggedOut.jsp이거나 사용자가 또 다른 항공편을 예약하기 원할 경우에는 Welcome.jsp가 사용된다.
    • 사용자가 로그아웃을 선택하면 사용자 ID는 Session 객체에서 제거된다. 따라서 다음 번에 사용자가 이 사이트에 오면 영속성 쿠키는 남아있지만 사용자 ID는 더 이상 이 Session 객체에 존재하지 않는다. 사용자는 다시 로그인 해야 한다.

아래 그림은 위 단계를 그림으로 묘사한 것이다.


그림 2. 샘플 애플리케이션의 흐름
Application Flow 

Application Flow 

Application Flow 

Application Flow 


위로


WAR에서 웹 프로젝트 만들기

WTP와 Derby 플러그인에 포함된 다양한 툴의 사용법을 이해하려면 애플리케이션을 WAR 파일로서 반입한다. 이는 웹 애플리케이션의 표준 패키징 단위이고 JAR 파일 포맷으로 되어있다.

JSP와 서블릿을 사용하는 웹 애플리케이션을 구현하는 첫 번째 단계는 동적 웹 애플리케이션을 만드는 것이다. WTP 툴 세트를 사용하여 만들 수 있고 이 툴은 J2EE 웹 애플리케이션용 디렉토리 구조를 자동으로 만든다. WAR 파일을 Project Explorer 뷰의 Dynamic Web Project 폴더로 반입하여 새로운 웹 프로젝트를 만든다.

Eclipse가 실행되지 않는다면 Eclipse를 시작하고 WAR 파일을 반입하여 새로운 Dynamic Web Project를 만든다. 과정은 다음과 같다.

  1. J2EE Perspective를 연다.
  2. Project Explorer 뷰에서, Dynamic Web Projects 폴더를 오른쪽 클릭한다.
  3. Import를 선택하고 Import 윈도우에서 WAR file을 선택한 후 Next를 누른다.
  4. WAR Import 윈도우에서 앞서 다운로드 했던 LowFareAir 파일을 찾는다. (소프트웨어 요구사항 참조.) 이 프로젝트 이름을 LowFareAir로 하고 Target 서버가 Apache Tomcat V5.0인지를 확인하라. ( 소프트웨어 설정 참조.) Finish를 누른다.

그림 3은 마지막 단계 모습이다.


그림 3. WAR 파일을 반입하여 Dynamic Web Project 생성하기
Dynamic Web Project 

WAR 파일에 포함되지 않은 세 개의 JAR 파일들도 반입해야 한다. 앞서 다운로드 했던 자카르타 taglibs에서 jstl.jar와 standard.jar를, Derby 코어 플러그인에서 derbyclient.jar 파일을 반입한다. 일반적으로 완전한 WAR 파일에는 세 개의 JAR 파일들이 있지만 여러분이 알아야 할 내용이기에 설명하는 것이다.

자카르타 패키지에서 JAR 파일을 가져오려면 jakarta-taglibs-standard-1.1.2.zip의 압축을 푼다. jstl.jar와 standard.jar 파일이 새롭게 만들어진 jakarta-taglibs-standard-1.1.2/lib 디렉토리에 생긴다. 반입 방법은 다음과 같다.

  1. Dynamic Web Projects 폴더를 연다. 반입한 LowFareAir 프로젝트가 나타난다. 이 폴더를 확장한 다음 WebContent 폴더를 확장한다.
  2. WebContent/WEB-INF/lib 폴더를 오른쪽 클릭하고 Import를 선택한다. Import 윈도우에서, File System을 선택하고 Next를 누른다.
  3. jakarta-taglibs-standard-1.1.2/lib 하위 디렉토리를 검색한다. 이 곳은 taglibs의 압축을 푼 곳이다. jstl.jar와 standard.jar를 선택한다. LowFareAir/WebContent/WEB-INF/lib 디렉토리로 맞게 반입했는지 확인한다. Finish를 누른다.

이제, derbyclient.jar 파일을 웹 애플리케이션에서 사용할 수 있는 라이브러리에 추가한다. 웹 애플리케이션은 derbyclient.jar에서 JDBC 드라이버를 사용하여 데이터베이스로 연결한다.

derbyclient.jar를 반입하려면,

  1. WebContent/WEB-INF/lib 폴더를 오른쪽 클릭하고 Import를 선택한다. Import 윈도우에서, File System을 선택하고 Next를 누른다.
  2. Eclipse 홈 디렉토리 밑에 있는 플러그인 디렉토리를 검색하고 org.apache.derby.core_10.1.1을 확인한다. LowFareAir/WebContent/WEB-INF/lib 디렉토리로 반입했는지 확인한다. Finish를 누른다.

이것으로 웹 컴포넌트 반입이 끝났다. 애플리케이션에 필요한 자바 소스 파일들과 모든 라이브러리들도 반입하였다. 이제는 Derby 데이터베이스인 airlinesDB를 반입하고 샘플 데이터를 완성시켜 보자.




위로


데이터 레이어 설정하기

애플리케이션용 데이터베이스에 액세스 하는 데이터 레이어와 툴을 설정하려면,

  1. Apache Derby Nature를 LowFareAir 프로젝트에 추가한다.
  2. LowFareAirData.zip 파일을 프로젝트에 반입한다. 이 zip 파일에는 airlinesDB Derby 데이터베이스가 포함되어 있다. 여기에는 애플리케이션용 모든 데이터와 샘플 SQL 스크립트가 포함되어 있다.
  3. 웹 애플리케이션 전개 디스크립터인 web.xml을 설정하여 airlinesDB 데이터베이스를 가리키는 데이터 소스를 포함시킨다.
  4. Derby 속성 derby.system.home을 설정하여 airlinesDB 데이터베이스의 전체 경로를 가리키도록 한다. 이 속성을 설정함으로서 JDBC 연결 URL에 있는 airlinesDB 데이터베이스에 대한 모든 레퍼런스들이 전체 파일 시스템 경로 대신 'airlinesDB' 만 참조할 수 있다.

Apache Derby nature 추가하기

이 웹 애플리케이션은 Derby 데이터베이스를 사용하여 가상의 LowFareAir 항공사의 항공편 정보를 저장 및 쿼리한다. Eclipse에 있는 Derby 데이터베이스에 접근하여 이를 사용할 수 있는 쉬운 방법은 Derby 플러그인을 통해서이다.

Derby 플러그인을 사용하면 Derby nature를 어떤 Eclipse 프로젝트로도 추가할 수 있다. Dynamic Web Project를 포함하여 프로젝트에 nature를 추가한다는 것은 프로젝트가 특정 기능과 작동을 상속 받는다는 것을 의미한다. Derby nature를 추가한다는 것은 Derby 데이터베이스 JAR 파일들과 Derby와 함께 묶인 명령행 툴들을 Eclipse 환경에 추가한다는 것을 의미한다.

Project Explorer 뷰는 여러분이 만들었던 LowFareAir 프로젝트를 보여준다.

Derby nature를 LowFareAir 프로젝트에 추가하려면 이것을 오른쪽 클릭하고 메뉴 아이템 Apache Derby > Add Apache Derby nature을 선택한다.

LowFareAirData.zip 반입하기

소스 코드에 포함된 것은 airlinesDB이다. 이는 웹 애플리케이션에 사용되는 샘플 데이터베이스이다. 이 데이터베이스는 몇몇 샘플 SQL과 함께 LowFareAir 프로젝트에 반입되어야 한다.

  1. Dynamic Web Projects 폴더를 확장한다. LowFareAir 폴더를 오른쪽 클릭하고 Import를 선택한다. Import 윈도우에서, Archive file 파일을 선택한 다음 Next를 누른다.
  2. LowFareAirData.zip을 보고 왼쪽 프레임에 / directory를 반드시 체크한다. 여기에는 data와 sql 폴더가 포함되어 있다. Into 폴더 이름에 LowFareAir를 선택하고 Finish를 누른다.
  3. 반입이 성공할 경우 LowFareAir 폴더에는 두 개의 새로운 하위 폴더가 생긴다. data와 sql 이다. data 폴더에는 airlinesDB 디렉토리(데이터베이스)가 포함될 것이다.
  4. sql 디렉토리에는 세 개의 SQL 파일들(airlinesDB.sql, flights.sql, flighthistory_users.sql)이 포함된다.

웹 애플리케이션에 필요한 모든 파일들이 반입되었다. LowFareAir 프로젝트는 다음과 같은 구조가 된다. (그림 4)


그림 4. LowFareAir 프로젝트의 Project Explorer 뷰
Project Explorer view of LowFareAir project 

Derby 데이터 소스로 web.xml 설정하기

web.xml 파일에는 Derby airlinesDB 데이터베이스가 데이터 소스로서 사용할 데이터 소스 엔트리가 포함되어 있다. 이것은 웹 애플리케이션이 Derby 데이터베이스로 연결되는데 필요한 것은 아니다. 하지만 이 애플리케이션은 첫 번째 JSP 페이지에 데이터 소스를 사용한다. 다른 JSP는 데이터 소스를 사용하지 않고 서블릿이 표준 자바 클래스를 사용한다. 표준 자바 클래스가 JDBC를 사용하여 데이터베이스로 연결한다.

파일 시스템에 airlinesDB의 위치를 정하려면 LowFareAir 프로젝트의 데이터 디렉토리 밑에 airlinesDB 폴더를 오른쪽 클릭하여 Properties를 선택한다. Properties 윈도우는 airlinesDB 디렉토리에 대한 전체 파일 시스템 경로를 갖고 있는 Location 필드를 보여준다. 다음 스트링을 복사해 두어 다음 단계에서도 사용하라. C:\eclipse\workspace\LowFareAir\data\airlinesDB

(WebContent/WEB-INF 디렉토리 밑에 있는) web.xml을 열어 이 섹션을 검사하고 Source 모드에서 본다. (param-value 섹션의 엔트리는 읽기 쉽도록 라인을 분리했다. 하지만 URL은 한 라인에 있다.)


Listing 1. Web.xml context-param 섹션
<context-param>
 <param-name>javax.servlet.jsp.jstl.sql.dataSource</param-name>
   <param-value>
   jdbc:derby://localhost:1527/C:\eclipse\workspace\LowFareAir\data\ /
   airlinesDB;user=a;password=b;,
   org.apache.derby.jdbc.ClientDriver
 </param-value>
</context-param>

<param-value> 섹션에 있는 값을 자신의 환경에 해당하는 데이터베이스 URL로 바꾼다. 복사해 놓은 airlinesDB 데이터베이스에 전체 경로를 사용한다. 이것을 정확히 편집하지 않는다면 이 애플리케이션의 첫 번째 페이지(Welcome.jsp)는 실패한다. 또한 Welcome.jsp를 실행하기 전에 네트워크 서버를 시작해야 한다. 위 URL은 Derby Client 드라이버를 사용하여 Network Server로 접근을 시도하기 때문이다.

프로젝트에 맞게 derby.system.home 설정하기

Eclipse에서 Derby 데이터베이스 환경을 설정하는 그 다음 단계는 derby.system.home 이라고 하는 Derby 시스템 속성을 편집하여 airlinesDB 데이터베이스의 위치를 가리키도록 한다. 데이터베이스에 대한 전체 파일 시스템 경로를 지정하지 않고도 Derby 플러그인을 사용하여 airlinesDB에 연결할 수 있다. airlinesDB라는 이름만이 데이터베이스 연결 URL에 리스팅되어야 한다.

앞서 복사했던 airlinesDB 디렉토리에 대한 경로를 약간 변경하여 derby.system.home을 설정한다.

  1. LowFareAir 프로젝트를 오른쪽 클릭하고 Properties를 선택한다.
  2. Properties 윈도우의 왼편에서 (현재는 PropertyDialog.propertyMessage 이다. 마치 버그처럼 보인다.) Apache Derby를 선택한다.
  3. 여러분이 변경할 수 있는 Apache Derby 속성들은 오른편에 있다. derby.system.home 이라고 하는 Derby System Property는 현재 디폴트 값(.)으로 설정된다. 이것을 변경하여 airlinesDB 디렉토리가 있는 디렉토리의 전체 경로를 가리키도록 한다. 주: port 속성에서 네트워크 서버가 리스닝하는 포트를 변경할 수 있다. 
    derby.system.home 속성 값을 데이터 디렉토리의 전체 경로로 편집한다. 위에서 복사한 스트링에 붙이고 뒤따르는 \airlinesDB를 제거한다. 앞서 예제 경로가 주어졌다면 derby.system.home 속성은C:\eclipse\workspace\LowFareAir\data가 된다. 주: 데이터베이스 디렉토리 이름을 입력하지 말라. 이것은 데이터베이스 디렉토리가 상주하는 디렉토리가 되어야 한다. 이 경우는 airlinesDB 디렉토리가 아닌 데이터이다.
  4. OK를 클릭하고 프로젝트 설정을 저장한다.

다음에는 Derby Network Server를 시작하여 airlinesDB 데이터베이스로 연결한 다음 Derby 플러그인에서 제공하는 ij 툴을 사용하여 SQL을 만들 것이다.

Derby 네트워크 서버를 시작하고 ij 실행하기

airlinesDB에 있는 테이블에 쿼리를 실행할 것이기 때문에 여러분이 갖고 있는 테이블과 이들이 정의되는 방법을 알아두는 것이 좋다. 오래된 데이터베이스를 삭제하고 새로운 데이터베이스에 모든 테이블을 다시 생성하고 싶지 않다면 airlinesDB.sql을 다시 실행하지 말라.


Listing 2. airlinesDB 데이터베이스용 테이블 문 만들기
CREATE TABLE APP.CITIES
(
 CITY_ID          INTEGER NOT NULL constraint cities_pk primary key,
 CITY_NAME        VARCHAR(24) NOT NULL,
 COUNTRY          VARCHAR(26) NOT NULL,
 AIRPORT          VARCHAR(26),
 LANGUAGE         VARCHAR(16),
 COUNTRY_ISO_CODE CHAR(2) 
);

CREATE TABLE APP.FLIGHTS
(
 FLIGHT_ID      CHAR(6) NOT NULL,
 SEGMENT_NUMBER INTEGER NOT NULL,
 ORIG_AIRPORT   CHAR(3),
 DEPART_TIME    TIME,
 DEST_AIRPORT   CHAR(3),
 ARRIVE_TIME    TIME,
 MEAL           CHAR(1) CONSTRAINT MEAL_CONSTRAINT 
 CHECK (meal IN ('B', 'L', 'D', 'S')),
 FLYING_TIME    DOUBLE PRECISION,
 MILES          INTEGER,
 AIRCRAFT       VARCHAR(6),
 CONSTRAINT FLIGHTS_PK Primary Key (FLIGHT_ID, SEGMENT_NUMBER)
);

CREATE TABLE APP.FLIGHTAVAILABILITY
(
 FLIGHT_ID              CHAR(6) NOT NULL ,
 SEGMENT_NUMBER         INTEGER NOT NULL ,
 FLIGHT_DATE            DATE NOT NULL ,
 ECONOMY_SEATS_TAKEN    INTEGER DEFAULT 0,
 BUSINESS_SEATS_TAKEN   INTEGER DEFAULT 0,
 FIRSTCLASS_SEATS_TAKEN INTEGER DEFAULT 0,
 CONSTRAINT FLIGHTAVAIL_PK Primary Key 
 (FLIGHT_ID, SEGMENT_NUMBER, FLIGHT_DATE),
 CONSTRAINT FLIGHTS_FK2 Foreign Key (FLIGHT_ID, SEGMENT_NUMBER)
 REFERENCES FLIGHTS (FLIGHT_ID, SEGMENT_NUMBER)
);

CREATE TABLE APP.FLIGHTHISTORY
(
 ID             INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
 USERNAME       VARCHAR(26) NOT NULL,
 FLIGHT_ID      CHAR(6) NOT NULL,
 ORIG_AIRPORT   CHAR(3) NOT NULL,
 DEST_AIRPORT   CHAR(3) NOT NULL,
 BEGIN_DATE     CHAR(12),
 CLASS          CHAR(12)
);

CREATE TABLE APP.USERS 
(
 ID             INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
 USERNAME       VARCHAR(40) NOT NULL,
 PASSWORD       VARCHAR(20)
);

LowFareAir 프로젝트를 오른쪽 클릭하고 Apache Derby > Start Derby Network Server를 선택하여 Derby 네트워크 서버를 시작한다. 이 콘솔 뷰는 서버가 Derby properties Network Server 설정에서 지정된 포트상에서 연결을 수락할 준비가 되었다는 것을 나타낸다. sql 폴더를 열고 flights.sql 파일을 오른쪽 클릭한다. Apache Derby > Run SQL Script using 'ij'를 선택한다.

이 콘솔 윈도우는 flights.sql 파일에 저장된 세 개의 SQL 문의 결과를 보여줄 것이다. 연결이 이루어지지 않았다면 네트워크 서버가 시작되었는지를 확인하고 derby.system.home이 LowFareAir 폴더 밑에 있는 데이터 디렉토리에 대한 전체 경로로 설정되었는지를 확인한다.




위로


WTP 데이터 툴 -- 대안

WTP는 풍부한 데이터베이스 툴 세트를 갖고 있다. 사용자들은 Derby, DB2, Informix, MySql, Oracle, SQL Server, Sybase 데이터베이스에 연결하여 SQL을 검색 및 실행할 수 있다. 이 섹션에서는 Derby Network Client 드라이버를 사용하여 Derby Network Server로 연결하고 Derby 플러그인의 대안으로서 이러한 툴을 사용하는 방법을 설명할 것이다.

J2EE perspective에서 Window > Show View > Other를 선택한다. Show View 윈도우에서 Data > Database Explorer를 선택하고 OK를 클릭한다. Database Explorer 뷰는 워크스페이스의 오른쪽 하단에 나타날 것이다. 이 뷰 에서 오른쪽 클릭하여 New Connection을 선택한다.

새롭게 나타나는 위자드는 New Connection 위자드이다. Use default naming convention 체크박스에서 체크를 해제하고 커넥션 이름을 Derby 10.1로 한다. Select a database manager섹션 밑에서 Derby 아이템을 확장한다. 10.0 버전의 데이터베이스 시스템이 나열된다.

WTP 0.7만이 Derby 10.0을 지원하지만 최신 Derby 릴리스 버전은 10.1 이고, Database Explorer와 함께 여기에서 여러분이 사용할 Derby JAR 파일은 10.1 버전이다. Derby 10.1 버전에서는 네트워크 서버로 연결할 때 새로운 오픈 소스 클라이언트 드라이버인 derbyclient.jar를 권장한다.

아래 이미지는 나의 환경에서 각 필드의 값을 나타낸 것이다. 밑에 테이블은 설정 샘플이다.


그림 5. WTP Database Explorer의 New Connection 위자드
Creating a new connection 
표 1. Derby Client Driver를 사용하는 Derby 10.1 연결 값
매개변수
연결 이름 Derby 10.1
데이터베이스 매니저 Derby 10.0
JDBC 드라이버 기타
데이터베이스 C:\eclipse\workspace\LowFareAir\data\airlinesDB
JDBC 드라이버 클래스 org.apache.derby.jdbc.ClientDriver
클래스 위치 C:\eclipse\plugins\org.apache.derby.core_10.1.1\derbyclient.jar
연결 URL jdbc:derby://localhost:1527/C:\eclipse\workspace\LowFareAir\data\airlinesDB
사용자 ID slc (유효 값)
패스워드 slc (유효 값)

Derby 데이터베이스에 인증을 설정하는 것이 가능하지만 airlinesDB 데이터베이스에는 설정되지 않았다. 사용자 ID와 패스워드에 (유효) 값을 사용하고 Test Connection 버튼을 클릭한다. 네트워크 서버가 1527 포트에서 실행된다면 테스트는 성공한다. 그렇지 않다면 네트워크 서버가 연결 URL에서 지정된 포트에서 실행되는지를 확인하고 모든 값이 환경에 맞는지를 확인한다.

airlinesDB 데이터베이스로 연결하는데 네트워크 서버가 사용되기 때문에 다중 JVM이 여기에 액세스 할 수 있다. ij, Database Explorer, 클라이언트 애플리케이션이 데이터베이스에 잇는 테이블에 연결 및 쿼리할 수 있다는 의미이다.

테스트 연결이 성공하면 Next 버튼을 누른다.

Specify Filter 윈도우에서, Disable filter 체크박스를 해제하고 Selection을 선택하고 APP 스키마를 체크한다. Finish를 누른다.


그림 6. Derby 10.1 연결용 Filter 지정하기
Specifying the Filter 

Database Explorer 뷰가 airlinesDB 데이터베이스로의 연결을 보여준다. 트리를 확장하고 APP 스키마용 Tables 폴더 밑에 있는 FLIGHTS 테이블을 검색한다. FLIGHTS 테이블을 오른쪽 클릭하고 Data > Sample Contents를 선택한다.


그림 7. Database Explorer의 샘플 컨텐츠 
Sampling the contents of the FLIGHTS table 

Data Output 뷰에 FLIGHTS 테이블에 열들이 나타난다.


그림 8. Data Output 뷰
Data Output view of the FLIGHTS table 

Database Explorer 뷰의 또 다른 특징은 테이블에서 열을 삽입, 삭제, 업데이트 할 수 있다는 것이다. Table Editor 는 테이블에서 데이터를 수정할 수 있는 기능을 제공한다. FLIGHTS 테이블에 또 다른 열을 추가하려면 Database Explorer 뷰에서 오른쪽 클릭하여 Data > Open을 선택한다. 새로운 열을 입력하면서 각 칼럼에 값을 넣는다. FLIGHTS 탭 상에서 FLIGHTS 단어 앞에 별표를 단다. 이걸 보면서 에디터가 업데이트 되었음을 알 수 있다.


그림 9. Table Editor
The FLIGHTS table in the Table Editor 

테이블에 열을 삽입하려면 File > Save를 선택하거나 단축키 Ctrl + S를 사용하여 에디터를 저장한다. Data Output 뷰의 Messages 탭에는 데이터가 잘 삽입되었다는 것을 보여주고 있다.


그림 10. FLIGHTS 테이블에 열이 삽입되었다. 
The Data Output view showing a successful insertion into the FLIGHTS table 

Database Explorer 뷰는 테이블을 추출 및 로딩하고, SQL Editor를 열어 SQL을 실행하고, 전체 데이터베이스 스키마나 스키마 하위세트를 만드는데 사용할 수 있는 SQL 스크립트를 만드는데 매우 유용한 DDL 옵션을 생성할 수 있다. 스키마 객체(테이블, 뷰, 인덱스, 스키마)를 오른쪽 클릭하여 여러분이 갖고 있는 이 모든 옵션들을 보고 어떤 옵션들이 특정 객체에 사용될 수 있는지를 가늠할 수 있다.




위로


뷰 레이어와 JSP

이제 애플리케이션에서 JSP를 검토하도록 하자. 그림 2의 애플리케이션 흐름에서 보면 첫 번째 JSP는 Welcome.jsp이다. Project Explorer에서 WebContent 폴더 밑에 있는 Welcome.jsp 파일을 연다. 이 페이지용 코드는 아래 섹션에 있다. 주: 몇몇 코드 리스팅은 백슬래시 문자 "\"가 있다. 이것은 코드 라인이 이어지는 것이지만 읽기 쉽도록 나누었다는 의미이다.


Listing 3. Welcome.jsp에 Core와 SQL tablibs 반입하기 
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>

첫 번째 두 라인에는 JSP 페이지에 사용할 수 있는 taglib 명령어가 있기 때문에 이 코어와 SQL JSTL 태그 라이브러리를 사용할 수 있다.

다음 섹션은 코어 태그 라이브러리를 사용하여 사용자 브라우저에 쿠키가 설정되었는지를 테스트 한다. 아무것도 설정되지 않았다면 JSP 페이지는 Register.jsp로 간다. 적어도 한 개의 쿠키라도 있으면 derbyCookie라는 이름으로 쿠키가 설정되었는지가 확인된다. derbyCookie가 존재하면 Session 객체에 사용자 ID가 포함되었는지를 확인한다. 그렇지 않다면 사용자는 Login.jsp로 가서 애플리케이션에 로그인 한다.

Session 객체에 사용자 ID가 없다면 사용자는 Welcome.jsp 페이지로 가게 된다.


Listing 4. Welcome.jsp에 쿠키 설정 확인 
<HTML>
<HEAD>
<TITLE>Derby Airlines</TITLE>
</HEAD>
<BODY>

<c:choose>
 <c:when test="${empty cookie}">
  <jsp:forward page="Register.jsp" />
   </c:when>
 <c:otherwise>
<!--  if the derbyCookie has been set but the username is not in \
the session object -->
   <c:forEach var="cookieVal" items="${cookie}">
    <c:if test="${cookieVal.key == 'derbyCookie'}">
     <c:if test="${empty sessionScope.username}">
      <jsp:forward page="Login.jsp" />
     </c:if>
    </c:if>
   </c:forEach>
 </c:otherwise>
</c:choose>

아래 코드는 페이지가 게시될 때 nodirectflights 매개변수가 설정되었는지를 확인하는 코드이다. 코드를 더 보면 이 폼에 대한 액션은 CheckFlightsServlet으로 포스팅 하는 것이다. CheckFlightsServlet이 사용자가 선택한 출발지와 도착지에 직항편이 없다면 nodirectflights 매개변수는 true로 설정되고, 사용자는 이 페이지로 리턴된다. 코드는 직항편이 없다는 메시지를 디스플레이 하게 된다.


Listing 5. 직항편이 없음 
<c:if test="${nodirectflights == 'true'}" >
<p>
There were no direct flights between <font color="blue" size="5">
${cityNameFrom}</font> and <font color="blue" size="5">
${cityNameTo}</font>. <br> 
Please select another flight.
</p>
</c:if>

JSTL 코어 out 태그를 사용하여 세션이나 요청 객체에 있는 JSP로 전달된 매개변수들을 디스플레이 할 수 있다. 로그인이 성공하면 사용자 ID는 Session 객체에 놓이게 되고 사용자가 이 페이지에 액세스 할 때 Welcome.jsp 페이지에 디스플레이 된다. 현재 월, 일, 년도를 디스플레이 하는 CalendarServelt을 포함시키는 jsp:include 태그와 드롭다운 박스를 사용하여 출발 날짜를 나타내고 있다는 것을 주목하라.


Listing 6. 로그인이 성공한 후
<H3>
Welcome to Derby Air, <c:out value="${username}" />!</H3>
<p>
Please proceed to select a flight.
</p>
<form action="CheckFlightsServlet" method="post">

<table width="50%">
<tr>
 <td valign="top">
  <b>Departure Date:</b><br>
  <jsp:include page="/CalendarServlet">
  	<jsp:param name="type" value="orig" />
  </jsp:include>
 </td>

이제는 JSTL SQL 라이브러리를 사용하는 섹션이다. sql:query 태그를 사용하기 전에 애플리케이션용 web.xml 파일에 DataSource를 설정했다. 엔트리는 나중에 설명하겠다. CITIES 테이블에 대해 쿼리를 실행하여 APP.CITIES 테이블의 city_name, country, airport 칼럼에 저장된 값을 리턴한다. 쿼리 결과는 cities라고 하는 변수에 놓이게 되는데 이것은 javax.servlet.jsp.jstl.sql.Result 객체이다. Result 객체는 getRows() 이라는 메소드를 갖는다. 이는 여기에 포함된 모든 열들을 리턴한다. 열들은 java.util.SortedMap 객체의 어레이로서 리턴된다.


Listing 7. SQL taglib 사용하기 
<sql:query var="cities">
 SELECT CITY_NAME, COUNTRY, AIRPORT FROM APP.CITIES ORDER BY \
 CITY_NAME, COUNTRY
</sql:query>

cities Result 객체에 있는 열들에 대한 반복은 forEach 태그를 사용한다. 어레이를 통한 반복을 위해, city 라는 변수가 SortedMap 객체를 갖고 있다. Expression Language에서는 데이터베이스에서 열을 나타내는 특정 SortedMap 객체에 있는 칼럼 이름을 참조하여 각 열에 있는 각각의 칼럼 값에 액세스 할 수 있다.


Listing 8. SQL 쿼리 결과 
<td>
 <b>Origin:</b><br>
 <select name="from" size="4">
 <c:forEach var="city" items="${cities.rows}">
 <option value="${city.airport}"> ${city.city_name}, ${city.country}\ 
 </option>
</c:forEach>
 </select>
 <br><br>
 </td>
</tr>

나머지 페이지는 여기에는 보이지 않는다. 위에서 Origin 목적지가 만들어졌던 것과 같은 방식으로 Destination 드롭다운 박스가 만들어지고, 사용자가 Origin과 Destination 간 항공편을 검사할 때 쿼리를 제출할 수 있는 버튼이 제공된다.




위로


컨트롤 흐름 검사와 애플리케이션 실행

LowFare Air를 실행하기 전에 Derby Network Server를 시작해야 한다. LowFareAir 폴더를 오른쪽 클릭하여 Apache Derby > Start Derby Network Server를 선택한다.

Project Explorer 뷰에서 Welcome.jsp 파일을 오른쪽 클릭하고 Run As > Run On Server를 선택한다.


그림 11. Tomcat Server에서 Welcome.jsp 실행하기
Running Welcome.jsp 

Run on Server 위자드가 생기면 다음과 같이 한다.

  1. 서버의 호스트 이름에 localhost를 선택한다. 서버 유형의 경우 Apache 폴더를 확장하여 Tomcat v5.0을 선택한다. Set server as project default 박스를 체크한다. Next 버튼을 누른다.
  2. Add and Remove Projects 윈도우에서, Configured Projects 부분에 LowFareAir 프로젝트가 리스팅 되었는지를 확인한다. 그렇지 않다면 Available Projects 카테고리에 있을 것이다. 이것을 Configured Projects 카테고리로 옮긴다. Finish를 누른다.

이로서 JSP 페이지가 실행될 외부 Tomcat 서버와 브라우저 윈도우가 시작되었다. Windows의 경우, Eclipse에서 내부 브라우저를 시작하는 것이 기본이다. 리눅스에서는 외부 브라우저가 기본이다.

외부 브라우저의 설정하기:

  1. Window > Preferences를 선택한다.
  2. General 트리 아이템과 Web Browser를 선택한다.
  3. Use external Web browser 버튼을 선택한 다음 리스트에서 사용 가능한 브라우저를 선택한다.
  4. OK를 클릭하고 선호도를 설정한다.

다른 브라우저로 웹 페이지를 검사하는 것이 좋다. 몇몇 HTML 엘리먼트를 렌더링 할 때 다르게 작동하기도 하고 쿠키 핸들링에도 다르게 작동한다.

앞서 설명한 것 처럼 Welcome.jsp를 처음 시작하면 Register.jsp 페이지로 리다이렉션 된다. DerbyCookie가 아직 설정되지 않았기 때문에 Welcome.jsp는 Register.jsp로 리다이렉션 하여 사용자 ID와 패스워드를 만들도록 한다. (그림 12)


그림 12. Register.jsp의 새로운 사용자 ID 엔트리
Register.jsp 

사용자 ID와 패스워드를 입력하고 Register New User 버튼을 누르면 LoginServlet 클래스로 값이 전달된다. LowFareAir > Java Resources > JavaSource > com.ibm.sample 폴더와 패키지 구조 밑에 배치된 자바 클래스를 연다.

doPost 메소드가 Register.jsp에서 설정된 ID와 패스워드를 포함하여 인커밍 매개변수들을 파싱한다.


Listing 9. LoginServlet 클래스의 doPost 메소드
protected void doPost(HttpServletRequest request,
 HttpServletResponse response) throws ServletException, IOException
{
 String user = request.getParameter("username");
 String password = request.getParameter("password");
 // Register.jsp set the parameter newuser
 String newUser = request.getParameter("newuser");
 String loggedOut = request.getParameter("loggedOut");

그런 다음 DerbyDatabase 클래스상의 getConnInstance() 메소드를 호출하여 Derby 데이터베이스로 연결한다. getConnInstance 메소드는 java.sql.Connection을 데이터베이스로 리턴한다.


Listing 10. conn 변수를 DerbyDatabase 클래스의 Connection 객체로 설정하기
Connection conn = DerbyDatabase.getConnInstance();

이 코드의 다음 섹션에서는 사용자가 새로운 사용자인지 여부를 결정하고 사용자가 존재할 경우 데이터베이스에서 사용자의 ID를 선택하거나, 존재하지 않을 경우 데이터베이스에 ID를 추가한다.


Listing 11. LoginServlet 클래스에서 새로운 사용자 처리하기 
// the user is not new, so look up the username and password
// in the APP.USERS table

if (newUser == null || newUser.equals(""))
{
 sql = "select * from APP.USERS where username = '" + user
        + "' and password = '" + password + "'";
 String[] loginResults = DerbyDatabase.runQuery(conn, sql);

 // if the query was successful one row should be returned
 if (loginResults.length == 1)
 {
  validUser = true;
 }
}
// the user is new, insert the username and password into 
// the APP.USERS table
else
{
 sql = "insert into APP.USERS (username, password) values " + "('"
 + user + "', '" + password + "')";
 int numRows = DerbyDatabase.executeUpdate(conn, sql);
 if (numRows == 1)
 {
  validUser = true;
 }
}

사용자 ID Susan이 APP.USERS 테이블에 추가되었다는 것을 확인하려면 ij를 사용하여 APP.USERS 테이블을 쿼리한다.

ij를 가져오려면 LowFareAir 폴더를 오른쪽 클릭하여 Apache Derby > ij (Interactive SQL)를 선택한다. ij에서 연결 문을 만들고 select * from APP.USERS; 쿼리를 실행하여 airlinesDB 데이터베이스로 연결하여 브라우저에 입력한 사용자 ID가 나타나는지를 확인한다. 이 예제에서 사용자 ID는 Susan이다.

주: Eclipse 버전 3.1은 이전 버전과는 다른 작동을 갖고 있다. 커서가 콘솔 뷰에 있다. 커서는 언제나 라인의 시작부분에 위치한다. 이상하게 보여도 ij 프롬프트에서 입력을 시작하면 커서는 정확환 위치로 배치된다. ij에서 'j' 다음에 배치된다.


Listing 12. airlinesDB 데이터베이스로 연결하기
connect 'jdbc:derby://localhost:1527/airlinesDB';
select * from APP.USERS;

ij의 아웃풋은 다음과 같다.


그림 13. APP.USERS 테이블의 ij 결과 
APP.USERS table results 

Register.jsp는 이 값들을 정확히 전달하고 LoginServlet.java는 사용자 ID와 패스워드를 정확히 테이블에 삽입했다. 'slc'와 'slc' 라는 사용자 ID와 패스워드는 이미 테이블에 있었다.

LoginServlet.java의 나머지 코드는 부정확한 사용자 ID와 패스워드를 처리한다. 모든 것이 정확하다면 Welcome.jsp로 결과를 전달한다. 다음 이미지는 출발지 Albuquerque와 도착지 Los Angeles가 있는 Welcome.jsp이다. 사용자 ID는 LoginServlet.java에서 Welcome.jsp로 전달되었다.


그림 14. 로그인 성공 후 Welcome.jsp 
Welcome.jsp after login 

Welcome.jsp는 CheckFlightsServlet.java에 게시된다. CheckFlightsServlet.java를 연다. 이 서블릿에서 주목할 점은 인커밍 매개변수들을 파싱한 후에 DerbyDatabase 메소드 origDestFlightList()를 호출한다는 것이다. 이 메소드는 FlightsBean 객체들의 어레이를 리턴한다.


Listing 13. CheckFlightsServlet 클래스
Connection conn = DerbyDatabase.getConnInstance();

FlightsBean[] fromToFlights = \
 DerbyDatabase.origDestFlightList(conn, from, to);

FlightsBean 어레이가 파퓰레이트 되면, CheckFlightsServlet fromToFlights의 변수 이름과 함께 이 세션에 결과를 배치한다.


Listing 14. FlightsBean의 어레이를 세션 빈에 배치하기 
request.getSession().setAttribute("fromToFlights", fromToFlights);

DerbyDatabase.java 클래스를 열어서 이 메소드가 어떤 일을 수행하는지를 확인한다. 코드 일부는 알아보기 쉽도록 포맷되었다.


Listing 15. origDestFlightList 메소드 확인
public static FlightsBean[] origDestFlightList(Connection conn, \
 String origAirport, String destAirport)
{
 String query = "select flight_id, segment_number, orig_airport, " +
 "depart_time, dest_airport, arrive_time, meal, flying_time, miles," +
 "aircraft from app.flights where ORIG_AIRPORT = ? AND " +
 "DEST_AIRPORT = ?";
 List list = Collections.synchronizedList(new ArrayList(10));
        
 try
 {            
  PreparedStatement prepStmt = conn.prepareStatement(query);
  prepStmt.setString(1, origAirport);
  prepStmt.setString(2, destAirport);
  ResultSet results = prepStmt.executeQuery();

  while(results.next())
  {
   String flightId = results.getString(1);
   String segmentNumber = results.getString(2);
   String startAirport = results.getString(3);
   String departTime = results.getString(4);
   String endAirport = results.getString(5);
   String arriveTime = results.getString(6);
   String meal = results.getString(7);
   String flyingTime = String.valueOf(results.getDouble(8));
   String miles = String.valueOf(results.getInt(9));
   String aircraft = results.getString(10);
                
   list.add(new FlightsBean(flightId, segmentNumber, startAirport,
   departTime, endAirport, arriveTime, meal, flyingTime, miles, aircraft));
  }
  results.close();
  prepStmt.close();
 }
 catch (SQLException sqlExcept)
 {
  sqlExcept.printStackTrace();
 }
        
 return (FlightsBean[])list.toArray(new FlightsBean[list.size()]);
}

origDestFlightList 메소드는 PreparedStatement를 사용하여 SQL 쿼리를 만들고 그 결과를 FlightsBean[] 어레이에 둔다. FlightsBean 구조체들 중 하나는 아래와 같다.


Listing 16. FlightsBean 구조체
public FlightsBean(String flight_id, String segNumber, 
 String origAirport, String depart_time, String destAirport, 
 String arrive_time, String food, String flying_time, 
 String mile, String jet)
{
 flightId = flight_id;
 segmentNumber = segNumber;
 startAirport = origAirport;
 departTime = depart_time;
 endAirport = destAirport;
 arriveTime = arrive_time;
 meal = food;
 flyingTime = flying_time;
 miles = mile;
 aircraft = jet;
}

origDestFlightList 메소드가 FlightsBean 어레이를 파퓰레이드 하면 CheckFlightsServlet 서블릿에서 프로세스가 계속 진행되고 결과가 GetFlights.jsp 페이지로 전달된다.

다음 섹션에서는 WTP의 JSP 디버거 기능을 사용하여, 항공편을 선택할 때 FlightsBean에 리턴된 값을 볼 것이다.

다음 섹션에서는 Tomcat 서버를 디버그 모드에서 시작할 것이다. 작업공간의 우측 하단 섹션에 있는 Servers 뷰 탭을 선택한다. Tomcat Server 라인을 오른쪽 클릭하여 Stop을 선택한다.


그림 15. WTP Servers 뷰에서 Tomcat 서버 중지하기 
Stopping Tomcat 



위로


JSP 디버거 사용하기

다시 코드로 돌아가 샘플 애플리케이션을 정리해 보자.

  • WTP
    • Database Explorer 뷰를 사용하여 Derby 클라이언트 드라이버를 사용하는 Derby 10.1 데이터베이스로 연결한다.
    • Database Explorer 뷰에서 FLIGHTS 테이블의 내용을 샘플링 한다.
    • Database Explorer 뷰에서 FLIGHT 테이블로 열을 추가한다. Data > Open 메뉴 옵션을 사용한다.
    • JSP 파일에서 Run As > Run On Server 옵션을 사용하여 Tomcat 서버를 시작한다.
    • JSP 에디터에서 JSP를 열고 확인한다.
    • Servers 뷰를 사용하여 Tomcat 서버를 중지한다.
  • Derby 플러그인
    • Apache Derby nature를 Dynamic Web Project에 추가한다.
    • Project Properties 메뉴를 사용하여 Derby 시스템 속성을 설정한다.
    • ij를 통해 전체 SQL 스크립트를 실행한다.
    • ij를 통해 SQL 명령어를 만든다.
    • Derby Network Server를 시작 및 중지한다.

이제 WTP의 JSP 디버깅 기능을 살펴보자.

이 시점에는 Derby airlinesDB APP.USERS 테이블에 적어도 한 개의 유효 사용자가 있어야 하고 여러분은 또 한명을 추가할 수도 있다. 애플리케이션을 사시 실행하기 전에 GetFlights.jsp 페이지에 중단점을 설정하고 디버그 모드에서 Tomcat 서버를 시작한다.

중단점을 설정하려면 GetFlights.jsp를 열고 <c:set var="myradiobutton"로 시작하는 코드 라인 왼쪽 편에 회색 공간에 오른쪽 클릭을 한다. Toggle Breakpoints를 선택한다.


그림 16. GetFlights.jsp 중단점 설정
Setting a breakpoint 

중단점은 왼편 회색 부분에 푸른색 점으로 나타날 것이다. Project Explorer(Derby Network Server가 여전히 실행되는지를 확인하라.)에서 Welcome.jsp를 오른쪽 클릭하고 Debug As > Debug On Server를 선택한다. Tomcat Server가 Debug 모드에서 시작하고 Welcome.jsp 페이지에서는 사용자 ID와 패스워드를 보여준다.

이전에 입력한 사용자 ID와 패스워드를 입력하거나 패스워드 값 slc와 사용자 ID 값 slc를 입력한다. 이전에 설정된 쿠키를 삭제하지 않았다면 로그인을 다시 하지 않고 Welcome.jsp에서 항공편을 선택할 수 있다. Origin에서 Destination 까지 리스팅 된 모든 항공편이 다 직항은 아니다. Origin of Albuquerque 와 Destination of Los Angeles를 선택한다. 왜냐하면 이 항공편이 직항이기 때문이다. Submit Query를 누르고 종료한다.

이 부분에서 Eclipse는 Debug perspective로 전환할 수 있도록 해 준다. perspective 전환을 확인한다. 디버그 perspective가 나타나면 Variables 뷰가 작업 공간의 상단에 나타난다. 왼쪽 하단에는 GetFlights.jsp 에디터가 나타난다.

Variables 뷰에는 값들이 즉시 파퓰레이트 되지 않을 수도 있다. Debug 뷰에 가서 일시 중지된 쓰레드를 선택한다. 중지된 쓰레드를 확장하고 Debug 뷰에서 GetFlights.jsp를 선택한다. Variables 뷰가 파퓰레이트 된다.

Variables 뷰에서 코어 JSTL when 태그를 찾는다. _jspx_th_c_when_0=WhenTag용 트리를 확장한다. (그림 17)


그림 17. JSP Debug perspective에서 Variables 확인하기 
Examining variables 

WhenTag 내에서 ChooseTag 부모 태그에 대한 참조를 주목하라. ChooseTag를 확장하고 이 안에 부모 ForEachTag를 포함시킨다. ForEachTag를 확장하고 FlightsBean과 동급인 아이템 변수를 확장한다. 이 모든 일을 수행하면 Variables 뷰는 다음과 같다.


그림 18. Debug 모드에서의 FlightsBean 값
FlightsBean values in Debug mode 

FlightsBean 객체에 설정된 값을 보여주고 있다. 이것은 Albuquerque의 공항과 Los Angeles의 공항과 함께 선택되었다. JSP 디버거는 웹 애플리케이션의 문제를 해결할 때 매우 유용하다. 특히 변수들을 호가인할 때 특별히 유용하다.

왼쪽 상단 메뉴 아이템에 있는 Resume 버튼(녹색 화살표 모양)을 클릭하여 중단점으로 간다. 이 브라우저는 GetFlights.jsp 페이지의 결과를 디스플레이 한다. 이 브라우저에서 가능한 항공편(AA1111)을 선택하고 Book Flight 버튼을 누른다.

다음 페이지는 항공편을 예약하거나 다른 항공편을 검색할 수 있는 페이지이다. Book Flight 버튼을 클릭한다.


그림 19. Flight History
Flight History Browser view 

이전 스크린에서 Book Flight를 클릭하면 APP.FLIGHTHISTORY 테이블로 열이 삽입된다. ij Database Explorer를 사용하는 방법을 알고있기 때문에 그 열이 실제로 테이블에 삽입되었는지를 확인할 수 있다.

이 부분에서 사용자는 새로운 항공편을 선택하거나 애플리케이션에서 로그아웃 할 수 있다.




위로


요약

WTP 플랫폼을 설정할 때 외부 Tomcat 서버를 사용하고 JSP 파일을 디버그 하고 Database Explorer를 사용하는 10.1 Derby 데이터베이스로 연결을 설정하고 Database Explorer를 사용하여 테이블을 검색하고 열을 삽입하였다.

Apache Derby nature를 추가하고, 네트워크 서버를 시작 및 중지하고, ij를 사용하여 SQL 스크립트를 실행하고 명령어를 만들고 derby.system.home 속성을 설정했다.

웹 애플리케이션용 web.xml 파일을 설정하여 Derby를 데이터 소스로서 사용했다.

마지막으로 JSTL SQL 태그 라이브러리를 사용하여 데이터 소스로서 설정했던 Derby 데이터베이스에 대해 쿼리를 만들었다.

이 글을 통해 WTP와 Derby 플러그인에서 사용할 수 있는 다양한 툴을 이해했으리라 믿는다. 여러분은 앞으로 데이터 스토어로서 Derby를 사용하는 강력한 웹 애플리케이션을 만들 수 있을 것이다.





위로


다운로드 하십시오

설명 이름 크기 다운로드 방식
Derby Database files for the Web Application LowFareAirData.zip 216 KB  FTP|HTTP
LowFare Air war file LowFareAir.war 31 KB  FTP|HTTP
다운로드 방식에 대한 정보


출처: http://www.ibm.com/developerworks/kr/library/dm-0509cline/