메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

오픈라즐로 애플리케이션 개발하기

한빛미디어

|

2006-11-15

|

by HANBIT

10,750

제공: 한빛 네트워크
저자: Sreekumar Parameswaran Pillai, 이대엽 역
원문: Developing an OpenLaszlo App

소개

XML 기술은 기술적으로 최고조에 달했으며 업체들은 XML 기술의 능력과 유연성을 이용하는데 열광하고 있다. XML에 기반한 표현계층(presentation tier)의 기술들 또한 이러한 흐름에 탄력을 받고 있다. 데이터베이스 제공업체들은 한동안 그들의 DB 제품에 암묵적으로 XML을 지원하도록 하였다. IBM은 개발, 생산, 심지어 배포에 이르기까지 모든 측면에 대하여 무료로 제공되는 DB2 Express-C 소프트웨어에 XML을 지원을 제공하고 있다. 오픈라즐로는 XML 기반의 스크립팅 프레임워크를 제안하는데 이는 시각적인 호소력, 유연성, 효율성으로 인해 충분히 주목할만한 가치가 있다. 라즐로의 기반 구조물(foundation block)은 XML이며 그것들은 다른 어떤 것들과도 다르게 단짝을 이룬다.

이 기사에서는 오픈라즐로, DB2, 그리고 자바를 이용하여 주소록(addressbook) 애플리케이션의 종단을 개발할 것이다. 애플리케이션은 기능은 단순하더라도 위에서 언급된 기술들이 통합된 모습을 보여줄 수 있어야 한다. 이 기사는 Ant와 IDE4Laszlo의 개발환경을 초기화하는 것에 관해 빠르게 시작하는 데 있어 가이드를 제공하였던 오픈라즐로(OpenLaszlo) 소개 기사의 후속편이다. 우리는 주소록 애플리케이션을 거기에서 논의했던 개발환경 위에 그대로 구축할 것이다.

필요한 소프트웨어 다운로드

주소록 애플리케이션을 시험해 보기 위해서는 다음의 소프트웨어들이 개발환경에 추가적으로 필요하다:
  1. DB2 Express-C를 다운로드하여 설치한다. 이것을 다운로드, 개발, 생산하는 것은 무료이다. 여러분은 앞의 링크에서 IBM XML 데이터베이스에 관해 좀 더 배울 수도 있다.
  2. 전체 애플리케이션의 소스코드를 다운로드한다.
소프트웨어 설치

설치 프로그램에 들어있는 설명서에 따라 DB2 Express-C를 설치한다.

adbookdb 데이터베이스 생성
  1. 이것은 XML 데이터베이스이므로 테이블은 단순히 두 개의 컬럼을 가진 매우 단순한 구조를 띤다 (그림 1 참조).

    그림1
    그림 1. adbookdb의 구조

  2. 윈도의 Start >> Programs >> IBM DB2 >> 으로 간 다음 DB2 Command Editor를 실행한다. 아니면 윈도의 알림영역에 위치한 DB 아이콘에 오른쪽 버튼을 클릭하여 start(DB2)를 선택하거나 Command Editor를 실행시킨다(그림 2 참조).

    그림2
    그림 2. DB2 Community Edition의 빠른 실행

  3. 아래 리스팅에 나타나 있는 스크립트를 실행하여 데이터베이스를 초기화한다.
    리스팅 1.
    CREATE DATABASE ADBOOKDB USING CODESET UTF-8 TERRITORY US~
    
    CONNECT TO ADBOOKDB user db2admin using "db2admin"~
    
    CREATE SCHEMA DB2ADMIN AUTHORIZATION DB2ADMIN~
    
    CREATE TABLE DB2ADMIN.ADDRESSBOOK 
          (EMAILID CHARACTER (50) NOT NULL PRIMARY  KEY, CONTACTINFO XML) ~
    
    위 파일은 10개의 레코드를 데이터베이스에 삽입하는 스크립트를 포함하고 있다. 한 사람의 전자메일 아이디가 주키이며 이는 데이터베이스에 삽입되는 다음의 XML 문자열로부터 주어진다. 한 사람의 전체 연락처 정보는 하나의 XML 문자열 엘리먼트로 전달된다. 아래에 나타나 있는 코드는 입력 스크립트의 한 예이며, XML과 주키간의 1대1 대응관계를 할당하기 위하여 전자메일 아이디가 엘리먼트에 하나의 속성으로서 유지되고 있음을 주목하라.
    insert into db2admin.addressbook values ("grace.thomas@yahoo.com","
    
    Grace
    Thomas
    9947267690
    Grace Villa
    III Cross
    Pattom
    ")~
    
  4. 데이터가 적절히 삽입되었는지 확인하기 위하여 다음의 명령을 DB2 Command Editor에서 실행해 본다. DB2는 XML 컬럼을 트리 뷰와 소스 뷰(그림 3과 그림 4 참조)의 두 가지 형태로 볼 수 있는 뛰어난 뷰를 제공해 준다.
    SELECT * FROM DB2ADMIN.ADDRESSBOOK~ 
    
    그림3
    그림 3. DB2 XML 문서 뷰어에서의 XML 필드에 대한 트리 뷰

    그림4
    그림 4. DB2 XML 문서 뷰어에서의 XML 필드에 대한 소스 뷰
애플리케이션 작동 흐름

addressbook 애플리케이션은 주소록 기능을 제공해주는 다른 어떤 애플리케이션과도 차이점은 없다. 사실 그것은 오직 다음의 제한된 기능들만을 제공한다:
  1. addressbook 데이터베이스에 연락처 정보 추가
  2. 이미 데이터베이스내에 존재하는 연락처 정보들의 목록 나열
  3. 정보 갱신
추가될 수 있는 다른 모든 기능들은 독자의 상상에 맡기도록 하겠다.

addressbook 애플리케이션은 완전한 기능을 갖춘 애플리케이션을 대신하여 간단한 JSP을 사용한다. 이것이 가능한 까닭은 DB2 Express-C 데이터베이스가 데이터를 적격한(well-formed) XML 구조로 리턴할 수 있게 하는 XQuery를 지원하기 때문이다. 생산 계획상으로는 이러한 JSP는 트랜잭션 처리와 비즈니스 로직을 구현하기 위한 애플리케이션 프레임워크에 의해 대체될 수도 있다. 또한 표현계층(presentation layer)이 응용계층 및 데이터 전송으로부터 XML을 이용하여 이론상 완전히 분리되었으므로 애플리케이션 코드는 어떠한 기술을 사용하더라도 만들어 질 수 있다.

오픈라즐로를 이용하면 어떠한 페이지의 변동도 없으므로 기존 웹 애플리케이션과는 다르게 표현을 처리해야 할 필요가 있다. 데이터는 웹 애플리케이션으로 전송되어 저장되며 동시에 사용자 인터페이스가 갱신되어 그 변화를 반영한다. 그러나 이것은 두 가지 문제를 내포하고 있다:
  1. 만약 GUI상의 데이터에 대한 갱신의 반영이 저장되고 있는 데이터에 대한 애플리케이션의 요청과 동시에 이루어지게 되면 어떻게 그 정보가 영속성 메커니즘에 따라 적절히 추가되었음을 보장할 수 있을 것인가? 만약 유효성 오류 혹은 사용자에게 전달되어야 할 필요가 있는 예외가 발생할 경우에는 어떻게 될 것인가? 이것을 해결하는 한 가지 방법은 데이터베이스의 변경이 이루어질 때마다 즉시 클라이언트의 데이터도 갱신시켜주는 것이다. 이 경우 클라이언트에 이미 존재하는 정보는 한번 더 다운로드 될 것이므로 비효율적일 수 있다.
  2. 레코드의 전체 집합을 다시 한번 모두 읽어옴으로써 갱신하는 것은 형편없는 응답 시간을 만들어내는 또 하나의 원인이 될 수도 있다. 또한 활동들을 비동기적으로 실행시킬 수 있는 능력을 가진 Ajax의 위력을 간과할 수도 있다.
궁극적으로 우리에게는 어쩔 수 없이 한 가지 선택만이 남아있다: 응용계층으로부터 확인하는 즉시 클라이언트 GUI를 갱신하는 것이다. 이렇게 하면 변경된 데이터 집합만이 갱신될 것이다. 다른 모든 정보들은 컴포넌트 캐시에 존재한다. 이 방법은 신속한 응답 시간을 제공하는 데스크톱 애플리케이션을 흉내 낸 것일 것이다. 오픈라즐로의 데이터 캐싱 메커니즘과 오픈라즐로 API는 이러한 기능을 쉽게 사용할 수 있도록 해준다. (그림 5 참조)

그림5
그림 5. 주소록 애플리케이션의 작동 흐름

애플리케이션 구동
  1. 이 기사에서 제공되는 addressbook.zip 파일을 압축 해제하여 파일을 각각의 위치에 복사한다 (그림 6 참조).

    그림6
    그림 6. 이클립스에서의 주소록 애플리케이션 작업공간
  2. db2jcc.jar와 db2jcc_license_cu.jar를 웹 애플리케이션의 web-inf/lib 폴더로 복사한다. 이 JAR 파일들은 애플리케이션이 데이터베이스에 연결되는데 필요하다. 이러한 JAR 파일들이 들어있는지 DB2 설치 디렉터리 아래의 SQLLIB\java 디렉터리를 살펴보라.
  3. Ant 타겟인 deploy-all을 실행시켜 오픈라즐로와 자바 웹 애플리케이션을 디플로이한다. 이것은 오픈라즐로 애플리케이션은 LPS로, .war 파일은 기본 톰캣 5.0 서버로 디플로이 할 것이다.
  4. DB2를 시작한다.
  5. 오픈라즐로 프레젠테이션 서버를 시작한다.
  6. 브라우저에서 http://localhost:8080/lps-3.2/laszlotutorial/addressbook.lzx URL을 입력하고 엔터키를 친다. 그림 7은 메인 페이지의 스크린샷이다.

    그림7
    그림 7. 주소록 애플리케이션
애플리케이션의 기능

애플리케이션의 네비게이션은 직관적이다.
  1. Add New Contact를 클릭하면 개인의 연락처 정보를 추가하는 화면이 나타날 것이다. 전자메일 아이디만이 필수 입력사항이다. 다른 모든 정보는 언제든지 이 화면으로 되돌아와 갱신 시킬 수 있다(그림 8 참조).

    그림8
    그림 8. 새 연락정보 추가 화면
  2. List all contacts를 클릭하면 데이터베이스내에 저장되어 있는 연락처 정보 가운데 기본적인 정보들만이 스크롤 가능한 테이블로 나열될 것이다(그림 9 참조).

    그림9
    그림 9. 데이터베이스내의 모든 연락정보 나열
  3. 한 사람의 전자메일 아이디를 더블클릭하면 현재 데이터베이스 상에서 볼 수 있는 정보들이 나타나 있는 갱신 화면이 팝업으로 나타날 것이다.

    그림10
    그림 10. 이미 존재하는 연락정보의 열람 및 갱신
  4. 이 화면에서 Update 버튼을 누르면 애플리케이션이 데이터베이스내의 레코드를 갱신하도록 요청하게 된다. 웹 응용계층상의 예외나 검증상의 다른 어떠한 오류들도 HttpResponse내의 사용자 정의 XML을 통해 클라이언트로 전달될 수 있다. 만약 여러분이 실행이 중지된 데이터베이스내의 연락처들을 나열하게 되면 그림 11과 같은 화면을 보게 될 것이다. 이것은 사용자에게 유용한 메시지를 전달할 수 있도록 손쉽게 수정될 수 있다.

    그림11
    그림 11. 예외사항을 사용자에게 보여주기
다음은 애플리케이션에서 사용된 .lzx 클래스들이다:
  1. addressbook.lzx: 전체 사용자 인터페이스가 만들어져 구축될 캔버스를 선언한다.
  2. contactdetails.lzx: 이 클래스는 연락처의 세부 정보를 보여주기 위한 화면을 생성한다. 여기에서 사용자는 연락처 정보를 갱신할 수도 있다.
  3. newcontact.lzx: 이것은 새로운 연락처에 대한 화면 정보들의 집합이다.
  4. datasets.lzx: 이 클래스는 데이터집합을 하나의 파일로 그룹화하는 것을 나타낸다. 그 파일은 addressbook.lzx에 포함되어 혼란을 방지한다.
  5. xmlfetcher.jsp: 이 JSP 파일은 현재 구성에서 응용계층을 표현한다. 생산 계획상 이것은 비즈니스 로직을 포함하는 프레임워크와 트랜잭션, 검증 및 기타 작업들을 처리하는데 필요한 프레임워크로 대체될 수도 있다.
  6. ringingphone.gif: 애플리케이션에 양념을 가미하는 자그마한 그래픽 파일이다.
GUI의 구조는 단지 초기에는 숨겨졌다가 관련된 옵션이 선택되면 보여지는 3개의 뷰로 구성된다. 이 뷰는 항상 보여진다.

코드 검토

[addressbook.lzx]

인클루드(include) 문장은 두 개의 클래스를 메인 파일에 합친다. 그것들은 가독성 향상을 목적으로 분리된 .lzx 파일에 들어 있다.



onclick() 이벤트 핸들러는 phonelist와 contactallinfo 뷰를 숨기고 Add New Contact 화면을 보여준다.


messagetext.setText("");
if(phonelist.visible){phonelist.setVisible(false);}
if(contactallinfo.visible){contactallinfo.setVisible(false);}
newperson.setVisible(true);
newperson.resetForm();
newperson.title.setAttribute("text","New Contact");


onclick() 이벤트 핸들러는 다른 뷰들을 숨기고 listAllContacts() 메소드를 호출한다.


messagetext.setText("");
if(newperson.visible){newperson.setVisible(false);}
parent.parent.listAllContacts();
contactallinfo.setVisible(false);
phonelist.setVisible(true);



오픈라즐로의 그리드 컴포넌트는 테이블 형태로 XML 경로내의 데이터를 나열한다. 또한 그리드 컴포넌트는 나열된 어떠한 컬럼에 대해서도 앞단에서 정렬할 수 있도록 해준다.

No


 First Name


 Last Name


 Phone


 Email Id

한 사람의 전자메일 아이디를 나타내는 텍스트로부터 ondblclick() 이벤트가 처리된다. 더블클릭 이벤트에서는 getContactdetailsMore() 메소드가 현재 컴포넌트의 텍스트 값을 전달하면서 호출되는데, 이 텍스트 값은 다름 아닌 전자메일 아이디이다. 다음은 이것의 처리과정이다:
  1. 연락처 정보에 대한 주키인 전자메일 아이디는 여기에서는 JSP에 의해 표현되는 웹 애플리케이션으로 전달된다.
  2. JSP는 연락처에 대한 상세정보를 한 사람의 노드(node)로서 돌려준다.
  3. contactallinfo 창의 경로는 위 연락처에 관한 상세 정보를 가지는 새로운 경로로 지정된다. 따라서 현재 창은 특정 연락처에 관한 상세 정보를 보여준다.

phonelist.setVisible(false);
contactallinfo.setVisible(true);
contactallinfo.getContactdetailsMore(this.text);
contactallinfo.setDatapath("contactdetailsDS:/addressbook/person");
contactallinfo.title.setAttribute("text","View/ Update contact details");




listAllContacts() 메소드는
  1. 캔버스로부터 listcontactsDS에 대한 참조를 얻는다
  2. LzParam 객체를 생성하는데 이 객체는 우리가 HttpRequest에 필요한 파라미터를 이름=값의 쌍으로 추가할 수 있도록 해준다.
  3. action=getall 문자열이 LzParam 객체에 추가되는데, 이는 데이터 집합과 관련되어 있다.
  4. HttpRequest는 LzParam 객체상의 doRequest() 메소드를 호출함으로써 만들어진다.
xmlfetcher.jsp의 HttpResponse는 현재 데이터베이스에 존재하는 연락처의 전체 목록을 가진 listcontactsDS 데이터집합을 가지게 된다. 또한:
  1. "getall" 기능은 데이터베이스내의 연락처에 속하는 정보 중 다음의 4개만을 돌려준다: 이름, 성, 전화번호, 전자메일 주소. 대부분의 경우 이 정보만으로도 충분할 것이다.
  2. 초기에 목록을 나열하는 동안 읽어들여지는 데이터의 양을 제한함으로써 응답시간은 좀 더 빨라질 수 있다.
  3. 만약 사용자가 특정 연락처에 추가정보를 요구하면, 연락처의 전자메일 아이디를 더블클릭하여 요청할 수 있다.

var ds=canvas.datasets.listcontactsDS;
var p=new LzParam();
p.addValue("action","getall",true);
ds.setQueryString(p);
ds.doRequest();

datapointer는 listcontactsDS (데이터집합)내의 결과 노드를 가리키며 만약 데이터 집합의 데이터에 어떠한 변경사항이 존재하면 ondata() 이벤트가 트리거 될 것이다. 만약 응용계층에서 예외사항이나 검증 오류가 존재하면 애플리케이션(JSP)은 데이터집합의 결과 노드에 예외사항에 관한 메시지를 집어넣을 것이다. ondata() 이벤트에서는 datapointer가 노드의 값을 검사하는데, 그것이 만약 성공적이면 GUI 갱신 절차를 시작한다. 가 실패하면 사용자에게 예외사항에 관한 메시지를 출력한다.


if (this.xpathQuery("listcontactsDS:/addressbook/result[@action="exception"]/text()") == "failure") {
messagetext.setText("There is an exception!");
}else{
messagetext.setText("");
}


[Contactdetails.lzx]

getContactdetailsMore() 메소드는 전자메일 아이디에 근거하여 한 사람의 상세정보를 모두 얻어온다. 이것은 contactdetailsDS 데이터집합에 적재된다. 서로 다른 단계별 contactdetailsDS 데이터집합의 내용을 알아보는 것은 재미있는 일이다. 갱신에 대한 요청으로 인해 이 데이터집합은 연락처에 관한 상세 정보를 포함하게 될 것이다. 갱신 명령이 실행될 때 이 데이터집합은 실행이 완료됨과 동시에 갱신된 정보를 갖게 될 것이며, 예외사항 아니면 성공했다는 메시지를 포함하게 될 것이다. 여러분이 updateContact 메소드를 실행해 보면 알게 되는 것처럼 이 데이터집합은 xmlfetcher.jsp에 대한 갱신 요청에 대한 상태 정보만을 가지게 될 것이다.

var ds=canvas.datasets.contactdetailsDS;
var p=new LzParam();
p.addValue("action","getcontactdetails",true);
p.addValue("emailid",email_id, true);
ds.setQueryString(p);
ds.doRequest();

updateContact() 메소드는:
  1. 폼 필드의 현 데이터를 클래스 속성으로 캐싱한다. 이는 갱신상태에 근거하여 GUI가 갱신될 필요가 있을 때 필요하다.
  2. 연락처에 관한 새로운 정보를 데이터베이스에 저장한다.
  3. contactdetailsDS 데이터집합은 xmlfetcher.jsp에 전달된 전자메일에 대한 전체 연락처의 상세정보를 가진다.
각각의 단계별로 데이터집합의 내용은 계속 변화하기도 한다. updateContact 메소드를 실행하면 이 데이터집합은 xmlfetcher.jsp에 대한 갱신요청에 대한 상태정보만을 갖게 될 것이다.

setAttribute("emailid",hb_1.email_in.getText());
setAttribute("firstnm",hb_2.fname_in.getText());
setAttribute("lastnm",hb_2.lname_in.getText());
setAttribute("phonenmbr",hb_4.pnumber_in.getText());

var ds=canvas.datasets.contactdetailsDS;
var p=new LzParam();
p.addValue("action","updatecontact",true);
p.addValue("emailid",emailid, true);
p.addValue("firstname",firstnm,true);
p.addValue("lastname",lastnm,true);
p.addValue("phonenumber",phonenmbr,true);
p.addValue("housename",hb_3.hname_in.getText(),true);
p.addValue("streetname",hb_3.sname_in.getText(),true);
p.addValue("cityname",hb_4.cname_in.getText(),true);
ds.setQueryString(p);
ds.doRequest();

[newcontact.lzx]

addNewContact() 메소드는 폼 필드의 값을 재사용할 목적으로 지역변수에 캐싱하며 응용계층에 대한 요청을 수행하여 데이터베이스를 갱신한다.

setAttribute("emailid",hb_1.email_in.getText());
setAttribute("firstnm",hb_2.fname_in.getText());
setAttribute("lastnm",hb_2.lname_in.getText());
setAttribute("phonenmbr",hb_4.pnumber_in.getText());

var ds=canvas.datasets.addnewDS;
var p=new LzParam();
p.addValue("action","addnewcontact",true);
p.addValue("emailid",emailid, true);
p.addValue("firstname",firstnm,true);
p.addValue("lastname",lastnm,true);
p.addValue("phonenumber",phonenmbr,true);
p.addValue("housename",hb_3.hname_in.getText(),true);
p.addValue("streetname",hb_3.sname_in.getText(),true);
p.addValue("cityname",hb_4.cname_in.getText(),true);
ds.setQueryString(p);
ds.doRequest();

그런 다음 폼 컴포넌트를 초기화 한다:

hb_1.email_in.setText("");
hb_2.fname_in.setText("");
hb_2.lname_in.setText("");
hb_4.pnumber_in.setText("");
hb_3.hname_in.setText("");
hb_3.sname_in.setText("");
hb_4.cname_in.setText("");

동일한 기능이 다른 datapointers에서도 제공되는데 여기에서 다시 새로운 연락처 추가 기능에 대한 오류확인이 이루어진다. 만약 메시지가 성공적이면 이것은 데이터집합의 루트를 가리키는 포인터를 얻게 되며 자식 엘리먼트를 탐색하여 폼 컴포넌트에 주어진 값에 텍스트를 설정한다. 그런 다음 그리드의 datapath가 갱신되어 변경된 데이터가 그리드에서 보여지게 된다.


if (this.xpathQuery("result[@action="addnewcontact"]/text()") == "success") {
messagetext.setText("Contact details successfully Inserted");
var dp = canvas.datasets.listcontactsDS.getPointer();
dp.selectChild(2);
dp.addNodeFromPointer(dp);
dp.setNodeAttribute("email",classroot.emailid);
dp.selectChild();
dp.setNodeText(classroot.firstnm);
dp.selectNext();
dp.setNodeText(classroot.lastnm);
dp.selectNext();
dp.setNodeText(classroot.phonenmbr);
Debug.write("classroot.emailidentifier",classroot.emailid);
parent.setVisible(false);
canvas.mainwindow.listAllContacts();
phonelist.setVisible(true);
contactsgrid.datapath.updateData();
} else if (this.xpathQuery("result[@action="addnewcontact"]/text()") == "failure") {
messagetext.setText("Update failed !");
}else if (this.xpathQuery("result[@action="exception"]/text()") == "failure") {
messagetext.setText("There is an exception!");
}else{
messagetext.setText("");
}


[datasets.lzx]

이것은 애플리케이션에 필요한 모든 데이터집합을 선언한다.










[xmlfetcher.jsp]

다음의 XQuery는 전자메일 아이디, 이름, 성, 그리고 전화번호를 리턴한다. 이전과 XQuery 표현 다음의 문자열들에 주목하라. 이것은 루트 엘리먼트인 안의 엘리먼트를 감싸는 데 필요한 것들이다.
if (action.equals("getall")) {
pstmt = connection.prepareStatement("XQuery  {
( for $person in db2-fn:xmlcolumn("DB2ADMIN.ADDRESSBOOK.CONTACTINFO")/person"+
"return  {($person/firstname), ($person/lastname),($person/phone)} )}
");
rs = pstmt.executeQuery();

while (rs.next()) {
System.out.println(rs.getString(1));
out.print(rs.getString(1));
}
}
이 기능에서는 한 사람의 모든 정보가 검색되어 클라이언트로 리턴된다. 그 사람의 전자메일 아이디는 요청 파라미터 값으로 전자메일 아이디가 JSP로 전달된다.
if (action.equals("getcontactdetails")) {
String pk = request.getParameter("emailid");

String sql="values(xmlquery(" for $person in db2-fn:xmlcolumn(\"DB2ADMIN.ADDRESSBOOK.CONTACTINFO\")/person"+
" where $person/@email eq $emailid " +
" return {($person)} " "+
" passing cast(? AS varchar(50) ) as \"emailid\" ))";

pstmt = connection.prepareStatement(sql);

pstmt.setString(1,pk);
rs= pstmt.executeQuery();

while (rs.next()) {
System.out.println(rs.getString(1));
out.print(rs.getString(1));
}
이 기능에서는 새로운 연락처 정보가 데이터베이스에 저장된다. 정보는 요청 파라미터로부터 파싱되어 CONTACTINFO 컬럼으로 들어가기 전에 XML 문자열로 변환된다. 생산 환경에서는 이것은 애플리케이션 프레임워크에 포함된 XML 생성기 유틸리티에 의해 처리될 것이다.
if (action.equals("addnewcontact")) {
String pk = request.getParameter("emailid");
String fname = request.getParameter("firstname");
String lname = request.getParameter("lastname");
String hname = request.getParameter("housename");
String sname = request.getParameter("streetname");
String cname = request.getParameter("cityname");
String phnumber = request.getParameter("phonenumber");

String finalString=""+fname+
                                    ""+lname+""+
phnumber+""+hname+""+
sname+""+cname+"";

String sql="INSERT INTO DB2ADMIN.ADDRESSBOOK(EMAILID ,CONTACTINFO)values(""+pk+"",""+finalString+"")";

stmt = connection.createStatement();
stmt.executeUpdate(sql);

out.print("success");

}
updatecontact 기능에서는 사용자의 변경된 정보들이 데이터베이스에 갱신된다. 이전의 경우에서처럼 XML 문자열이 생성되어 DB XML 컬럼이 새로운 문자열로 갱신된다. 이 상황에서는 표현 계층에서 동일한 XML이 만들어져 파라미터의 값으로 전달됨으로써 전과 동일한 결과가 발생할 수 있을지에 대해서도 고려해 보아야 한다. 그런데 이것은 대부분의 경우 바람직한 일이 아닐 수도 있는데 왜냐하면 표현계층으로부터 전달되는 데이터에 대한 비즈니스 로직의 수행은 그것이 데이터베이스에 저장되기 이전에 이루어져야 할 필요가 있기 때문이다.
if (action.equals("updatecontact")) {
String pk = request.getParameter("emailid");
String fname = request.getParameter("firstname");
String lname = request.getParameter("lastname");
String hname = request.getParameter("housename");
String sname = request.getParameter("streetname");
String cname = request.getParameter("cityname");
String phnumber = request.getParameter("phonenumber");

String finalString=""+fname
+" "+lname+""+
phnumber+""+hname+""+
sname+""+cname+"";

String sql="UPDATE DB2ADMIN.ADDRESSBOOK SET CONTACTINFO=""+ finalString+ "" WHERE EMAILID=""+pk +""";

stmt = connection.createStatement();
stmt.executeUpdate(sql);

out.print("success");
System.out.println("success");

}
예외사항이 잡히는 곳의 catch 블록은 XML 문자열에 등록되어 클라이언트로 전송된다. 예외사항에 대한 메시지는 노드에서 구할 수 있다.
} catch (Exception e) {
e.printStackTrace();
out.print("failure");
} finally {
System.out.println("executing finally ");
try {
System.out.println("Closing the statement and connection");
if(null!=rs){
rs.close();
}
if(null != pstmt){
pstmt.close();
}
connection.close();
System.out.println("closing the connection");
} catch (Exception e) {
System.out.println("There is exception in the finally block");
e.printStackTrace();
}
}
결론

이 기사에서는 DB2 Express-C 에디션, 오픈라즐로, 그리고 자바 기술을 사용하여 애플리케이션을 개발하는 방법에 대하여 설명하였으며 DB2 XQuery의 기능들을 매우 제한된 범위에서 알아보았다. 또한 계층화된 웹 애플리케이션에서 기대되는 것과 같은 뷰와 애플리케이션 코드간의 XML을 이용한 끊김없는(seamless) 통합뿐만 아니라 이상적인 100 퍼센트의 분리를 이루어 냈다. 뿐만 아니라 어떠한 상황에서도 변경되는 데이터만을 조작함으로써 사용자 행위에 대하여 시스템의 응답 속도를 높여주는 해결방안에 대해서도 알아보았다.

관련자료
  1. Software Engineer"s Guide to Developing OpenLaszlo Applications
  2. LZX Reference Manual
  3. IBM DB2 Database for Linux, Unix, and Windows information center
TAG :
댓글 입력
자료실

최근 본 책0