BLOG ARTICLE blazeds | 2 ARTICLE FOUND

  1. 2009.09.03 Java VO를 ActionScript VO로 변환하기
  2. 2009.04.16 Flex 3 + BlazeDS

BlazeDS를 사용하려면 동일한 내용을 담는 Vo를 Java 버전과 ActionScript 버전의 짝을 만들어 줘야 한다.
근데 이번에 한꺼번에 대량 작업을 하려다 보니 너무 귀찮아져서 Java VO 디렉토리를 쭉 훑어서 특정 디렉토리 아래에 ActionScript VO로 변환해서 저장해 주는 초간단/초허접 프로그램을 만들어 보았다.
필요하신 분들은 용도에 맞춰 고쳐 쓰시고, 고쳐 달라고 하기는 없기~

package com.my.vo.data;

import com.my.vo.CommonVo;

// Generated 2009. 8. 24 ???? 12:54:51 by Hibernate Tools 3.2.4.GA

/**
 * Foo generated by hbm2java
 */
public class FooVo extends CommonVo{

    /**
     *
     */
    private static final long serialVersionUID = 4526158581216990458L;
   
    public FooIdVo id;
    public String barName;
    public String barType;
    public int barLength;

    ...
}
이것이 원본 Java VO


package vo.data
{
    import vo.CommonVo;
   
    [Bindable]
    [RemoteClass(alias="com.my.vo.data.FooVo")]

    public class FooVo extends CommonVo
    {       
        public var id:FooIdVo;
        public var barName:String;
        public var barDesc:String;
        public var barType:String;
        public var barLength:int;
    }
}
이것이 원하는 형태의 ActionScript VO


package flex;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class ConvertJavaToAS {
    public static final String packagePrefix = "com.my.";

    public static void main(String[] args) throws Exception {
        String javaDir = "C:/workspace/com/my/vo";
        String asDir = "D:/temp/vo";
       
        File inDir = new File(javaDir);
       
        traverse(inDir, asDir);
    }

    public static void traverse(File in, String out) throws Exception {
        File[] files = in.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory())
                traverse(files[i], out);
            else if (files[i].getName().endsWith("Vo.java")){
                convert(files[i], out);
            }
        }
    }
   
    public static void convert(File java, String out) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(java));
       
        String strPackage = "";
        String strClass = "";
        StringBuilder strVar = new StringBuilder();
       
        String line = null;
        while ( (line = br.readLine()) != null ) {
            if (!strClass.equals("") && line.trim().startsWith("public " + strClass + "("))
                break;
            else if (line.trim().startsWith("package")) {
                String[] strs = line.trim().split(" ");
                strPackage = strs[1].substring(0, strs[1].length()-1);
            }
            else if (line.trim().startsWith("public class")) {
                String[] strs = line.trim().split(" ");
                strClass = strs[2];
            }
            else if (line.trim().startsWith("public")) {
                String[] strs = line.trim().split(" ");
                strVar.append("\t\tpublic var ")
                      .append(strs[2].substring(0, strs[2].length()-1)).append(":")
                      .append(mapDataType(strs[1])).append(";\n");
            }
        }
       
        br.close();
       
        save(strPackage, strClass, strVar.toString(), out);
    }
   
    public static String mapDataType(String javaType) {
        if (javaType.equals("BigDecimal")) {
            return "String";
        }
        else
            return javaType;
    }
   
    public static void save(String pack, String clazz, String vars, String out) throws Exception {
        String subdir = pack.substring(pack.lastIndexOf(".")+1);
        String outDir = out + "/" + subdir;
        File asDir = new File(outDir);
        if (!asDir.exists())
            asDir.mkdirs();
       
        String asPackage = pack.substring(packagePrefix.length());
       
        BufferedWriter bw = new BufferedWriter(new FileWriter(outDir + "/" + clazz + ".as"));
        bw.write("package " + asPackage + "\n{\n");
        bw.write("\timport vo.CommonVo\n\n");
        bw.write("\t[Bindable]\n");
        bw.write("\t[RemoteClass(alias=\"" + pack + "." + clazz + "\")]\n\n");
        bw.write("\tpublic class " + clazz + " extends CommonVo\n\t{\n");
        bw.write(vars);
        bw.write("\t}\n}");
       
        bw.flush();
        bw.close();
    }
}

이것이 변환 프로그램


사용시 수정해야 할 것들은 굵은 글씨도 표시된 부분

1. packagePrefix : Java VO와 ActionScript VO의 패키지 경로를 다르게 사용할 경우 Java VO의 package에서 잘라내야 할 앞부분. 같은 패키지 경로를 사용하면 이걸 빈 문자열로 설정하면 된다.
2. javaDir : Java VO 들이 있는 최상위 디렉토리. 이 아래에 있는 모든 Java VO를 찾아서 ActionScript VO로 변환한다.
3. asDir : 생성된 ActionScript VO들을 저장할 디렉토리. 패키지에 따라 하위디렉토리를 만들어서 저장.
4. Vo.java : 나는 일단 Java VO 파일의 postfix가 Vo.java라서 이렇게 썼고, 필요에 따라서 고쳐 쓰시길.
5. mapDataType : Java의 데이터타입을 AS이 데이터타입으로 매핑시켜 주는 메소드. 원하는만큼 추가해 주면 됨.
6. CommonVo : 나는 공통으로 상속할 상위클래스가 있어서 이렇게 썼고, 필요없으면 빼고 다르면 고쳐서 쓰시길...


띄어 쓰기 같은 건 무조건 한칸으로 가정하고 처리했으니까 Hibernate Tools로 생성한 VO를 사용하거나, 줄 잘 맞춰서 직접 정성껏 만든 VO를 사용해야 원하는 결과를 얻을 수 있다.

'Flex' 카테고리의 다른 글

Tooltip과 Datatip의 스타일 지정  (0) 2009.09.22
includeInLayout 속성  (0) 2009.09.18
Flex + BlazeDS + Java 웹프로젝트용 Ant Build.xml  (0) 2009.08.20
Flex I18N 메시지 컴파일용 Ant Build.xml  (0) 2009.07.01
DataGrid Paging 구현  (0) 2009.05.20
AND

Flex 3 + BlazeDS

Flex 2009. 4. 16. 23:49
기본적으로 Flex는 화면단만을 개발할 수 있다.
(기본제공 컴포넌트가 다양해서 일반적인 화면은 쉽게 개발할 수 있고, 기본제공 컴포넌트로 구현할 수 없는 복잡한 화면은 기본 컴포넌트를 상속해서 확장하거나 ActionScript 코딩을 통해 구현하면 된다.)
다수의 사용자가 접속하는 시스템의 경우 애플리케이션 서버에 DB 등에 접속하는 코드가 있고, 이 코드와 Flex로 구현한 화면간의 통신을 구현해야 한다.
화면단의 Flex와 서버간의 통신기능을 제공하는 유료제품으로 Adobe의 LiveCycle Data Service가 있다. 그런데, 이것을 사용해서 시스템을 구축하면 운영서버의 CPU수에 따라 라이센스 비용을 지불해야 한다. 이 비용이 꽤 비싼 것으로 알고 있다. 우리나라에선 Flex Builder도 외국에 비해 상당히 비싼데, LCDS까지 이렇게 비싸니 우리나라에서 Flex가 빨리 보급되지 못 하는 이유 중 하나라고 생각된다.
LCDS에 대한 대안으로 아이러니하게도 Adobe에서 BlazeDS라는 것을 제공한다. 이것은 오픈소스로 무료로 사용할 수 있다. LCDS는 Flex Builder에서 편리하게 개발할 수 있는 기능을 제공하지만, BlazeDS는 Flex Builder에는 기능이 제공되지 않아 약간의 수작업이 필요하다. 하지만 약간의 유틸리티를 이용하면서 구성만 잘 하면 비용대비 효과가 우수한 시스템을 구축할 수 있다.

(이하 내용은 제가 사용하면서 예측한 내용으로 사실과 다를 수 있음을 알려 드립니다)
BlazeDS는 Flex로 구현된 화면단과 J2EE로 구현된 서버단간에 HTTP로 데이터를 원활히 주고 받을 수 있도록 연결해 주는 역할을 수행한다. 서버단에서 수행되는 메커니즘을 보면 Struts하고 유사하다고 보면 된다. 화면에서 특정 이름으로 서버단의 BlazeDS 서블릿을 호출하면, 서블릿은 그 이름에 해당하는 클래스를 XML 설정파일에서 찾아 객체를 생성하고 해당 메소드에 인자를 넘겨 호출한 후 결과를 리턴한다. 여기서 중요한 역할이 화면단에서 ActionScript 형태로 만들어 보낸 인자를 그에 맞는 Java 객체로 변환해서 메소드에 전달하는 것과 해당 메소드의 처리결과(Java 객체)를 Flex 화면에서 받을 수 있도록 전달해 주는 것이다. BlazeDS의 이런 역할 덕분에 Flex 화면과 J2EE 웹컨테이너간의 통신이 가능하다.
여기서, 서블릿이 특정 이름에 대해 호출하는 클래스는 특별한 제약이 없이 POJO면 가능하다. 즉, 여기부턴 자유롭게 구성이 가능하므로 예를 들면 Spring으로 이후를 구성할 수도 있다는 뜻이다. 아니면 Struts2의 Action처럼 클래스를 구현하고 DB처리는 Hibernate나 iBatis로 구현해도 된다.

대형 시스템을 구성한다면 BlazeDS를 이용해서 서버단 라이센스 비용을 대폭 줄일 수 있겠고, 대신 Flex Builder는 개발자수만큼 사야 될 것이다. Flex Builder는 기본과 Pro 버전이 있는데 기본이 1명당 40만원 정도였던 것 같고, Pro는 백만원이 넘었던 것으로 기억한다.(환율따라 자주 변함) Pro는 Advanced DataGrid라고 DataGrid에 트리형태의 표현 등 기능이 추가된 것과 차트 기능이 추가된다. 본인은 유료 Pro 버전을 쓰고 있는데 Advanced DataGrid는 별로 쓸 일이 없었고, 차트 기능은 편리해서 잘 사용하고 있다. 개발자가 많다면 대부분은 기본버전을 구매하고, 한두명만 Pro버전을 구매해서 이 사람들에게 차트개발을 몰아주는 것도 방법이 될 수 있을 것 같다. 솔직히 Flex 써 보니 사용하기도 괜찮고 모양도 예쁘게 만들어져서 좋긴 한데 우리나라에선 너무 비싸게 파는 것 같다.

참고로 Flex Builder는 3.0 말고 3.2 이상을 쓰는 것이 좋다. 맨 처음 3.0 썼는데 소스 하나 고치고 저장할 때마다 빌드시간이 너무 오래 걸려서 짜증났는데, 3.2 쓰면서 빌드 시간이 거의 5초 이내로 줄어서 쓸만해졌다.
참고 또 하나, Flex와 BlazeDS로 현재 개발환경을 구성한다면 Eclipse 3.4 (Ganymede)에 Flex Builder 3.2 Eclipse Plugin 버전을 사용하면 된다. Eclipse 3.3에서 3.4로 버전업 되면서 다른 건 몰라도 Search 결과는 참 보기 좋게 바뀌었다. 그래서, 3.4 강추!
-> 얘길 들어보니 Flex Builder 3.2를 써도 Eclipse 3.3을 쓰면 빌드 시간이 여전히 길다고 하니 반드시 Flex Builder 3.2에 Eclipse 3.4의 조합이 최적인 것 같다.

이와 관련된 링크나 설치방법, 샘플 등은 본인이 워낙 게으른 관계로 제공하지 못 하고, 그냥 열심히 해 보시라는 말 밖에 못 드리는 점 양해 바랍니다.

'Flex' 카테고리의 다른 글

Flex에서 HTML 페이지 띄우기  (0) 2009.05.14
Flex3 유용한 사이트  (0) 2009.04.23
로딩속도 향상  (0) 2009.04.13
FormItem 안의 내용을 옆으로 배치  (0) 2009.04.13
Label, TextInput에 손 모양 커서 적용  (0) 2009.04.13
AND