Article Category

분류 전체보기 (202)
사는 이야기 (15)
Programming (174)
Photo (5)
게임 (2)
프로젝트 (0)

Recent Comment

Recent Trackback

Calendar

«   2019/05   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Archive

  • Total96,493
  • Today0
  • Yesterday2
  1. 2008.08.06
    자바 개발자를 위한 Ajax: Ajax와 Direct Web Remoting
  2. 2008.08.06
    Rich Internet Applications의 기술 옵션

자바 개발자를 위한 Ajax: Ajax와 Direct Web Remoting

데이터 직렬화

 

 

 


 



난이도 : 중급

Philip McCarthy, Software development consultant, Independent

2006 년 10 월 17 일
2006 년 10 월 17 일 수정

Ajax 기능을 애플리케이션에 추가하기란 간단한 일이 아닙니다. 자바™ 개발자를 위한 Ajax 시리즈 세 번째 기사에서는 Direct Web Remoting (DWR)을 사용하여 JavaBeans 메소드를 JavaScript 코드에 직접 노출하고 Ajax를 자동화 하는 방법을 설명합니다.

Ajax 프로그래밍의 기초 (한글) 이해하는 것은 필수적인 일이지만, 복잡한 Ajax UI를 구현한다면, 고급 추상화 레벨에서 작업할 수 있어야 한다. Ajax for Java developers 시리즈 세 번째 글에서는 지난 달 소개했던 Ajax용 데이터 직렬화 기술 (한글)을 바탕으로, 자바 객체들을 직렬화 하는 문제를 단순화 하는 방법을 설명하겠다.

이전 글에서, JavaScript Object Notation (JSON)을 사용하여 클라이언트 상에서 JavaScript 객체로 쉽게 변환되는 포맷으로 데이터를 직렬화 하는 방법을 설명했다. 이 설정을 통해, JavaScript 코드를 사용하여 원격 서비스 호출을 호출하고, 원격 프로시저 호출과는 달리, 그에 대한 응답으로 JavaScript 객체 그래프를 받을 수 있다. 이번에는, 한 단계 더 나아가서 JavaScript 클라이언트 코드로부터, 서버 측 자바 객체에 대한 원격 프로시저 호출을 하는 기능을 규정하는 프레임웍을 사용해 보겠다.

DWR은 오픈 소스이며, 서버 측 자바 라이브러리, DWR 서블릿, JavaScript 라이브러리로 구성된 Apache 라이센스 솔루션이다. DWR이 자바 플랫폼에 사용할 수 있는 유일한 Ajax-RPC 툴킷은 아니지만, 가장 성숙하고, 많은 유용한 기능들을 제공하고 있다. 참고자료 섹션에서 DWR을 다운로드 하기 바란다.

DWR이란 무엇인가?

간단히 말해서, DWR은 서버 측 자바 객체의 메소드를 JavaScript 코드로 노출하는 엔진이다. DWR을 사용하여 애플리케이션 코드에서 Ajax 요청-응답 사이클 절차를 줄일 수 있다. 다시 말해서, 클라이언트 측 코드가 XMLHttpRequest 객체를 직접 다루거나 서버의 응답을 직접 다룰 필요가 없다는 것을 의미한다. 객체 직렬화 코드를 작성하거나 서드 파티 툴을 사용하여 객체를 XML로 전환할 필요가 없다. 서블릿 코드를 작성하여 Ajax 요청들을 자바 도메인 객체에 대한 호출로 중재할 필요도 없다.

DWR은 웹 애플리케이션에 서블릿으로서 전개된다. 블랙 박스처럼 보이는 이 서블릿은 두 가지 중요한 역할을 한다. 하나는, 각각 노출된 클래스에 대해, DWR은 JavaScript를 동적으로 생성하여 웹 페이지에 포함시킨다. 생성된 JavaScript에는 자바 클래스에 상응하는 메소드를 나타내는 스텁 함수가 포함되어 있고 막후에서 XMLHttpRequest도 수행한다. 이러한 요청들은 DWR 서블릿으로 보내지고, 요청들을 서버 측 자바 객체에 대한 메소드 호출로 변환하고, JavaScript로 인코딩 하여 메소드의 리턴 값을 다시 클라이언트로 보낸다. 이것이 두 번째 역할이다. DWR은 일반적인 UI 태스크를 수행하는 것을 돕는 JavaScript 유틸리티 함수도 제공한다.




위로


예제

DWR을 보다 자세히 설명하기 전에, 간단한 예제 시나리오를 소개하겠다. 이전 글에서와 마찬가지로, 온라인 스토어에 기반한 최소한의 모델을 사용하겠다. 이번에는 기본적인 제품 표현으로 구성된, 제품 아이템들을 포함시킬 수 있는 사용자의 쇼핑 카트와, 데이터 액세스 객체(DAO)를 사용하여 데이터 스토어에서 제품 상세를 검색한다. Item 클래스는 이전 글에서 사용했던 클래스이지만, 더 이상 수동 직렬화 메소드는 구현하지 않겠다. 그림 1은 설정 방법을 묘사한 것이다.


그림 1. Cart, CatalogDAO, Item 클래스를 나타내는 클래스 다이어그램

이 시나리오에서 두 개의 매우 간단한 유스 케이스를 설명하겠다. 첫 번째는 사용자가 카탈로그에서 텍스트 검색을 수행하고 매칭 아이템을 찾는 것이다. 두 번째는, 사용자가 아이템을 쇼핑 카트에 추가하고 카트에 있는 아이템들의 총 비용을 보는 것이다.




위로


카탈로그 구현하기

DWR 애플리케이션의 시작점은 서버 측 객체 모델을 작성하는 것이다. 이 경우, DAO를 작성하여 제품 카탈로그 데이터스토어에 검색 기능을 제공한다. CatalogDAO.java는 단순한 스테이트리스 클래스로서 인자 구조체가 없다. Listing 1은 Ajax 클라이언트로 노출 할 자바 메소드이다:


Listing 1. DWR을 통해 노출 할 CatalogDAO 메소드
				
/**
 * Returns a list of items in the catalog that have 
 *  names or descriptions matching the search expression
 * @param expression Text to search for in item names 
 *  and descriptions 
 * @return list of all matching items
 */
public List<Item> findItems(String expression);

/**
 * Returns the Item corresponding to a given Item ID
 * @param id The ID code of the item
 * @return the matching Item
 */
public Item getItem(String id);

다음에는, DWR을 설정하여, Ajax 클라이언트가 CatalogDAO를 구현하고 이러한 메소드를 호출하도록 할 것이다. Listing 2의 dwr.xml config 파일을 사용했다.


Listing 2. CatalogDAO 메소드를 노출하는 설정
				
<!DOCTYPE dwr PUBLIC
  "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
  "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
  <allow>
    <create creator="new" javascript="catalog">
      <param name="class" 
        value="developerworks.ajax.store.CatalogDAO"/>
      <include method="getItem"/> 
      <include method="findItems"/> 
    </create> 
    <convert converter="bean" 
      match="developerworks.ajax.store.Item">
      <param name="include" 
        value="id,name,description,formattedPrice"/>
    </convert>
  </allow>
</dwr>

dwr.xml 문서의 루트 엘리먼트는 dwr이다. 이 엘리먼트 안에는 allow 엘리먼트가 있는데, 이것은 DWR이 원격 조정할 클래스들을 지정한다. allow의 두 개의 자식 엘리먼트들은 createconvert이다.

Creat 엘리먼트

Create 엘리먼트는 DWR에게 서버 측 클래스가 Ajax 요청으로 노출되도록 명령하고, DWR이 그 클래스의 인스턴스를 얻는 방법을 정의한다. creator 애트리뷰트에는 new 값이 설정되고, 이는 DWR이 클래스의 디폴트 컨스트럭터를 호출하여 인스턴스를 얻어야 한다는 것을 의미한다. 다른 기능들은 Bean Scripting Framework (BSF)를 사용하여 스크립트 조각을 통해 인스턴스를 만들거나, IOC 컨테이너인 Spring과의 통합을 통해 인스턴스를 얻는 것이다. 기본적으로, DWR에 대한 Ajax 요청이 creator를 호출하면, 인스턴스화 된 객체가 페이지 범위에 놓이고, 요청이 완료된 후에는 더 이상 사용할 수 없다. 스테이트리스 CatalogDAO의 경우, 이것은 괜찮다.

Createjavascript 애트리뷰트는 JavaScript 코드에서 액세스 될 객체 이름을 지정한다. create 엘리먼트 내에 중첩된 param 엘리먼트는 creator가 만들 자바 클래스를 지정한다. 마지막으로, include 엘리먼트는 노출되어야 하는 메소드의 이름을 지정한다. 노출될 메소드를 명확히 드러내는 것은 잠재적으로 발생할 수 있는 위험들을 피하기에 좋다. 엘리먼트가 생략된다면 모든 클래스의 메소드들은 원격 호출에 노출될 것이다. exclude 엘리먼트를 사용하여 접근을 방지하고 싶은 메소드만 지정할 수 있다.

Convert 엘리먼트

creator가 클래스를 노출하는 것과, 웹 리모팅 방식과 연관이 있는 반면, convertor는 그러한 메소드의 매개변수와 리턴 유형과 연관이 있다. convert 엘리먼트의 역할은 서버 측 자바 객체 구현과 직렬화된 JavaScript 구현 사이에서 데이터 유형을 변환하는 방법을 DWR에게 명령하는 것이다.

DWR은 자바와 JavaScript 구현들 간 데이터 유형들을 자동으로 중재한다. 이 유형에는 자바 프리머티브와 각각의 클래스 구현, String과 Date, 어레이, 컬렉션 유형들이 포함된다. DWR은 또한 JavaBeans를 JavaScript 구현으로 변환하고, 보안 때문에, 명확한 설정이 필요하다.

Listing 2convert 엘리먼트는 DWR에게 리플렉션 기반 빈 convertor를 CatalogDAO의 노출된 메소드에 의해 리턴된 Item에 사용하고 직렬화에 포함될 Item의 멤버를 지정한다. 멤버들은 JavaBean 네이밍 규약을 사용하여 지정되어, DWR은 상응하는 get 메소드를 호출할 것이다. 이 경우, 숫자 price 필드를 생략하고, 대신 통화로 포맷된 formattedPrice 필드를 포함시켰다.

이 시점에서, dwr.xml을 나의 웹 애플리케이션의 WEB-INF 디렉토리에 전개할 준비가 되고, 이 곳에서 DWR 서블릿이 집어낸다. 진행하기 전에, 모든 것이 생각한 대로 잘 작동하는지를 확인해보는 것이 좋다.




위로


전개 테스팅

DWRServletweb.xml 정의에서 init-param debugtrue로 설정했다면 DWR의 가장 유용한 테스트 모드가 실행된 것이다. /{your-web-app}/dwr/을 검색하면 DWR이 설정했던 클래스 리스트가 나타날 것이다. 해당 클래스에 대해 상태 스크린을 클릭한다. CatalogDAO용 DWR 테스트 페이지는 그림 2에 나타나 있다. script 태그를 웹 페이지에 붙일 뿐만 아니라, 클래스용으로 생성된 DWR의 JavaScript를 가리키면서, 이 스크린 역시 클래스의 메소드 리스트를 제공한다. 이 리스트에는 클래스의 상위 유형에서 상속된 메소드가 포함되어 있고, dwr.xml에서 원격용으로 명확하게 지정한 메소드도 액세스 가능한 것으로 표시된다.


그림 2. CatalogDAO용 DWR 테스트 페이지
The diagnostic and test page generated by DWR for CatalogDAO

매개변수 값을 액세스 가능한 메소드 옆 텍스트 박스에 입력하고 Execute 버튼을 눌러 이들을 호출할 수 있다. 단순한 값이 아니라면, 서버의 응답은 경고 박스에 JSON 공지를 사용하여 디스플레이 될 것이다. 이 경우 메소드를 따라서 한 줄로 디스플레이 된다. 이러한 테스트 페이지들은 매우 유용하다. 어떤 클래스와 메소드가 원격으로 노출되어있는지 쉽게 검사할 수 있고 각 메소드가 기대한 대로 작동하는지를 테스트 할 수 있다.

일단 원격 메소드가 올바르게 실행되었다면 DWR의 JavaScript 스텁을 사용하여 클라이언트 측 코드에서 서버 측 객체들을 호출할 수 있다.




위로


원격 객체 호출하기

원격 자바 객체 메소드와 이에 상응하는 JavaScript 스텁 함수들간 매핑은 간단하다. 일반적인 폼은 JavaScriptName.methodName(methodParams ..., callBack)인데, 여기에서 JavaScriptNamecreatorjavascript 애트리뷰트로 지정된 이름이고, methodParams는 자바 메소드의 n 매개변수이며, callback은 자바 메소드의 리턴 값과 함께 호출 될 JavaScript 함수이다. Ajax를 잘 알고 있다면 이 콜백 메커니즘이 XMLHttpRequest의 비동기화에 유용한 접근 방식이라는 것을 알 수 있을 것이다.

예제 시나리오에서, Listing 3의 JavaScript 함수를 사용하여 검색 결과로 UI를 검색 및 업데이트 한다. 이 리스팅은 DWR의 util.js에서 편리한 함수를 사용한다. $()라는 JavaScript 함수에 주목하라. 이것은 document.getElementById()의 다른 버전이라고 생각하면 된다. 타이핑 하기 쉽다. 프로토타입 JavaScript 라이브러리를 사용했다면, 이 함수가 익숙할 것이다.


Listing 3. 클라이언트에서 원격 findItems() 메소드 호출하기
				
/*
 * Handles submission of the search form
 */
function searchFormSubmitHandler() {

  // Obtain the search expression from the search field
  var searchexp = $("searchbox").value;

  // Call remoted DAO method, and specify callback function
  catalog.findItems(searchexp, displayItems);

  // Return false to suppress form submission
  return false;
}
       
/*
 * Displays a list of catalog items
 */
function displayItems(items) {

  // Remove the currently displayed search results
  DWRUtil.removeAllRows("items");

  if (items.length == 0) {
    alert("No matching products found");
    $("catalog").style.visibility = "hidden";
  } else {

    DWRUtil.addRows("items",items,cellFunctions);
    $("catalog").style.visibility = "visible";
  }
}

searchFormSubmitHandler() 함수에서, 재미있는 코드는 무엇보다도 catalog.findItems(searchexp, displayItems);이다. 이 한 줄의 코드는 네트워크를 통해 XMLHttpRequest를 DWR 서블릿으로 보내고 원격 객체의 응답과 함께 displayItems() 함수를 호출할 때 필요하다.

displayItems() 콜백 그 자체는 Item의 어레이와 함께 호출된다. 이 어레이는 DWRUtil.addRows() 함수로 전달되고, 전개할 테이블의 아이디와 함수의 어레이가 함께 전달된다. 각 테이블 행(row)에는 셀들이 있기 때문에 이 어레이에는 많은 함수들이 있다. 각 함수는 어레이에서 Item과 함께 호출되고 상응하는 셀에 전개될 콘텐트를 리턴해야 한다.

이 경우, 이 아이템 테이블의 각 행이 아이템의 이름, 디스크립션, 가격은 물론, 마지막 칼럼에는 아이템용 Add to Cart 버튼을 디스플레이 하도록 해야 한다. Listing 4는 이를 수행하는 셀 함수 어레이 모습이다.


Listing 4. 아이템 테이블을 전개하는 셀 함수 어레이
				
/*
 * Array of functions to populate a row of the items table
 * using DWRUtil's addRows function
 */
var cellFunctions = [
  function(item) { return item.name; },
  function(item) { return item.description; },
  function(item) { return item.formattedPrice; },
  function(item) {
    var btn = document.createElement("button");
    btn.innerHTML = "Add to cart";
    btn.itemId = item.id;
    btn.onclick = addToCartButtonHandler;
    return btn;
  }
];

처음 세 개의 함수들은 dwr.xml의 Itemconvertor에 포함된 필드의 콘텐트를 리턴한다. 마지막 함수는 버튼을 만들고, Item의 아이디를 여기에 붙이고, addToCartButtonHandler 함수가 버튼이 클릭될 때 호출되도록 지정한다. 이 함수는 두 번째 유스 케이스에 대한 엔트리 포인트이다. Item을 쇼핑 카트에 추가한다.




위로


쇼핑 카트 구현하기

DWR의 보안

DWR은 보안도 염두 해 두었다. dwr.xml을 사용하여 원격화 할 클래스와 메소드만 리스팅하면 악용될 수 있는 기능의 노출을 피할 수 있다. 게다가, 디버그 Test Mode를 사용하면 웹에 노출된 모든 클래스와 메소드를 검사할 수 있다.

DWR은 또한 역할 기반 보안을 지원한다. creator 설정을 통해 특정 빈에 액세스 하기 위해 사용자가 갖춰야 하는 J2EE 역할을 지정할 수 있다. URL 보안이 된 DWRServlet 인스턴스와 dwr.xml config 파일을 전개하여 다양한 사용자들에게 다양한 원격 기능들을 제공할 수 있다.

사용자 쇼핑 카트의 자바 구현은 Map에 기반하고 있다. Item이 카트에 추가될 때, Item은 키로서 Map으로 삽입된다. 그 Map에서 상응하는 값은 카트에 있는 Item의 양을 나타내는 Integer이다. 따라서 Cart.javaMap<Item,Integer>로 선언된 contents라는 필드를 갖고 있다.

해시(hash) 키로서 복합 유형을 사용하면 DWR에 문제가 생긴다. JavaScript에서, 어레이 키는 리터럴이어야 한다. 결과적으로, contents Map은 DWR에 의해 그 자체로 변환될 수 없다. 하지만, 쇼핑 카트 UI의 목적 상, 모든 사용자는 카트에 있는 각 아이템의 이름과 양을 봐야 한다. 따라서 getSimpleContents() 메소드를 Cart에 추가하여, contents Map을 취해 단순화된 Map<String,Integer>를 구현하여, 각 Item의 이름과 양만 나타내도록 하였다. 이러한 스트링 키 map 구현은 DWR의 빌트인 컨버터에 의해서 JavaScript로 변환될 수 있다.

클라이언트가 관심을 갖고 있는 Cart의 다른 필드는 totalPrice이다. 이것은 쇼핑 카트에 있는 모든 것의 총합을 나타낸다. Item과 마찬가지로, 숫자로 된 총합을 사전 포맷 된 String으로 나타낸 formattedTotalPrice을 제공했다.

카트 변환하기

콘텐트를 얻기 위해서 그리고 최종 가격을 알기 위해, 클라이언트 코드가 Cart로 두 번의 호출을 하도록 하는 대신, 이 모든 데이터를 클라이언트로 한번에 보낸다. 이를 위해서, 이상하게 보이는 메소드를 추가했다. (Listing 5):


Listing 5. Cart.getCart() 메소드
				
/**
 * Returns the cart itself - for DWR
 * @return the cart
 */ 
public Cart getCart() {
  return this;
}

이 메소드는 정상적인 자바 코드에서는 과잉이지만(메소드를 호출하면 Cart에 대한 참조가 이미 존재한다.) DWR 클라이언트가 Cart가 스스로를 JavaScript로 직렬화 시킬 수 있도록 한다.

getCart() 외에, 원격화 될 다른 메소드는 addItemToCart()이다. 이 메소드는 카탈로그 아이템의 아이디의 String 구현을 취해서, 이 아이템을 Cart에 추가하고, 총 합을 업데이트 한다. 이 메소드는 또한 Cart를 리턴하여, 클라이언트 코드가 Cart 콘텐트를 업데이트 하고 하나의 연산으로 새로운 상태를 받을 수 있다.

Listing 6은 확장된 dwr.xml config 파일로서, Cart 클래스를 원격화 하는데 필요한 여분의 config 정보가 포함되어 있다:


Listing 6. Cart 클래스를 통합하는 변경된 dwr.xml
				
<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
    "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
  <allow>
    <create creator="new" javascript="catalog">
      <param name="class" 
        value="developerworks.ajax.store.CatalogDAO"/>
      <include method="getItem"/>
      <include method="findItems"/>
    </create>
    <convert converter="bean" 
      match="developerworks.ajax.store.Item">
      <param name="include" 
        value="id,name,description,formattedPrice"/>
    </convert>
    <create creator="new" scope="session" javascript="Cart">
      <param name="class" 
        value="developerworks.ajax.store.Cart"/>
      <include method="addItemToCart"/>
      <include method="getCart"/>
    </create>
    <convert converter="bean" 
      match="developerworks.ajax.store.Cart">
      <param name="include" 
        value="simpleContents,formattedTotalPrice"/>
    </convert>
  </allow>
</dwr>

이 버전의 dwr.xml에서, Cartcreatorconvertor를 추가했다. create 엘리먼트는 addItemToCart()getCart() 메소드가 원격화 되고, 생성된 Cart 인스턴트가 사용자 세션에 놓이도록 지정한다. 결과적으로, 카트의 콘텐트는 사용자 요청 사이에 되풀이 된다.

Cartconvert 엘리먼트는 원격 Cart 메소드가 Cart 자체를 리턴하기 때문에 필요하다. 직렬화 된 JavaScript에 나타나야 하는 Cart의 멤버는 simpleContents 맵과 formattedTotalPrice 스트링이다.

약간 혼란스럽다면, create 엘리먼트는 DWR 클라이언트에 의해 호출될 수 있는 Cart에 대한 서버 측 메소드를 지정하고, convert 엘리먼트는 Cart의 JavaScript 직렬화에 포함될 멤버를 지정한다는 것을 기억하면 된다.

이제, 원격 Cart 메소드를 호출하는 클라이언트 측 코드를 구현할 수 있다.




위로


원격 Cart 메소드 호출하기

무엇보다도, 스토어 웹 페이지가 처음 로딩되면, 세션에 저장된 Cart의 상태를 검사하고 싶다. 사용자가 아이템들을 Cart에 추가하고 페이지를 리프레쉬 하거나 다시 검색할 수 있기 때문에 이는 필요하다. 이러한 상황에서, 재 로딩된 페이지는 세션에서 Cart 데이터와 연결되어야 한다. 나는 이 페이지의 함수에 수행된 호출을 사용했다: Cart.getCart(displayCart). displayCart()는 서버에서 Cart 응답 데이터와 함께 호출된 콜백 함수이다.

Cart가 이미 세션에 있다면 creator는 이를 가져오고 이것의 getCart() 메소드를 호출할 것이다. 어떤 Cart도 세션에 없다면 creator는 새로운 것을 인스턴스화 하여, 이것을 세션에 두고, getCart() 메소드를 호출한다.

Listing 7은 아이템의 Add to Cart 버튼이 클릭될 때 호출되는 addToCartButtonHandler() 함수의 구현 모습이다:


Listing 7. addToCartButtonHandler() 구현
				
/*
 * Handles a click on an Item's "Add to Cart" button
 */
function addToCartButtonHandler() {

  // 'this' is the button that was clicked.
  // Obtain the item ID that was set on it, and
  // add to the cart.
  Cart.addItemToCart(this.itemId,displayCart);
}

모든 통신을 책임지고 있는 DWR을 사용하여 클라이언트에서의 카트에 추가하기 작동은 문자 그대로 한 줄의 함수이다. Listing 8은 최종 가격이다. Cart의 상태로 UI를 업데이트 하는 displayCart() 콜백의 구현이다:


Listing 8. displayCart() 구현
				
/*
 * Displays the contents of the user's shopping cart
 */
function displayCart(cart) {

  // Clear existing content of cart UI
  var contentsUL = $("contents");
  contentsUL.innerHTML="";

  // Loop over cart items
  for (var item in cart.simpleContents) {

    // Add a list element with the name and quantity of item
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(
                    cart.simpleContents[item] + " x " + item
                  ));
    contentsUL.appendChild(li);
  }

  // Update cart total
  var totalSpan = $("totalprice");
  totalSpan.innerHTML = cart.formattedTotalPrice;
}

simpleContentsString을 숫자로 매핑하는 JavaScript 어레이라는 것을 기억하라. 각 스트링은 아이템의 이름이고, 연관 어레이의 상응하는 숫자는 카트에 있는 아이템의 수량이다. 따라서 cart.simpleContents[item] + " x " + item 식은 "2 x Oolong 128MB CF Card"로 계산된다.

DWR Store 애플리케이션

그림 3은 DWR 기반의 Ajax 애플리케이션 실행 모습이다. 오른쪽에 사용자 쇼핑 카트와 검색된 아이템들을 디스플레이 하고 있다:


그림 3. DWR 기반의 Ajax 스토어 애플리케이션 실행 모습
Screenshot of example scenario, with search results and shopping cart



위로


DWR의 장단점

함수의 일괄처리

DWR에서, 여러 원격 호출이 하나의 HTTP 요청과 함께 서버로 보내질 수 있다. DWREngine.beginBatch()를 호출하면 DWR에게 후속 원격 호출들을 바로 보내지 말라고 명령하는 것이다. 이들을 하나의 일괄 요청으로 묶지 않는다. DWREngine.endBatch()을 호출하면, 일괄 요청이 서버로 보내진다. 원격 호출은 서버 측에서 순서대로 실행되고, 각 JavaScript 콜백이 실행된다.

일괄 작업은 두 가지 방식으로 레이턴시를 줄일 수 있다. 우선, XMLHttpRequest 객체를 만들고, 각 호출에 대해 HTTP 연결을 만드는 오버헤드를 피할 수 있다. 또한, 실행 환경에서, 웹 서버는 많은 동시 HTTP 요청들을 다룰 필요가 없기 때문에 응답 시간이 빨라진다.

DWR을 사용하여 Ajax 애플리케이션을 구현하기가 얼마나 쉬운지를 배웠다. 이 샘플 시나리오는 단순하고 유스 케이스를 구현하는데 매우 단순한 접근 방식을 취했지만, DWR의 역할을 과소 평가해서는 안된다. 이전 글에서, Ajax 요청과 응답을 직접 설정하고 자바 객체 그래프를 JSON으로 변환하는 과정을 설명했지만, 여기에서는 DWR이 이 모든 작업을 수행했다. 나는 50줄 미만의 JavaScript를 작성하여 클라이언트를 구현했고, 서버 측에서도 내가 했던 일은, 나의 JavaBean에 두 개의 추가 메소드만 추가했을 뿐이다.

물론, 모든 기술에는 단점도 있기 마련이다. RPC 메커니즘과 마찬가지로, DWR에서도 원격 객체로 하는 호출이 로컬 함수 호출보다 훨씬 더 비싸다는 것을 쉽게 잊는다. DWR은 Ajax를 숨기는 일은 잘 하지만, 네트워크는 투명하지 않다는 것을 기억해야 한다. DWR 호출에는 레이턴시가 있고, 애플리케이션은 대단위 원격 메소드가 되도록 설계되어야 한다. 이러한 이유로 addItemToCart()Cart 자체를 리턴한다. addItemToCart()를 유효 메소드로 만드는 것이 더 자연스럽지만, 각 DWR 호출 다음에는 getCart()가 호출되어 변경된 Cart 상태를 검색한다.

DWR은 호출 일괄처리 시 레이턴시 문제에 대한 자체 해결책을 갖고 있다. (함수 일괄처리 사이드 바 참조) 애플리케이션에 맞는 대단위 Ajax 인터페이스를 줄 수 없다면 호출 일괄처리를 사용하여 여러 원격 호출들을 하나의 HTTP 요청으로 묶는다.

영역의 분리

본질상, DWR은 클라이언트 측과 서버 측 코드간 강결합을 만든다. 우선, 원격 메소드의 API 변경은 DWR 스텁을 호출하는 JavaScript로 반영되어야 한다. 두 번째(더 중요한 것은), 이 커플링이 클라이언트 측 영역이 서버 측 코드로 누수 되어야 한다. 예를 들어, 모든 자바 유형들이 JavaScript로 변환될 수 있는 것은 아니기 때문에 자바 객체에 추가 메소드를 추가하여 보다 쉽게 원격화 될 수 있도록 한다. 예제 시나리오에서, CartgetSimpleContents() 메소드를 추가하여 이 문제를 해결했다. 또한 getCart() 메소드를 추가했는데, 이것은 DWR 시나리오에서는 유용하지만 완전한 과잉이다. 원격 객체에 대한 대단위 API가 필요하고, 특정 자바 유형을 JavaScript로 변환하는 문제 때문에, 원격화된 JavaBean이 Ajax 클라이언트에만 유용한 메소드로 인해 어떻게 오염되는지를 볼 수 있다.

이를 해결하기 위해, 래퍼 클래스를 사용하여 여분의 DWR 스팩의 메소드를 JavaBean에 추가한다. JavaBean 클래스의 자바 클라이언트는 원격화와 관련된 과잉이 더 이상 없고, 원격화된 메소드에 보다 친숙한 이름을 줄 수 있다. 예를 들어, getFormattedPrice() 대신 getPrice()로 한다. 그림 4는 Cart를 래핑하여 여분의 DWR 기능을 추가하는 RemoteCart 클래스 모습이다:


그림 4. 원격 기능을 위해 Cart를 래핑하는 RemoteCart
Class diagram of RemoteCart wrapper class

마지막으로, DWR Ajax 호출은 비동기식이고, 이들이 파견된 순서대로 리턴 되리라고 기대해서는 안된다. 예제 코드에서 작은 문제를 무시했지만, 이 시리즈의 첫 번째 글에서는 순서 없이 도착하는 데이터에 대한 방어책으로서 응답에 타임스탬프를 실행하는 방법을 설명했다.




위로


맺음말

DWR은 많은 기능을 한다. 서버 측 도메인 객체에 대한 인터페이스를 빠르고 간단하게 만든다. 서블릿 코드, 객체 직렬화 코드, 클라이언트-측 XMLHttpRequest 코드를 작성할 필요가 없다. DWR을 사용하면 웹 애플리케이션으로의 전개도 매우 간단하고, DWR의 보안 기능은 J2EE 역할 기반 인증 시스템과 통합될 수 있다. DWR이 모든 애플리케이션 아키텍처에 적용되는 것은 아니지만 도메인 객체의 API 디자인에 고려해볼 만한 가치가 있다.

Ajax와 DWR의 장단점에 대해 보다 자세히 알고 싶다면 직접 다운로드 하여 시험해 보기 바란다. 여기에서 미처 다루지 못한 DWR의 많은 기능들이 있지만, 이 글에 소개된 소스 코드는 DWR을 시작할 수 있는 좋은 출발점이 된다. 참고자료 섹션에는 Ajax, DWR, 관련 기술들이 보다 자세하게 설명되어 있다.

가장 중요한 포인트는 Ajax 애플리케이션에는 정해진 하나의 솔루션이 없다는 것이다. Ajax는 새로운 기술들을 사용하는 개발 분야이다. 이 시리즈를 통해서 Ajax 애플리케이션의 웹 티어에서 자바 기술을 활용하는 방법에 초점을 맞췄다. XMLHttpRequest-기반 방식에 객체 직렬화 프레임웍을 선택하든, 아니면 DWR의 고급 추상화를 사용했든 상관은 없다. 다음 달, Ajax for Java developers 시리즈를 기대해주기 바란다.

기사의 원문보기





위로


다운로드 하십시오

설명 이름 크기 다운로드 방식
DWR source code j-ajax3dwr.zip 301 KB  FTP
다운로드 방식에 대한 정보


참고자료

교육

제품 및 기술 얻기

토론


필자소개

Philip McCarthy는 자바와 웹 기술 전문 소프트웨어 개발 컨설턴트이다. 현재는 Hewlett Packard 연구소와 Orange에서 디지털 미디어 및 텔레콤 프로젝트에 참여하고 있으며, City of London에서 금융 소프트웨어 관련 작업을 하고 있다. philmccarthy@gmail.com

Trackback 0 and Comment 0

Rich Internet Applications의 기술 옵션

기본 브라우저를 넘어서

 

 

 




난이도 : 초급

Mr. Vaibhav V. Gadge, Software Engineer, IBM 

2006 년 9 월 11 일

웹 애플리케이션들은 다음 단계로 진화해야 하고, Rich Internet Applications (RIA)는 사용자 인터랙션을 상당히 향상시킬 수 있습니다. 이 글에서는 사용자 인터페이스(UI) 레이어에 RIA를 적용하는 방법을 설명합니다. 웹 개발자와 아키텍트라면 현재 이 분야에서 사용되는 기술인 Laszlo, XUL, XForms, Macromedia Flex, Dojo에 관심이 있을 것입니다. 아울러 다른 기술도 소개해 드립니다. 물론 HTML과 XML 같은 전통적인 UI 툴에 대한 이해가 필수입니다.

Rich Internet Applications (RIA)는 HTML에서 제공하는 기존의 사용자 인터페이스(UI) 컨트롤(텍스트 박스, 체크박스, 라디오 버튼)로 제한된 표준을 넘어서고 있다. RIA는 보다 풍부한 컨트롤 세트와 고급 서버 인터랙션 메커니즘을 제공한다. RIA를 사용하면 브라우저에서 데이터를 보낼 때 페이지를 리프레쉬 할 필요가 없다. 페이지의 일부만 리프레쉬 할 수 있고 더 나은 에러 핸들링 기능을 갖추고 있다.

이 글의 내용:

RIA 개요

"Rich Internet Application"이란 용어는 몇 년 전부터 사용되었으며 개념은 다음과 같이 알려져 있다.:

  • 원격 스크립팅
  • X Internet
  • 리치 (웹) 클라이언트(Rich (Web) clients)
  • 리치 웹 애플리케이션(Rich Web application)

인터넷은 거대한 정보의 보고이며, 웹 상에서의 정보 전달과 스토리지 퍼포먼스를 높이기 위해 많은 기술들이 생겨나고 있다. 대부분의 웹 애플리케이션에서 상당히 많은 프로세싱이 서버 측에서 발생하고 클라이언트 측에서는 단순한 사용자 인터랙션만 발생한다. 이는 결국 서버에 많은 데이터와 프로세싱 부하로 부담을 주게 되고 네트워크 트래핑에 대한 의존성만 점점 커지게 된다.

옛날 클라이언트-서버 기반 아키텍처는 매우 유연하고 풍부했지만 Web 시절에 사장되었다. 한 가지 이유는 클라이언트 애플리케이션의 표준화가 부족했기 때문이었다. 이제, 브라우저는 보편적으로 채택되는 웹 툴이 되었다. 하지만 지능적인 프로세싱이 부족하다. 따라서 풍부한 사용자 경험을 제공할 수 있는 클라이언트 애플리케이션에 부담이 생기고 클라이언트 측에 간단한 프로세싱을 수행하게 되었다. RIA는 더 빠르고 가용성 있는 사용자 경험을 디자인 할 기회를 브라우저 내에서 제공한다.

웹과 인터넷 UI 레이어에서 작업하는 개발자들은 UI 레이어 상에서 최소한의 외부 지원으로 효과적으로 작업할 수 있는 다양한 RIA 툴을 실험하고 있다. 대부분의 경우, 브라우저는 플러그인, 확장, 다운로드의 관점에서 지원을 받아야지만 완벽하게 작동할 수 있다.

이 글에서는 비즈니스 케이스에 가장 적합한 RIA를 규명하는 툴과 매개변수를 설명하겠다. RIA의 모든 요소들을 설명할 수 없기 때문에 몇 가지 중요한 기능들만 집중적으로 설명하겠다.

평가 요소

RIA 기술을 평가할 때 다음 요소들을 고려해야 한다:

UI의 풍부함 정도
UI를 개발할 때 기본적인 UI 위젯이나 컨트롤이 어느 정도 있는가? 이러한 컨트롤을 가지고 데이터 바인딩과 이벤트 바인딩을 어떻게 수행 할 것인가? 새로운 컨트롤은 사용하기 쉽고 쉽게 플러그인 되어야 하다. 몇몇 RIA 기술에는 애니메이션 API를 페이지에 추가하는 등 풍부함과 더 많은 정보를 추가하는 간단한 방식이 있다. 예를 들어, 사용자가 버튼을 단 한번만 클릭하도록 버튼을 움직이게 할 수 있다.
복잡성
개발자들은 많은 세월 동안 기존 페이지 기반 모델을 사용해 왔다. 쉽고 단순하다는 이유에서였다. 하지만 보이는 모습은 형편없다. RIA 기술은 배우기도 쉽고 구현 및 확장하기도 쉬워야 한다. 기존 웹 기술과 운용성도 있어야 한다.
유연성과 컴포넌트화
다양한 미들웨어 컴포넌트와 협업할 수 있는 유연성은 중요한 것이다. 협업은 쉽게 구성 및 확장되어 새로운 커스터마이징 위젯을 만들 수 있어야 한다. 일단 커스텀 위젯의 라이브러리를 만들면 이들을 애플리케이션에서 재사용 할 수 있다.
페이지 리프레쉬

전체 페이지 대신 페이지 블록을 리프레쉬 하면 매우 큰 효과가 있다. 블록을 리프레쉬 하면 애플리케이션이 더욱 빨라지고, 가용성도 높아지며, 시각적인 효과도 더 좋아진다. 에러를 더욱 잘 관리할 수 있다.

사용자가 웹 페이지에서 액션이나 첫 번째 태스크를 수행한다면 데이터는 백그라운드에 있는 서버로 간다. 사용자는 같은 페이지에서 또 다른 태스크를 시작한다. 그 동안, 첫 번째 태스크에서 온 피드백이 같은 페이지의 몇 부분을 업데이트 한다. 따라서 이와 같은 방식으로 웹 페이지를 디자인 한다면 작업 효율성이 높아질 것이다.

보안
RIA를 적용할 때 기존 애플리케이션과 비교하여 보안 위협은 없는지를 확인한다. 서버 통신과 관련한 보안, 클라이언트에서 다운로드 된 브라우저 플러그인과 확장을 주목하라.
기본적인 웹 패러다임 지원
이 기술은 오늘날 웹 애플리케이션에서 진화하고 있는 기본적인 웹 패러다임-사용자 장치 독립, 브라우저 독립, 업로드와 다운로드에 바이너리 파일 전송 지원-을 지원해야 한다. 기술의 성숙도도 문제가 된다.
툴링
단위 테스팅과 디버깅 지원을 사용하여 통합 개발 환경(IDE)에서 개발자들이 사용할 수 있는 툴링을 검토하라. 툴링은 기존 에디터나 지원 에디터를 갖춘 플러그인이 될 수 있다.
가용성
사용자는 브라우저 애플리케이션이 보통의 브라우저 기능들과 함께 작동하는 것을 기대한다. 특히 이미지 저장하기 기능, 페이지의 내용을 찾는 Ctrl+F, 카피& 페이스트는 FLASH 기반 솔루션에서는 작동하지 않는다. RIA 디자인의 기본을 인간과 사용자 인터랙션 (HCI) 원리에 맞춰라.



위로


UI 기술

이 섹션에서는 현재 UI 기술에서 제공되는 다양한 옵션들을 검토해 본다.

Laszlo

Laszlo는 FLASH를 사용하여 웹 상에서 RIA의 개발과 딜리버리를 위한 오픈 소스 플랫폼이다. FLASH 플레이어는 처음에는 브라우저 내에서 FLASH 파일을 실행하는 작은 플러그인으로 시작되었다. 높은 신뢰성과 호환성 덕택에 FLASH와 애니메이션 이미지를 만드는데도 사용되고 있다. 후기 버전에는 중요한 스크립팅 호환성, 서버와 데이터 교환, 양방향 오디오와 비디오 통신을 추가하는 Flash 6를 추가했다.

Laszlo는 그 풍부함을 확장했고, FLASH를 생성하여 브라우저에 전달하는 스크립팅 언어를 사용했다. 이것은 RIA를 구현할 때 오픈 소스 XML 플랫폼을 제공한다.

XPath란?
XML Path Language는 W3C가 권고한 언어로서 XML 문서에 있는 정보를 다룬다. XPath의 기본 목적은 XML 문서의 어떤 노드나 애트리뷰트를 통한 검색이다.

브라우저에 Flash 5.x+만 설치되어 있으면 된다. 스크립트는 LZX라고 하는 XML 기반 언어로 작성된다. LZX는 객체 지향의 태그 기반 언어로서 XML과 JavaScript 신택스를 사용하여 FLASH 파일들을 만든다. 서버에 있는 LZX 컴파일러는 LZX 파일을 컴파일 하고 FLASH 파일을 브라우저에 보낸다. 실제 데이터 교환은 XML 폼으로 이루어지고 LZX 컨트롤은 XPath를 사용하여 XML을 참조한다. 이벤트 역시 컨트롤과 바인딩 하기 쉽다. 각 컨트롤은 부모로부터 이벤트를 상속받을 수 있는 이벤트 세트를 정의한다. Listing 1의 예제는 이벤트를 사용하는 방법이다.


Listing 1. simplelaszlo.lzx 예제
                

<canvas width="500" height="80">

<view>

     <text align="center" valign="middle">Hello, World!</text>

     <button >Update

<method event="onclick">

 Debug.write("Button pressed");

</met>

</button>

</view>

</canvas>

Laszlo는 배우기 쉽고, 새로운 컴포넌트를 개발하고, 컴포넌트를 만들며, 어떤 웹 애플리케이션과도 통합된다. 기타 RIA 툴과 비교해 볼 때 풍부한 컴포넌트 라이브러리를 갖추고 있다.

LZX는 HTTP와 웹 서비스 요청을 SOAP과 RPC 프로토콜과 함께 페이지를 리프레쉬 하지 않고 백그라운드에 있는 서버로 요청을 하는 기능이 있다. 플러그인이 이미 있어서 웹 애플리케이션 파일과 Laszlo 라이브러리를 통합한다. 현재, Eclipse 기반 IDE를 개발에 사용할 수 있다. 클라이언트 측에서 LZX의 디버깅에 사용할 수 있는 툴링이 있다. 재미있게도 이들은 Laszlo 애플리케이션을 테스트 하는 Lzunit 프레임웍을 제공한다.

현재 Laszlo는 브라우저에 있는 애플리케이션을 같은 기존 프레임웍을 사용하여 DHTML로서 전달하는 것을 지원한다고 발표했다. 애플리케이션을 DHTML로 전달할지 아니면 FLASH로 전달할지를 설정할 수 있게 되었다. Laszlo는 Ajax 커뮤니티와 다중 사용자 장치 딜리버리로도 지원을 확장했다.

그림 1은 Laszlo와 Dojo 예제이다.


그림 1. Laszlo와 Dojo로 만들어진 RIA 이미지
Laszlo, Dojo demo images

XUL

XML user-interface language (XUL)는 Mozilla의 XML 기반, 크로스 플랫폼 언어로서 애플리케이션의 사용자 인터페이스를 기술한다. 이미 만들어진 컴포넌트의 풍부한 라이브러리를 페이지에 사용할 수 있도록 제공한다. 현재 Mozilla Firefox나 Netscape 6 이후 버전 같은 Gecko 기반 브라우저 상에서만 작동한다.

XUL은 XML 기반 마크업 언어를 사용하여 사용자 인터페이스 컨트롤을 기술한다. 메뉴, 탭, 트리, 팝업 메뉴 같은 모든 종류의 인터넷 컨트롤을 제공한다. XUL은 문서 객체 모델(DOM)을 사용하여 노드의 트리를 저장한다. 모든 XUL 파일이 로딩되면 XUL은 노드의 계층적 문서 구조에 있는 모든 태그들을 파싱 및 변환한다. DOM 구조를 사용하여 고유 메소드와 XUL 함수에서 제공되는 추가 메소드들을 사용하여 데이터를 검사 및 변경할 수 있다. JavaScript에서 DOM에 액세스 하여 조작할 수 있고 전형적인 HTML 컨트롤 처럼 이것을 핸들 할 수 있다. 각 컨트롤과 각 노드는 모양과 구조를 정의한 여러 애트리뷰트를 갖고 있다.

브라우저는 원격 위치에서 액세스 될 때 XUL 파일들을 HTML이나 다른 브라우저와 비슷하게 핸들한다. 하지만 확장으로서 크롬 시스템에 있는 브라우저에 로컬로 설치될 때 로컬 시스템과 북마크에 접근할 수 있는 특별한 권한을 받는다. 이 경우 부가적인 권한 작동을 수행할 수 있다.

Mozilla 브라우저는 XUL 파일, JavaScript, 스타일시트를 포함하고 있는 패키지 세트이다. 비록 이것은 훨씬 더 크고 복잡한 확장이다.

XUL은 바인딩에 eXtensible Bindings Language (XBL)를 사용한다. 각 컨트롤은 Mozilla의 XBL을 사용하여 바인드 될 수 있다. XUL은 RDF 포맷을 사용하는데, 주로 리소스를 저장한다. 다른 포맷으로 데이터를 사용하여 여기에서 RDF 데이터를 만들 수 있다. 이것은 XUL 엘리먼트로 바인딩 된다.

XUL은 XML 파일과 같기 때문에 IDE에 텍스트 에디터나 XML 에디터를 사용할 수 있다. 같은 기반 코드가 모든 XUL 파일, HTML, SVG를 핸들하기 때문에, 여러분은 CSS 속성을 사용하여 XUL 파일을 스타일링 할 수 있다. 모든 텍스트 콘텐트가 브라우저에서 개별적으로 저장될 때 로컬화도 지원한다.

Mozilla에서 CSS 파일들로 구성된 Skins는 브라우저의 사용자 인터페이스를 정의한다. 코드를 변경하지 않고 다른 모양으로 스킨을 변경 및 생성할 수 있다. 기능을 추가하여 브라우저 API의 힘을 늘리는 것과 비슷하다.

Mozilla Firefox 에서 Listing 2에 있는 파일을 실행하면 텍스트 박스와 버튼을 렌더링 한다.


Listing 2. simplexul.xul 예제
                

<?xml version="1.0"?>

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window id="example-window" title="Example 2.4.1"

        xmlns:html="http://www.w3.org/1999/xhtml"

        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<label control="label" value="Enter some text"/>

<textbox id="textid"/>

<button id="yes" label="Yes"/>

</window>

XForms

XForms 1.0은 온라인 인터랙션을 위해 새로운 플랫폼 독립적인 마크업 언어를 제공한다. W3C는 XForms를 구현하는 스팩을 만들었고, 이를 HTML 폼의 후계자로 간주하고 있다.

XForms는 표현 장치에 독립적이다. 전통적인 브라우저, PDA, 모바일 폰, 보이스 브라우저, 인스턴트 메신저로 코드 변경 없이 전달될 수 있다. 이는 RIA에 있어 매력적인 툴이다.

XForms에서 실제 데이터(XML 폼 정의)는 폼의 표현과 분리된다. XForms 모델이라고 하는 장치와 독립적인 XML 폼 정의는 다양한 표준 또는 상용 사용자 인터페이스와 작동할 수 있다.

XForms 사용자 인터페이스는 요즘의 XHTML 폼 컨트롤을 대체할 시각적 컨트롤 표준을 제공한다. 이들은 XHTML SVG 또는 기타 그룹, 보이스 브라우저 그룹 내에서 사용되거나 XForms의 사용자 인터페이스 컴포넌트를 독립적으로 개발할 수 있다. 각 XForms 컨트롤에 참조된 XForms 모델은 데이터를 렌더링 한다. 이것은 XPath를 따라 XML의 엘리먼트를 참조한다. 데이터가 제출되면 구축된 XML 데이터 모델을 제출할 수 있다.

XML 이벤트
XML 이벤트는 이벤트 리스너들을 일관성 있게 통합하고 이벤트 핸들러를 DOM 이벤트와 제휴시키는 기능을 갖춘 XML 언어이다. 이벤트가 발생하면 이는 문서 트리 경로를 통해 엘리먼트(타겟)으로 보내지고 트리로 다시 전달된다. 옵저버는 이 경로에서 이벤트에 응답할 수 있다.

XForms는 이벤트와 액션 핸들링에 XML 이벤트를 사용한다. XML 이벤트는 이벤트, 옵저버, 핸들러를 지정한다. Listing 3DOMActivate는 이벤트이고, 메시지 엘리먼트는 핸들러이고, 부모 트리거는 옵저버이다.

XForms를 Ajax와 통합할 수 있다. 현재, W3CXForms를 Ajax와 통합할 수 있다. 현재, W3C에서 20개 이상의 XForms 예제 구현을 볼 수 있다. IBM을 비롯한 많은 벤더들이 이미 XForms 엔진을 개발했다. (참고자료) Mozilla는 XForms가 Mozilla가 실행되는 모든 플랫폼 상에서 지원될 것이라고 발표했다. XForms 구현 예제는 참고자료를 참조하라.

Listing 3은 FormFaces™ 구현으로 렌더링 된 텍스트 박스와 버튼을 디스플레이 하는 XForms 예제이다.


Listing 3. FormFaces™ 구현으로 렌더링 된 텍스트 박스와 버튼을 디스플레이 하는 XForms
                

<!DOCTYPE  html PUBLIC "-//W3C//DTD XHTML 1.0//EN"

  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:form=http://www.w3.org/2002/xforms

xmlns:ev="http://www.w3.org/2001/xml-events"  xml:lang="en">

  <head>

    <title>Simple example</title>

      <link rel="stylesheet" type="text/css" href="xforms.css" />

      <script type="text/javascript" src="../../formfaces.js"></script>

      <form:model>

      <form:instance>

        <data xmlns="">

          <greeting>Hi there!</greeting>

        </data>

      </form:instance>

    </form:model>

 </head>

 <body>

   <form:input ref="greeting" incremental="true">

    <form:label>Greeting:</form:label>

   </form:input>

	<form:trigger>

	<form:label>Trigger</form:label>

	<form:message level="modal" ev:event="DOMActivate">You clicked 

	   button</form:message>

  </form:trigger>

  </body>

</html>

Dojo

Dojo는 JavaScript로 작성된 오픈 소스 DHTML 툴킷이다. Dojo 툴킷은 라이브러리 코어 세트와 다른 패키지 라이브러리의 리치(rich) 세트를 제공하는데 각각 특정 기능을 수행한다. Dojo는 저급 API를 통해 이식 가능한 JavaScript를 작성하고 복잡한 스크립트를 단순화 한다. 인터랙티브 위젯과 애니메이션 트랜지션을 쉽고 빠르게 프로토타이핑 할 수 있다. 이벤트 시스템, I/O 패키지, 일반적인 언어 기능을 위한 라이브러리가 있다. Dojo로 스크립트를 작성할 수 있고 필요에 맞게 API를 추가할 수 있다.

Dojo는 또한 어떤 애플리케이션에서라도 직접 사용할 수 있는 위젯 라이브러리를 선사한다. 메뉴 위젯, 탭 세트, 트리 위젯 같은 핵심 위젯을 UI 컨트롤로서 사용할 수 있다. 레이아웃 위젯, 데이터 피커, SVG 위젯 등도 있다.

Dojo는 DHTML 인터페이스 컴포넌트를 선언하고 사용하는 하나의 마크업 언어 주위에 구현된다. Listing 4는 HTML 페이지의 사용자를 위한 특별한 버튼에 대한 Dojo 컴포넌트 예제이다.


Listing 4. dojosample.html 예제
                

<button dojoType="Button2" widgetId="helloButton">Hello World!</button>

You need to include the Dojo widgets library that is required in your HTML page.

<script type="text/javascript">

	  dojo.require("dojo.widget.*");

      dojo.require("dojo.widget.Button2");

</script>	

Dojo 키트에는 디버깅 옵션들도 있다. AJAX Toolkit Framework (ATF)이 강력한 IDE로서 사용될 수 있다. 이것은 IBM의 Emerging technology Toolkit (ETTK)의 일부로서 이머징 기술을 특별히 모은 것이다. ATF는 Eclipse 웹 툴 프로젝트에 많이 의존하여 DOM 브라우징, JavaScript 디버깅 등을 실행한다.

최근에 Dojo Foundation은 Laszlo와 파트너쉽 계약을 맺었다. 계약에 따라 Laszlo의 오픈 소스 프로젝트에 Dojo 툴킷을 사용할 수 있다. Laszlo는 라이브러리를 Dojo 파운데이션에 기여하여 오른 소스 커뮤니티를 발전시킬 것이다.

Macromedia Flex

Macromedia Flex는 또 다른 FLASH 기반 사용자 인터페이스이다. 애플리케이션 서버에 있는 Flex 표현 서버를 제공하고 서버에서 동적으로 FLASH 파일을 만들어서 이를 브라우저에 전달한다. 이들 FLASH 파일들은 브라우저의 FLASH 플레이어 내에서 실행되고 사용자 인터랙션, 연산 수행, SOAP, HTTP, AMF 서버 연결 요청 등을 생성한다.

레이아웃과 UI 컴포넌트는 MXML이라는 XML 기반 언어로 정의된다. Flex는 시각적 컴포넌트, 컨테이너, 원격 서비스 객체, 데이터 모델에 풍부한 MXML 확장 클래스 라이브러리를 제공한다. 컨트롤과 데이터 바인딩을 수행하고 서버 측 데이터에 액세스 한다.

ECMA 스크립팅 언어(ActionScript 2)는 MXML에 삽입되어 사용자 이벤트, 시스템 이벤트를 핸들하거나 복잡한 데이터 모델을 구현한다. 이는 JavaScript와 ECME 스크립트와 비슷한 객체 지향 언어이다. XForms와 마찬가지로 Flex는 데이터 모델, 데이터 표현, 데이터 밸리데이터, 데이터 서비스를 분리한다. (MVC 스타일과 비슷하다.)

MXML에서 오는 모든 요청들은 Flex 컴파일러가 처리한다. MXML을 컴파일하고 SWF를 만들며 변경되어 브라우저에 전달될 때 까지 캐싱한다.

XML 에디터는 MXML의 스크립팅에 사용될 수 있지만 Macromedia 역시 Flex 애플리케이션 개발에 Flex Builder 1.5 IDE를 제공한다. 또한 서버에 연결하고, HTTP를 호출하고, 원격 자바™ 객체로 연결하고 브라우저에서 웹 서비스와 인터랙팅하는 컴포넌트도 있다. 기존 J2EE와 .NET 애플리케이션 모델과 통합될 수 있다.

Listing 5는 Macromedia Flex 코드 예제이다.


Listing 5. Macromedia Flex 코드
                

<?xml version="1.0"?>

<mx:Application xmlns:mx="http://macromedia.com/2003/mxml">

<mx:Form label="Employee Information">

      <mx:FormItem label="First Name">

         <mx:TextInput id="firstName" />

      </mx:FormItem>

</mx:FormItem>

</mx:Form>

<!-- The myEmployee data model. -->

<mx:Model id="myEmployee">

   <name>

      <first />

      <last />

   </name>

   <department />

   <email />

</mx:Model>

mx:Binding source="firstName.text" destination="myEmployee.name.first" />

</mx:Application>	

Macromedia Flex는 Laszlo와 비슷하다. 두 개 모두 풍부하고 강력한 FLASH 기반 애플리케이션이다. Laszlo는 FLASH 엔진의 밖에 존재하기 때문에 퍼포먼스는 떨어지지만 여라 장점들을 갖고 있다.




위로


툴 비교

이전 섹션에서 논의된 다섯 개의 툴들을 비교했다. Altiolive (리치 엔터프라이즈 애플리케이션)도 함께 비교했다.


표 1. 툴 비교
기술 브라우저 기술 스크립팅 Richness 비고
Laszlo Flash,XML LZX files+JavaScript 높음 배우기 쉽고 풍부하다.
Mozilla XUL XUL language XUL files+JavaScript 높음 강력하고 브라우저 의존성이 있다.
XForms Xform 구현에 따라 다름 제한됨 장치 중립적이고 W3C 순응이다.
Dojo JavaScript HTML+JavaScript 제한됨 JavaScript 기반. 채택성이 높아지고 있다.
Macromedia Flex Flash, XML MXML files 높음 오픈 소스가 아니다. Macromedia의 상용 툴이다.
Altiolive Applet, XML Java 제한됨 http://www.altio.com/




위로


기타 기술

지금까지 다섯 가지 기술에 대해 살펴보았지만 더 있다. 많은 기업들이 다양한 기술들을 사용하여 RIA를 프로토타이핑 하고 있다. 이들 모두를 설명하지는 않겠지만 조금만 살펴보도록 하자.

  • Backbase - Ajax 애플리케이션의 생성을 돕는 소프트웨어 개발 및 판매
  • Netvibes - 고객이 만든 웹 홈 페이지 솔루션을 위한 무료 서비스
  • Zimbra - 차세대 엔터프라이즈 메시징과 협업을 위한 오픈 소스 서버와 클라이언트 기술
  • Protopage - 무료, 퍼스널 시작 페이지
  • Nexaweb - Enterprise Internet Applications의 구현과 전개를 위한 소프트웨어 플랫폼
  • altio - 브라우저에 있는 리치 엔터프라이즈 애플리케이션




위로


맺음말

RIA, 현재의 UI 기술, 기타 기술들을 소개했다. 툴 비교를 통해 자신의 필요에 맞는 툴을 선택할 수 있기를 바란다. 기술들 마다 장단점이 있다.

이러한 기술들은 놀라운 것이고 더욱 풍부한 사용자 경험을 약속한다. 브라우저를 넘어서 PDA, 모바일 장치로 렌더링 되고 오디오, 비디오, 그래픽, 애니메이션을 추가할 수 있다. RIA는 XML을 대부분 수용했다.

앞으로 RIA가 웹 UI를 다음 레벨로 성장시키는데 중요한 역할을 할 것으로 기대한다.

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Photo of Vaibhav V. Gadge

Vaibhav V. Gadge는 인도 방갈로르 소재의 IBM 소프트웨어 연구소 소속의 소프트웨어 엔지니어이다. 현재 Websphere Product Center의 포탈 팀에서 일하고 있다. 그는 자바 인증 전문가이며 자바, J2EE, 웹 기반 기술에 5년의 경력을 갖고 있다. Nagpur University에서 전자공학 학사를 받았다. (vaigadge@in.ibm.com)

Trackback 0 and Comment 0