2008. 8. 31. 19:16

BlazeDS 시작하기 / Getting started with BlazeDS - part 4

Reference : http://www.adobe.com/devnet/livecycle/articles/blazeds_gettingstarted_04.html

Building a remoting application
리모팅 어플리케이션 만들기

Remoting Service 를 사용하면, 어플리케이션에서 어플리케이션 서버에 설치된 Java 오브젝트의 메쏘드를 직접 호출하고, 반환된 값(return value) 을 사용할 수 있습니다. 메쏘드는 primitive 데이터, 객체, 객체의 collection, 객체 graph, 등의 형태로 반환할 수 있습니다. 서버의 메쏘드에서 반환된 Java 객체는 dynamic 이나 typed ActionScript 객체에 deserialize 되어 있습니다

이 섹션은 BlazeDS Remoting Service 를 보여주는 간단한 재고 관리 어플리케이션을 만드는 방법을 설명하고 있습니다.

Note: 턴키 서버는 HSQLDB 데이터베이스를 포함하고 있어서, 데이터베이스를 설정하지 않고 “out-of-the-box” 샘플을 실행할 수 있습니다. HSQLDB 가벼운 Java RDBMS 로, 특히 샘플을 실행하는데 적합합니다.

샘플 데이터베이스 실행:

  1. command prompt 창을 여십시오
  2. /blazeds/sampledb 로 이동하십시오
  3. 아래의 명령어를 실행하십시오:

    startdb

Step 1: Create the Java components
Java 컴포넌트 생성

이 어플리케이션의 서버에서는 간단한 Data Access Object (DAO) 와 Value Object 패턴을 사용합니다:

  • ProductDAO 클래스는 제품을 삭제하고, 갱신하는 데이터 접근 로직을 제공합니다.
  • Product 는 Product 객체 (value objects) 를 사용하여 클라이언트와 서버 사이에서 전송됩니다.
Product.java 생성:
  1. Eclipse 가 Java 퍼스펙티브인지 확인하십시오
  2. blazeds-server 프로젝트에서, src 폴더를 우클릭하고, New > Class 를 선택하십시오. 패키지 이름으로 “tutorial” 을 입력하고 클래스 이름으로 “Product” 를 입력하십시오;그리고 Finish 를 클릭하십시오. 아래와 같이 Product 클래스를 구현하십시오:

package tutorial;

public class Product {

private int productId;
private String name;
private double price;
private int qty;

public int getProductId() {
return productId;
}

public void setProductId(int productId) {
this.productId = productId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

public int getQty() {
return qty;
}

public void setQty(int qty) {
this.qty = qty;
}

}

 

ProductDAO.java 생성:
  1. Eclipse 가 Java 퍼스펙티브인지 확인하십시오
  2. blazeds-server 프로젝트에서, src 폴더를 우클릭하고, New > Class 를 선택하십시오. 패키지 이름으로 “tutorial” 을 입력하고 클래스 이름으로 “ProductDAO” 를 입력하십시오; 그리고 Finish 를 클릭하십시오. 아래와 같이 ProductDAO 클래스를 정의하십시오:

package tutorial;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import flex.samples.ConnectionHelper;
import tutorial.Product;

public class ProductDAO {

public List getProducts() throws SQLException {
List list = new ArrayList();
Connection c = null;
try {
c = ConnectionHelper.getConnection();
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM product ORDER BY name");
while (rs.next()) {
Product product = new Product();
product.setProductId(rs.getInt("product_id"));
product.setName(rs.getString("name"));
product.setPrice(rs.getDouble("price"));
product.setQty(rs.getInt("qty_in_stock"));
list.add(product);
}
} finally {
c.close();
}
return list;
}

public void update(Product product) throws SQLException {
Connection c = null;
try {
c = ConnectionHelper.getConnection();
PreparedStatement ps = c.prepareStatement(
"UPDATE product SET name=?, price=?, qty_in_stock=? WHERE product_id=?");
ps.setString(1, product.getName());
ps.setDouble(2, product.getPrice());
ps.setInt(3, product.getQty());
ps.setInt(4, product.getProductId());
} finally {
ConnectionHelper.close(c);
}
}

}

Step 2: Create the remoting destination
리모팅 데스티네이션 생성

Remoting 데스티네이션은 Flex 어플리케이션이 외부에서 호출할 수 있는 Java 클래스를 노출합니다. 데스티네이션 아이디는 Flex 어플리케이션이 리모트 클래스를 참조할 때 사용하는 논리적 이름입니다. 아이디를 사용하면 fully qualified Java 클래스 이름에 대한 참조를 하드코드할 필요가 없습니다. 이 논리적 이름은 remoting-config.xml 의 데스티네이션 설정의 일부로서 Java 클래스 이름으로 매핑됩니다.

ProductDAO 클래스에 대한 리모팅 데스티네이션 생성:

  1. blazeds-server 프로젝트에서, flex 폴더에 있는 remoting-config.xml 파일을 여십시오.
  2. 아래와 같이 정의된 tutorial-product 라는 이름의 데스티네이션을 추가하십시오:

    <destination id="tutorial-product">
    <properties>
    <source>tutorial.ProductDAO</source>
    </properties>
    </destination>

Step 3: Create a Flex project
Flex 프로젝트 생성

  1. Eclipse 메뉴에서 File > New > Project… 를 선택하십시오.
  2. Flex Builder 노드를 펼치고, Flex Project 를 선택한 다음, Next 를 클릭하십시오.
  3. 프로젝트 이름으로 “tutorial-product” 를 입력하십시오.
  4. Use default location 이 선택되었는지 확인하십시오.
  5. 어플리케이션 종류로 Web Application 을 선택하십시오.
  6. 어플리케이션 서버 종류로 J2EE 를 선택하십시오.
  7. Use remote object access service 를 선택하십시오.
  8. Create combined Java/Flex project using WTP 선택을 해제하십시오.
  9. Next 를 클릭하십시오.
  10. LiveCycle Data Services 의 루트 폴더가 matches the root folder of your BlazeDS 웹 어플리케이션의 루트 폴더와 매치되는지 확인하십시오. 설정은 이것과 유사해야 합니다 (you may need to adjust the exact folder based on your own settings):

    Root Folder: C:\blazeds\tomcat\webapps\samples
    Root URL: http://localhost:8400/samples/
    Context Root: /samples

  11. Validate Configuration, Finish 를 차례로 클릭하십시오.

Step 4: Retrieve the list of products

  1. 새롭게 생성된 tutorial-product 프로젝트에서, src 폴더에 위치한 tutorial-product.mxml 파일을 열고, 아래와 같이 어플리케이션을 구현하십시오:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:RemoteObject id="ro" destination="tutorial-product"/>

    <mx:DataGrid dataProvider="{ro.getProducts.lastResult}" width="100%" height="100%"/>

    <mx:Button label="Get Data" click="ro.getProducts()"/>

    </mx:Application>
  2. 어플리케이션을 실행하고 테스트하십시오.

Step 5: Add event handlers to improve the application
어플리케이션 향상을 위한 이벤트 핸들러 추가

RemoteObject 호출은 비동기적입니다. 결과와 에러를 처리하기 위해 RemoteObject 컴포넌트의 result 와 fault 이벤트를 사용할 수 있습니다. 어플리케이션을 더 튼튼하게 만들고 잘 파티션하기 위해 아래와 같이 코드를 수정하십시오:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;

[Bindable]
private var products:ArrayCollection;

private function resultHandler(event:ResultEvent):void
{
products = event.result as ArrayCollection;
}

private function faultHandler(event:FaultEvent):void
{
Alert.show(event.fault.faultString);
}
]]>
</mx:Script>

<mx:RemoteObject id="ro" destination="tutorial-product"
result="resultHandler(event)"
fault="faultHandler(event)"/>

<mx:DataGrid id="dg" dataProvider="{products}" width="100%" height="100%"/>

<mx:Button label="Get Data" click="ro.getProducts()"/>

</mx:Application>

Step 6: Create the value object
밸류 객체 생성

In the application so far, the list of products returned by the getProducts() method is deserialized into dynamic objects. Sometimes, you may want to work with strongly typed objects. To work with typed objects in this application, first create the ActionScript version of the Product class created in step 1:

  1. tutorial-product 프로젝트에서 src 폴더를 우클릭하고 New > ActionScript Class 를 선택하십시오. 클래스 이름으로 “Product” 를 입력하고 Finish 를 클릭하십시오.
  2. 아래와 같이 Product 클래스를 구현하십시오:

    package
    {
    [Bindable]
    [RemoteClass(alias="tutorial.Product")]
    public class Product
    {
    public var productId:int;
    public var name:String;
    public var price:Number;
    public var qty:int;
    }
    }

Product 클래스의 ActionScript 버전 (Product.as) 과 Java 버전 (Product.java) 을 캐치하기 위해 [RemoteClass(alias="tutorial.Product")] 를 사용하고 있습니다. 그 결과, ProductDAO 의 getProducts() 메쏘드에 의해 리턴되는 Product 객체는 ActionScript Product 클래스의 인스턴스에 deserialize 되어 있습니다. 유사하게, 다음 단계에서, RemoteObject 의 update 메쏘드의 인자로서 전해지는 ActionScript Product 클래스의 인스턴스는 서버에서 Java 버전 Product 클래스의 인스턴스에 deserialize 되어 있을 것입니다.

Step 7: Update products
제품 갱신

  1. tutorial-product.mxml 어플리케이션을 아래와 같이 수정하여 사용자가 제품을 갱신할 수 있게 하십시오:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
    <![CDATA[

    [Bindable]
    private var product:Product;

    private function update():void
    {
    product.name = productName.text;
    product.price = Number(price.text);
    product.qty = parseInt(qty.text);
    ro.update(product);
    }

    ]]>
    </mx:Script>

    <mx:RemoteObject id="ro" destination="tutorial-product"/>

    <mx:DataGrid id="dg" dataProvider="{ro.getProducts.lastResult}" width="100%" height="100%"
    change="product = Product(dg.selectedItem)"/>

    <mx:Button label="Get Data" click="ro.getProducts()"/>

    <mx:Form>
    <mx:FormItem label="Name">
    <mx:TextInput id="productName" text="{product.name}"/>
    </mx:FormItem>
    <mx:FormItem label="Price">
    <mx:TextInput id="price" text="{product.price}"/>
    </mx:FormItem>
    <mx:FormItem label="Qty In Stock">
    <mx:TextInput id="qty" text="{product.qty}"/>
    </mx:FormItem>
    <mx:FormItem>
    <mx:Button label="Update" click="update()"/>
    </mx:FormItem>
    </mx:Form>

    </mx:Application>
  2. 어플리케이션을 실행하고 테스트하십시오