출처: http://blog.jidolstar.com/455

Adobe Flex를 접할때 어려워하는 부분중에 하나가 Event입니다.
깊숙히 이해하려고 할때 잘 이해가 안되는 부분이 많은게 이벤트죠.

기본에 충실해야한다!


프로젝트(http://starpl.com)를 하면서 많이 느꼈습니다.


처음 Flex 접했을때 가장 어려움을 겪었던 것은 기본이 탄탄하지 못한 것으로부터 였습니다.


그래서 Flex와 함께 ActionScript 3.0의 기본 문법 및 대략적 내용을 이해해야한다고 생각합니다.


단순한 문법뿐 아니라 분석/설계에도 관심을 가지고 공부해서 명확하고 깨끗한 프로그램을 만들 수 있도록 노력해야겠구요.


아래는 Event에 대한 질문을 걸어놓고 스스로 답변까지 해두었습니다.
이것으로 Event 전부를 설명할 수 없지만 몇가지 궁금한 사항을 이해하는데는 도움이 될겁니다.


그냥 읽고 지식만 얻어가지 마시고 없는 질문이 있다면 스스로 질문/답변을 댓글로 달아주시면 더욱 고맙겠습니다. 잘못된 내용이나 추가해야한다는 것도 포함합니다.


1. ActionScript 3.0 이벤트(Event)

1.1 ActionScript 2.0과 3.0에서 이벤트가 바뀐점은?

  • ActionScript 2.0에서는 이벤트 리스너를 추가하는 경우 상황에 따라 addListener() 또는 addEventListener()를 사용하지만 ActionScript 3.0에서는 항상 addEventListener()를 사용합니다.
  • ActionScript 2.0에는 이벤트 흐름이 없으므로 이벤트를 브로드캐스팅하는 객체에서만 addListener() 메서드를 호출할 수 있지만 ActionScript 3.0에서는 이벤트 흐름에 포함된 모든 객체에서 addEventListener() 메서드를 호출할 수 있습니다.
  • ActionScript 2.0에서는 함수, 메서드 또는 객체를 이벤트 리스너로 사용할 수 있지만 ActionScript 3.0에서는 함수 또는 메서드만 이벤트 리스너로 사용할 수 있습니다.
  • on(event) 구문은 이제 ActionScript 3.0에서 지원되지 않으므로 ActionScript 이벤트 코드를 무비 클립에 첨부할 수 없습니다. 이벤트 리스너를 추가할 때는 addEventListener()만 사용할 수 있습니다.

1.2 Event를 사용해야하는 이유? 2가지 이상

  • 객체간 강한 결합 해결 : 애플리케이션 설계시 Callback함수를 사용하는 등의 강한결합을 이용하는 경우 유지보수 및 확장이 어려워지는 경우가 크다. 이벤트는 객체간 느슨한 결합을 해주는데 큰 힘을 발휘할 수 있다.
  • 작업에 대한 일관성 없는 응답 : 동기적 방식과 비동기적 방식에 대한 응답에 대한 처리를 이벤트를 사용하지 않는 경우 서로 다른 방법을 선택해서 사용해야한다. 이벤트는 1가지 방법으로 응답처리를 가능하게 해준다.


2. Event의 구성요소 3가지는 무엇이고 의미를 설명하라.

  • 이벤트 객체(Event Object)
    flash.net.Event의 객체나 이를 확장한 이벤트 객체를 의미한다. 이벤트 객체에는 이벤트에 대한 정보가 들어가있다. 이벤트의 종류(Type)과 이벤트를 발생한 객체(target)에 대한 정보가 포함된다.
  • 이벤트 발생자(Event Dispatcher)
    이벤트를 발생(broadcast)하는 객체이다. 이벤트 객체에 target으로 이벤트 발생자 정보가 담긴다. flash.net.EventDispatcher를 확장한 모든 객체는 이벤트 발생자가 될 수 있다. EventDispatcher의 dispatchEvent() 메소드에 이벤트 객체를 담아 실행하면 이벤트가 발생하게 된다.
  • 이벤트 청취자(Event Listener)
    일종의 메소드 또는 함수이다. 발생한 이벤트를 듣는 역할을 한다. EventDispatcher클래스를 확장한 클래스의 객체에서 addEventListener()을 이용해 이벤트 청취자를 등록할 수 있다. addEventListener()을 이용하면 청취할 이벤트의 종류(type)을 결정할 수 있으며 청취할 이벤트 흐름(capture,target,bubbling) 및 우선순위등을 선택할 수 있다.

3. Event Listener를 등록/삭제하는 방법을 기술하라.

  • 등록
    EventDispatcher의 addEventListener() 메소드를 이용한다.
    예)
    var button:Button = new Button();
    button.addEventListener( MouseEvent.CLICK, onClick, false );
    public function onClick( event:MouseEvent )
    {
      trace( event.type, event.target  );
    }
  • 삭제
    EventDispathcer의 removeEventListener() 메소드를 이용한다.
    예)
    button.removeEventListener( MouseEvent.CLICK, onClick, false );
    3개의 인자가 addEventListener()를 사용할때와 같아야 정상적으로 이벤트 청취자 등록이 삭제된다.
    참고로 맨 마지막 인자는 useCapture이다.

4. Event 전파단계의 종류 3가지가 무엇이며 각각에 대한 설명

  • 이벤트 전파단계의 종류 : 캡쳐(capture) 단계, 타겟(target) 단계, 버블(bubble)단계
  • 이벤트 전파 순서 : 캡쳐->타겟->버블
  • 캡쳐 단계
    루트(root) 디스플레이 객체서부터 이벤트를 발생한 객체(target)까지 디스플레이 객체 리스트(display Object List)를 따라 검색해나가는 단계이다. 즉, 부모->자식으로 이벤트를 전파한다. 이 캡쳐 단계에 이벤트를 청취하기 위해서는 addEventListener()의 3번째 인자인 useCapture가 반드시 true로 되어야 한다. false로 되어 있다면 캡쳐단계가 아닌 타겟과 버블 단계에서 이벤트 청취를 한다.
    캡쳐단계 청취하는 목적은 다양할 수 있다. 가령 중간에 이벤트 전파를 중지시킬때 필요할 수 있다. 이해가 안될 수 있지만 실제 프로젝트를 하면 이런 경우가 다분하다.
    사용 예 )
    button.addEventListener( MouseEvent.CLICK, onClick, true );
  • 타겟 단계
    갭쳐 단계 이후 타겟단계에 도달한다. 타겟 단계는 이벤트를 발생시킨 객체까지 도달했을때 이뤄진다.
  • 버블 단계
    타겟 단계 이후 다시 루트(root) 디스플레이 객체로 이벤트가 전파되는 단계이다. 버블버블 물망울이 수면위로 다시 올라가는 것을 연상하면 되겠다. 캡쳐와 반대로 자식->부모로 이벤트가 전파되는 단계이다.
    이벤트가 버블 단계로 전파되기 위한 조건은 이벤트 송출시 Event의 생성자 인자값중 bubble값을 true로 설정되어 있어야 한다. MouseEvent같은 경우 이 bubble값이 true로 설정되어 있다.
    타겟단계와 버블단계에 이벤트 청취자를 등록하기 위해 addEventListener()의 3번째 인자 useCapture가 false로 되어야 한다. useCapture를 설정하지 않으면 기본값이 false이다.
  • 이벤트 객체가 전파되는 기능이 굳이 필요한 이유
    부모-자식1-자식2….-자식100 의 형태로 디스플레이 객체 리스트가 형성되어있다고 가정하자 자식50에서 자식 100을 마우스 클릭했을때 이벤트를 받고 싶다고 하자. 자식50은 자식100의 존재유무를 모른다(알 수 있지만 알게되면 강한결합이 일어난다.) 이런 경우 이벤트 객체가 전파되는 기능은 매우 유용하게 쓰일 수 있다. 캡쳐나 버블 단계에서 자식50은 자식100에서 발생된 이벤트를 받을 수 있다.
  • flash.display.DisplayObject 클래스는 EventDispatcher를 확장해서 만들어졌다는 것에 주목하자.

5. 4번의 Event 전파는 어떤 환경에서 가능한가?

  • 반드시 디스플레이 객체 리스트(Display Object List) 상에 존재하는 디스플레이 객체(Display Object)여야 이벤트 전파가 가능하다. 그 외의 이벤트 전파는 타겟 단계밖에 없다. 가령, HTTPService나 URLLoader에서 이벤트가 발생하는 경우 이들은 디스플레이 객체가 아니다.
  • 이벤트 전파의 조건
    1. 디스플레이 객체여야 한다.(flash.display.DisplayObject를 확장한 클래스의 객체)
    2. 디스플레이 객체는 디스플레이 객체 리스트에 존재해야 한다. 즉, stage로 부터 addChild되어 있어야 한다.

6. 이벤트 전파시 target과 currentTarget의 차이점은 무엇인가? 예를 들어 설명하라.

  • target은 이벤트를 발생한 객체이고 currentTarget은 이벤트를 청취하는 객체이다.
  • 예시)
    var p:Sprite = new Sprite(); //parent
    var c:Sprite = new Sprite(); //child
    addChild( p );
    p.addChild( c ); //c가 p의 자식인 것에 주목
    p.addEventListener( MouseEvent.CLICK, onClick ); //이벤트 청취를 p가 하는 것에 주목!
    public function onClick( event:MouseEvent )
    {
    trace( event.target, event.currentTarget ); //c를 클릭했을 경우 c, p가 나오고 p를 클릭했을 경우 p,p가 나온다.
    }

7. Event 우선순위에 대해서 간단한 예제를 들어 설명하라.

  • 이벤트 우선순위는 구체적으로 이벤트 청취 우선순위라고 할 수 있다.
  • 이벤트 청취 우선순위는 addEventListener()의 4번째 인자인 priority를 이용한다. 이 값이 클 수록 청취 우선순위가 높아지며 addEventListener()의 등록 순서에 상관없이 우선순위에 따라 이벤트 리스너가 호출된다.
  • 이벤트 청취 우선순위가 유효한 조건
    1. 같은 객체에서 청취한다.
    2. 같은 이벤트 종류(type)을 청취한다.
    3. 같은 useCapure 값을 가진다.
  • ex)
    a.addEventListener(MouseEvent.CLICK, aHandler, false, 3);
    a.addEventListener(MouseEvent.CLICK, bHandler, false, 1);
    a.addEventListener(MouseEvent.CLICK, cHandler, false, 100);

    a객체에 MouseEvent.CLICK 이벤트가 발생시 등록순서에 상관없이 priority값이 가장큰 cHandler가 먼저 호출되고 다음으로 aHandler, bHandler가 호출된다.

8. Event 전파를 중단하는 메소드 2개가 무엇이며 간단한 예제를 들어 각각의 차이점을 설명하라.

  • Event 클래스의 stopPropogation()와 stopImmediatePropogation() 메소드이다.
  • 차이점
    - stopPropogation()
      이벤트 전파를 중단하되 같은 노드의 이벤트를 청취까지는 허락한다.
    - stopImmediatePropogation()
      이벤트 전파를 즉시 중단한다.
  • 예제
    back이 배경 canvas이고 button1이 back에 포함된 button일때
    back.addEventListener(MouseEvent.CLICK, event1Handler);
    back.button.addEventListener(MouseEvent.CLICK, event2Handler);
    back.button.addEventListener(MouseEvent.CLICK, event3Handler);
    back.button.addEventListener(MouseEvent.MOUSE_OUT, outHandler);private function event1Handler(e:MouseEvent):void
    {
           trace(’back’);
    }
    private function event2Handler(e:MouseEvent):void
    {
           trace(’button’);
           e.stopPropagation();
           e.stopImmediatePropagation();
    }
    private function event3Handler(e:MouseEvent):void
    {
           trace(’button2′);
    }
    private function event1Handler(e:MouseEvent):void
    {
           trace(’out’);
    }

    e.stopPropagation(); e.stopImmediatePropagation(); 두가지 다 없을경우
            button
            button2
            back
            out
    e.stopPropagation(); 만 실행
            button
            button2
            out
    e.stopImmediatePropagation(); 만 실행
            button
            out

9. addEventListener의  useCapture 인자는 무엇을 의미하는가? 간단한 예제를 들어 설명하라.

  • 이벤트 전파를 청취할때 캡처단계를 청취할지 타겟 및 버블 단계를 청취할지 결정하는 인자이다.
  • 모든 전파 단계에서 청취하기 위해서는 useCapture가 다른 2개의 addEventListener()를 사용해야한다.
  • 예제 생략

10. Sprite, Shape와 같은 클래스에서 어떻게 하면 이벤트를 송출할 수 있는가?

  • dispatchEvent() 메소드를 호출하면 된다.

11. Sprite, Shape와 같이 이벤트 송출할 수 있는 클래스는 근본적으로 어떤 클래스를 상속받았기 때문에 가능한가?

  • Sprite와 Shape는 궁극적으로 DisplayObject를 확장해서 만들어졌으며 DisplayObject는 EventDispatcher를 확장했다. 그러므로 Sprite와 Shape와 같은 클래스는 EventDispatcher의 메소드를 전부 사용할 수있다. 이중에 dispatchEvent()도 사용할 수 있다.

12. IEventDispatcher는 무엇이며 어떤 경우에 이것을 사용해야할까?

  • EventDispatcher의 인터페이스이다.
  • IEventDispatcher를 활용하는 것은 다중상속이 불가능한 AS3에서 유용하다.
    가령, 어떤 클래스가 ProxyObject를 확장해서 만들어져야한다. 그런데 이 클래스는 이벤트도 발생시켜야 하므로 EventDispatcher클래스도 확장해야한다. ActionScript 3.0은 다중상속을 지원하지 않는다.(다중상속은 이점도 있지만 단점도 있다.) 그러므로 이러한 경우에는 주가 되는 클래스인 ProxyObject를 is-a 확장을 하고 EventDispatcher를 has-a 확장을 감행한다음 만들어진 클래스가 EventDispatcher의 기능을 수행한다는 것을 명시적으로 외부에 알려주고 내부적으로 구현시켜주기 위해 IEventDispatcher 인터페이스를 implements 해준다. 이렇게 하면 원하는 기능인 ProxyObject와 EventDispatcher의 기능을 전부 수행하면서도 다중상속의 문제를 극복할 수 있다.
  • ex)
    public class MyProxyObject extends ProxyObject implements IEventDispatcher
    {
      var evnetDispatcher:EventDispatcher = new EventDispatcher();
     
      //내부적으로 IEventDispatcher에 선언한 메소드를 구현한다.  가령…
      public function dispatchEvent( event:Event ):Boolean
      {
         return  eventDispatcher.dispatchEvent( event );
      }
    }

13. preventDefault()와 stopPropagation(), stopImmediatePropagation()의 근본적 차이점은 무엇인가?


  • preventDefault()는 기본 동작(dafault behaviors)를 취소하는데 쓰이는 메소드인 반면 stopPropagation(), stopImmediatePropagation()는 이벤트 전파에만 영향을 준다.

  • preventDefault()가 사용 가능한지는 isDefaultPrevented() 메소드로 알 수 있다.

14. preventDefault()를 호출해서 실행을 가능하게 하기 위한 조건은 무엇인가?

  • 이벤트 객체를 생성시 cancelable속성이 true로 설정되어 있어야 한다.

15. 커스텀 이벤트를 만들어야하는 어떤 경우이며 어떻게 만드는가?

  • 커스텀 이벤트는 기본 이벤트 클래스(flash.events.Event) 또는 그 상위 이벤트 클래스를 확장하는 경우를 의미한다.
  • 이벤트를 확장해야하는 경우는 이벤트 송출시에 필요한 정보를 담아내기 위함이다.
  • 만드는 방법
    class MyEvent extends Event
    {
      public static const MY_EVENT:String = “myevent”;
      public var value:String;
      public function MyEvent( type:String, value:String ):void
      {
         super( type, false, false );
         this.value = value;
      }
      overide public function clone():Event
      {
        return new MyEvent( type, value );
      }
    }

16. 커스텀 이벤트가 bubbling이 가능하기 위해 어떤 조건이 필요한가?

  • Event의 생성자의 2번째 인자인 bubble값을 true로 설정한다.

17. 커스텀 컴포넌트 만들때 clone()함수를 override해야하는 이유는 무엇인가?

  • clone()메소드는 기존과 신규 properties들을 clone 내로 설정해 이벤트 객체의 복사본을 돌려준다.
    clone() 메소드를 Event 클래스 확장시 오버라이드 해야하는 이유는 이벤트를 다시 재전달해야하는 경우 묵시적으로 복사해서 재전달할 필요가 있을때 필요하기 때문이다.

  • 참고로 toString()도 확장해서 사용하는 것이 좋다. 이벤트에 대한 명세서가 될 수 있기 때문이다.

18. 약참조에 대해서 GC(가비지 콜렉션)과 관련되어 설명하라.

  • addEventListener()함수로 이벤트 청취자를 등록할때 5번째 인자로 useWeakReference 인자가 있다. 이것을 true로 설정하면 이벤트 청취자가 이벤트 청취를 약참조를 하겠다는 의미이다. 반대로 false(기본)이면 강참조이다.
  • 약참조, 강참조를 설명하기 전에 가비지 콜렉션(GC, Garbage Collection)에 대해서 먼저 알아야한다.
    만들어졌던 객체가 더이상 쓸모가 없어졌을때 GC라고 한다. 쓸모가 없어졌다는 것은 참조의 고리가 끊어졌다는 것을 의미한다. 메모리에 상주해 있지만 조만간 메모리에서 없애야할 대상인 것이다. Flash Player는 GC로 선정된 객체들을 메모리에서 삭제하는 시점을 내부적으로 구현해놓고 있다.(많은 분들이 Flash Player GC처리를 못한다고 하지만 실제로는 문제없이 잘하고 있다. 단지 효율적으로 GC처리를 하는지는 의문이지만…)
    Flash Player GC 대상을 찾아내기 위한 방법은 2가지가 있다. 그것은 레퍼런스 카운팅(reference counting)과 마크 앤 스윕(Mark and Sweep)이다. 레퍼런스 카운팅은 생성된 객체가 참조할때마다 참조 카운트를 1씩 더해준다. 또 참조에서 끊어지는 경우 1씩 감소시켜준다. 만약 레퍼런스 카운팅 값이 0이되는 경우 바로 GC 대상이 되는 것이다. 마크 앤 스윕은 레퍼런스 카운팅 만으로 찾을 수 없는 GC대상을 찾아준다. 가령, 두개 이상의 객체가 서로 다른 객체를 참조하고 있다고 가정한다.(순환참조) 그럼 이들 레퍼런스 카운팅 값은 1 이상이다. 그러므로 레퍼런스 카운팅 방법으로는 GC대상을 만들 수 없다. 마크 앤 스윕은  이들 객체가 최상위 부모와 연결되어 있는지 검사하는 방법이다. 부모로 부터 꼬리에 꼬리를 물고 객체가 참조되어 있는 것인지 조사해나가는 방법으로 GC대상을 검색한다.
    레퍼런스 카운팅과 마크앤 스윕 방법으로 찾아낸 GC대상은 메모리에 상주되지만 Flash Player의 GC 삭제방법 로직에 의해 어느 순간 삭제된다.(이 시점은 프로그래머가 어찌할 수 없다. AIR 또는 Flash Player Debug버전의 경우에만 System.gc()를 이용해 강제적으로 GC를 메모리에서 삭제할 수 있긴 하다.)
  • addEventListener()의 useWeakReference를 true로 설정하면 약참조가 되어 레퍼런스 카운팅을 증가시키지 않는다. 강참조의 경우 이벤트 대상(target)의 참조를 지웠다고 해도 addEventListener로 등록한 청취자 메소드가 GC대상이 아니라면 이벤트 대상의 레퍼런스 카운팅 값은 0이 될 수 없다. 결국 프로그래머의 뜻과 다르게 메모리를 낭비하는 일을 초래할 수 있다. 물론 이벤트 대상이 사라지는 시점에 removeEventListener() 사용하면 되겠지만 때로는 그 시점을 모르는 경우도 발생한다. 이러한 경우 useWeakReference를 true로 설정해서 메모리 낭비를 없앨 수 있겠다.
  • Flex에서 List 계열의 컴포넌트를 살펴보면 dataProvider()에 ArrayCollection 객체를 받을때 ArrayCollection의 변화를 살펴보기 위해 addEventListener()를 사용한다. 그런데 ArrayCollection 객체는 언제 어떻게 될지 List 계열 컴포넌트는 알 수 없을 것이다. 이때 유용하게 사용하는 것이 바로 useWeakReference=true로 설정해서 필요없어진 ArrayCollection이 메모리 남는 것을 방지할 수 있다. 참고 : http://blog.jidolstar.com/375


19. 이벤트가 전파되는 중간에 전파를 멈추게 하기 위해 stopPropagation()을 사용하지 않고removeEventListener() 를 사용하면 안되는 이유를 설명하라. (힌트, ActionScript 3.0의 Native 메커니즘에 입각한다. http://bixworld.egloos.com/2149717)


  • 이벤트 송출을 시작하면 flash player는 이벤트가 송출될 디스플레이 객체 리스트를 전부 조사해 미리 이벤트 객체를 복사해두기 때문이다. 이미 전파할 대상이 모두 정해져있고 전파가 시행중인 경우에는 중간에 removeEventLisener를 사용하더라도 일단 송출된 이벤트는 끝까지 전파된다. 다음 시점 이벤트 송출시에는 removeEventLisener()가 적용되어 있는 상태가 된다.
 

 


20. willTrigger()와 hasEventListener()의 의미를 설명하고와 두 메소드의 차이점을 보여줄 수 있는 대한 예를 들어보자.

 



  • 공통점
    hasEventListener()이나 willTrigger() 모두 이벤트 청취자가 있는지 검사한다.
  • 차이점
    hasEventListener() : 지정한 객체에(만) 이벤트 청취자가 있는지 조사한다. 이벤트 흐름과는 무관하다.
    willTrigger() : 지정한 객체를 포함하는 디스플레이 객체 리스트에 해당 이벤트가 청취자가 있는지 조사한다. 그러므로 이벤트 흐름과 관련 있다.
  • 예제
    var button:Sprite = new Sprite();
    addChild( button );
    this.addEventListener( MouseEvent.CLICK, onClick );
    trace( button.willTrigger( MouseEvent.CLICK ) ); //true
    trace( button.hasEventListener( MouseEvent.CLICK ) ); //false ->왜 false가 되는가 아는게 중요!
    trace( this.willTrigger( MouseEvent.CLICK ) ); //true
    trace( this.hasEventListener( MouseEvent.CLICK ) ); //true
  • 이 두개의 함수를 잘 활용하면 쓸데없이 이벤트를 송출하는 경우를 방지할 수 있다.

21. ActionScript 3.0 이벤트에 대해 참고할 만한 문헌 및 자료를 조사하자.

AND

출처: http://deguls.tistory.com/

FLEX <-> Javascript 통신
보안샌드박스에러가 날땐 Object 태그에 allowScriptAcess 부분 설정을 변경해야 합니다.

HTML : sample.html
<script>
function SendToSWF(value){
    document.getElementById("externalcallswf").receive(value);
}
function Receive(value){
    document.getElementById("txtData").value = value;
}
</script>
<object id="externalcallswf" classid="clsid:.................>
<param name="무비경로" />
<param name="allowScriptAcess" value="allways" />
..
..
</object>


 

Flex : externalcalls.MXML
<?xml .... ?>
<mx:Application createComplete="initApp()" .....>
<mx:Script>
   <![CDATA[
    import flash.external.ExternalInterface;
    import flash.events.*;
    import mx.controls.Alert;

    private function initApp():void
    {
        if(ExternalInterface.available)
        {
             ExternalInterface.addCallback("receive", receive);
        }else{
            mx.controls.Alert.show("통신 불가..");
        }
    }

    private function receive(value:String):void{
            mx.controls.Alert.show(value);
    }

    private function sendToHTML(value:String):void{
           if(ExternalInterface.available)
           {
               ExternalInterface.call("Receive", value);
           }else{
               mx.controls.Alert.show("통신 불가..");
           }
    }
    ]]>
</mx:Script>


FLEX <-> C# (flex 부분은 상단과 동일 합니다.)
C# 어플리케이션에서 Flex나 Flash로 데이터를 보내거나 받으려면 아래와 같이 XML문서를 사용해야 합니다.
<invoke name="application name">
    <arguments>
        <string>문자열</string>
        <number>숫자형</number>
         ......
    </arguments>
</invoke>

Flash Object 참조방법 (단 플래시 플레이어가 Debug 버젼일 경우 윈폼 디자이너에 로드되지 않습니다.)
1. 참조 -> com -> Shockwave Flash 참조 추가
2. 도구상자 마우스 오른쪽 버튼 항목 선택 -> com 구성요소 -> Shockwave Flash 체크

C# Application
...
// 인보크 메세지 수신 이벤트 등록
this.axFlash.FlashCall += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(this.axFlash_FlashCall);
...

// SWF로 데이터 전달
private void SendToSWF(string strData, int intData){
    string invokeXmlData = "<invoke name=\"TansInformation\"><arguments>";
    invokeXmlData += "<string>" + strData + "</string>";
    invokeXmlData += "<number>" + intData.ToString() + "</number>";
    invokeXmlData += "</arguments></invoke>";
    try
    {
         this.axFlash.CallFunction(invokeXmlData);          
     }catch{
         MessageBox.Show("인보크 메세지 전달 실패 \r\n\r\n" + invokeXmlData);
    }
}

// 플래시 전송 이벤트 수신
private void axFlash_FlashCall(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)
{
    // xml 데이터
    XmlDocument XmlDoc = new XmlDocument();
    XmlDoc.LoadXml(e.request);
    XmlNodeList ArgumentList = XmlDoc.GetElementsByTagName("arguments");
   
    string XmlArguments = "";
    for(int i = 0;i<ArgumentList.Count;i++)
    {
        XmlArguments += ArgumentList[i].InnerText + Environment.NewLine;
    }
    MessageBox.Show(XmlArguments);
}
AND

출처: http://playin.innori.com/4223

웹페이지에 동영상을 삽입할 때 호환성 문제로

<object>
          <param name="movie" value="movie.swf"></param>
          <embed src="movie.sef" type="application/x-shockwave-flash"></embed>
</object>

구조로 사용하는 것이 거의 관례화되었는데 (대표적으로 YouTube)

최근 웹표준에 관한 관심이 높아지면서 비표준 태그인 Embed를 제거하고 사용하는 방법이 알려졌다. 일종의 편법이라고 할 수 있는데, Object 태그에 다음 내용을 추가한다.

<object type="application/x-shockwave-flash" data="movie.swf" >
     <param name="movie" value="movie.swf" />
</object>

참고 <http://www.alistapart.com/articles/flashsatay> 이 분이 처음에 발명(?)한 듯.
AND

출처: http://lemonfish.egloos.com/4969635


xhtml 표준에 따라 기존에 사용되던 embed 태그가 폐기되고, 대신 object 태그를 사용하게 되었다.
그런데...

일반적으로 페이지에 flash 삽입시에 아래와 같은 형식을 사용하는데.

<object width="320" height="265">
   
<param name="movie" value="a.awf" />
    <embed src="a.swf" type="application/x-shockwave-flash" width="320" height="265">
</embed>
</object>

보시다 시피 object 태그와 embed 태그가 중첩되어 있다. 이것은 브라우저마다 object 태그를 먹는 놈이 있고, embed 태그를 먹는 놈이 있기 때문에 양쪽다 정상적으로 동작하도록 하는 일종의 hack 같은 거다.

그런데...
앞서 말했듯이 xhtml 에서는 embed 태그를 쓸 수 없기 때문에 정직하게 규칙을 지켜서 작성을 하면


<object width="320" height="265">
   <param name="movie" value="a.swf" />
</object>

위와 같은 모양이 된다. 하지만 위와 같이 할경우 IE 에서는 동작하겠지만 Firefox 에서는 동작하지 않는다. 커허... 그럼 어쩌라고... 그리하야 이를 절충한 방법이 아래의 코드다.

<object width="320" height="265" type="application/x-shockwave-flash" data="a.swf" >
    <param name="movie" value="a.swf" />
 </object>

AND

출처: http://blog.naver.com/wookacula?Redirect=Log&logNo=40019126416

6.1 JSTL(JSP Tag Library) 개요

작성자 : 진은영 ( 2004-07-28)

목차

6.1.1 JSTL이란

① JSTL이란
JavaServer Pages (JSP)는 J2EE 플랫폼을 위한 표준 표현 레이어(presentation-layer) 이다. JSP는 페이지 콘텐트를 동적으로 생성할 수 있는 스크립팅 엘리먼트와 액션을 제공한다. 스크립팅 엘리먼트는 프로그램 소스 코드가 JSP 코드에 포함될 수 있도록 한다.

< %
   out.println( "연습입니다." ) ;
% >


액션(actions)은 전산 작동을 JSP 페이지의 템플릿 텍스트를 구성하고 있는 HTML 이나 XML과 거의 흡사하게하는 태그로 인캡슐한다. JSP 스팩에 표준으로 정의된 몇 가지의 액션들이 있다.

< jsp:useBean id="h" class="kr.co.a.HelloBean" />


하지만 JSP 1.1 부터 개발자들은 커스텀 태그 라이브러리 형태로 자신만의 액션들을 만들 수 있다.

JSP Standard Tag Library (JSTL)는 JSP 1.2 커스텀 태그 라이브러리 모음으로서 커스텀 태그 중에서 자주 사용되는 것을 모아서 표준으로 정한 것이다.

② JSTL과 일반 스크립트릿의 비교
물론, 스크립틀릿, 익스프레션, 선언 같은 JSP 스크립팅 엘리먼트를 사용하는 태스크를 구현할 수 있다. 그러나 페이지 내에 프로그램 소스 코드를 직접 장성하게 되면 소프트웨어 관리 태스크를 매우 복잡하게 하는 경향이 있다.

< %if ( a == 0 ){ % >
< %= a % >
< %} %>


위와 같이 복잡해 보이는 코드를 아래와 같이 줄일 수 있다.

< c:if test="${a==0}">
  < c:out value="${c}">
< /c:if>


JSTL은 일반적인 기능을 커스텀 태그 라이브러리의 표준 세트로 패키징했기 때문에 JSP 작성자들이 스크립팅 엘리먼트에 대한 필요를 줄이고 관련된 관리 비용을 피할 수 있도록 한다.


6.1.2 JSTL 설치

① JSTL 파일 다운로드
서블릿 컨테이너인 Tomcat의 버전이 4.x인 경우에는 아래의 장소에서 파일을 받아야 한다.

위치 : http://cvs.apache.org/builds/jakarta-taglibs/nightly/projects/standard-1.0/
파일 : jakarta-taglibs-standard-1.0-20040720.zip


② 압푹풀기
압축받은 파일을 워하는 위치에 푼다.


③ 복사
웹 애플리케이션을 하나 생성한다. 컨텍스트의 구조는 아래와 같다.


컨텍스트의 설정을 Tomcat의 server.xml 에 추가하는 것을 잊으면 안된다.

< Context path="/jstltest" docBase="E:/03.src/jslt" debug="0" reloadable="true" crossContext="true" />


압축받아 풀어놓은 폴더에서 아래의 jar 파일들을 복사해 현 컨텍스트에 가져다 놓는다.



이번에는 tld파일을 복사할 차례이다.




 

6.1.3 환경설정

필요한 파일들을 원하는 위치에 복사한 후 web.xml 파일에 지정만 하면 설정은 끝난다. web.xml은 해당 컨텍스트의 WEB-INF 폴더아래 있다.

< ?xml version="1.0" encoding="ISO-8859-1"?>
< !DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

< web-app>
 < taglib>
    < taglib-uri>jstl/core< /taglib-uri>
    < taglib-location>/WEB-INF/tld/c.tld< /taglib-location>
  < /taglib>
  < taglib>
    < taglib-uri>jstl/xml< /taglib-uri>
    < taglib-location>/WEB-INF/tld/x.tld< /taglib-location>
  < /taglib>
  < taglib>
    < taglib-uri>jstl/fmt< /taglib-uri>
    < taglib-location>/WEB-INF/tld/fmt.tld< /taglib-location>
  < /taglib>
  < taglib>
    < taglib-uri>jstl/sql< /taglib-uri>
    < taglib-location>/WEB-INF/tld/sql.tld< /taglib-location>
  < /taglib>  
< /web-app>



톰캣 데몬을 띄우고 브라우저를 띄운후 주소를 아래와 같이 입력한다.

참고문헌
AND

FLEX 란

flash 궁금하니? 2008. 8. 29. 09:03

출처: http://blog.naver.com/parkwon0204?Redirect=Log&logNo=70028914648


첨부파일 (1)


Xml 태그로 된 스크립트를 작성하여 플래시로 된 화면을 만들 수 있는 RIA(Rich Internet Application) 개발 솔루션 이다.



[FLEX 간략소개]


 개발 툴  FLEX Builder, 이클립스, 노트페드 ...
 개발 언어  액션 스크립트 3.0
 개발 방식  스크립트
 소스파일

 MXML 파일 (Magic eXtensible Markup Language : 위키메디어 참조)

 실행파일  SWF파일
 실행환경  플래시 플레이어 9.0
 용도  RIA 애플리케이션 개발


[FLEX 구성]


플렉스 데이터 서비스

기능 : 서버와 클라이언트 간에 데이터를
              실시간 으로 주고받는 서버기술
사용 : 관리 프로그램이나 채팅 프로그램에
              적용 하여 실시간으로 데이터가
              변하는 모습을 볼 수 있다.
용도 : 실시간/대량 데이터 처리

플렉스 빌더

기능 : 코드힌트, 디자인 뷰와 코드 뷰
사용 : 이클립스 기반으로 되어있어 플러그
             인으로 설치하여 기존의 자바개발
             환경에 융합하여 사용,또는 독립
용도 : 프로그램 개발

플렉스 sdk

기능 : 플렉스 컴파일러와 디버깅 제공
사용 : mxmlc을 이용하여 컴파일,
              컴파일의 결과로 SWF 생성
용도 : 플렉스 애플리케이션 개발

플렉스 차팅

기능 : 기존 차트 컴포넌트의 확장판
사용 : 플렉스 데이터 서비스와 연동하여
              동적인 데이터를 보여줄 수 있다.
용도 : 플렉스 차트 컴포넌트 라이브러리


(첨부화일 : 첨부화일에는 어도비에서 제공한 FLEX 기술백서(2.0)가 포함되어 있습니다.)

[출처] FLEX란 ?|작성자 원사마

AND

출처: http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/lcds/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=jsptaglib_1.html



Using the Flex 2 Tag Library for JSP

In an Adobe LiveCycle Data Services ES web application, complete the following steps to use the Flex 2 Tag Library for JSP in a JSP page:

  1. Add the following tag library declaration to your JSP page:
    <%@ taglib uri="FlexTagLib" prefix="mm" %>
    
  2. Use the <mxml> tag to insert a Flex application in an existing JSP page. The following example shows the <mxml> tag with the source attribute to include an external MXML file:
    <mm:mxml source="CustomerServiceChat.mxml"/>
    

    Alternatively, you can use the <mxml> tag with inline MXML source code, as the following example shows:

    <mm:mxml>
        <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
            <mx:Text label="Hello World">
        </mx:Application>
    </mm:mxml>
    

Use the <mxml> tag carefully, as any JSP execution that results in different MXML source code causes recompilation. Each distinct instance of MXML source code is cached separately and checked for recompilation separately. Two or three distinct versions of MXML source code might be acceptable, but different MXML source code on each compilation would not be.

For example, the following JSP code results in two sets of MXML source code; one is created when request.isUserInRole("admin") is true, and another is created when request.isUserInRole("admin") is false:

<mm:mxml>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
        <% if (request.isUserInRole("admin")) { %>
        <AdminConsole/>
        <% } else { %>
        <UserConsole/>
        <% } %>
    </mx:Application>
</mm:mxml>

Use the <mxml> and <flashvar> tags to quickly create a dynamic application. Updating the <flashvar> tag does not cause a recompilation. Although the MXML code was specified inline, the source is static without JSP scriptlets.

The following example uses <mxml> and <flashvar> tags with inline MXML code to get the Java version and current date:

<%@ taglib uri="FlexTagLib" prefix="mm" %>
<mm:mxml height="300" width="600" usePlayerDetection="true" useExpressInstall="false" >
      <mm:flashvar name="javaVersion" value='<%= System.getProperty("java.version") %>' />
    <mm:flashvar name="currentDate" value="<%= new java.util.Date().toString() %>"/>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" >
        <mx:VBox>
        <mx:HBox>
            <mx:Label text="Java version: "/>
            <mx:Label
                    text="{Application.application.parameters.javaVersion}" fontWeight="bold"/>
        </mx:HBox>
        <mx:HBox>
            <mx:Label text="Current Time: "/>
            <mx:Label text="{Application.application.parameters.currentDate}"
                    fontWeight="bold"/>
        </mx:HBox>
        </mx:VBox>
        </mx:Application>
</mm:mxml>

The following example shows how to invoke an external MXML file while passing dynamic flash variables to it:

<%@ taglib uri="FlexTagLib" prefix="mm" %>
<mm:mxml source="flashvarTest.mxml" width="400" height="200">
  <mm:flashvar name="javaVersion" value='<%= System.getProperty("java.version") %>' />
  <mm:flashvar name="currentDate" value="<%= new java.util.Date().toString() %>"/>
</mm:mxml>

Use the <mxml> tag attributes to present a Flex application when the correct version of Flash Player is available or an alternate version of the application when the player is unavailable.

In this example, you enable Flash Player Detection but disable the Express Install. With this configuration, the JSP drops directly to the alternateContentPage instead of proceeding to upgrade Flash Player through Express Install.

<mm:mxml source="FlexApplication.mxml" usePlayerDetection="true"
useExpressInstall="false" alternateContentPage="MyLegacyApplication.html"/>

Limitations

If you use the Flex 2 Tag Library for JSP incorrectly, overall application performance can suffer because of excessive recompilation. In general, there are no performance concerns if you use the <mxml> tag and compile MXML source code by using the source attribute.

The following alternative approaches do not modify the actual MXML code that a JSP page generates and do not cause excessive recompilations. Before deciding to use the tag library with your application with inline MXML source code, consider whether one of the following options would be more appropriate:

  • Separate the presentation from the data so that you can use LiveCycle Data Services to populate the data in the application.
  • Pass in the dynamic data by using the <flashvar> tag. You can safely use different name-value pairs on the <flashvar> tag for each JSP page execution, because the differences do not cause a modification and recompilation of the MXML source code.
  • Manipulate the presentation by using ActionScript.

Flex 2 Tag Library for JSP reference

Tag

Description

Attributes

mxml

Compiles the MXML code and generates the HTML wrapper. Includes MXML source as body content, or specify an external source file with the source attribute.

source  Location of the MXML code to compile.

id Name used to expose the SWF file through the id or name attribute of the HTML object or embed tag.

height Height of the MXML wrapper.

width Width of the MXML wrapper.

useHistoryManagement Include history management for the Flex application.

usePlayerDetection Include Flash Player detection for the Flex application.

useExpressInstall Install Flash Player through Express Install; ignored if Flash Player detection is disabled.

alternateContentPage Present this alternate page when the Flash Player version is unavailable; ignored if Flash Player detection is disabled.

flashvar

Specifies a variable to pass to your Flex application.

name Specifies the name of the flashvar variable.

value Specifies the value of the flashvar variable.


AND

출처 : http://mudchobo.tomeii.com/tt/tag/flex?page=15

저도 웹2.0에 뒤쳐지지 않기 위해서 flex를 공부하려고 합니다-_-; 우선 개발환경을 만들어봅시다.

준비물입니다.

JDK 6u2
http://java.sun.com/javase/downloads/index.jsp

Tomcat6.0
http://tomcat.apache.org/download-60.cgi

Flex Builder 2 (요고이 유료입니다! 돈내고 사셔야합니다-_-; 평가판 주소입니다.)
아래 사이트를 들어가셔서 adobe홈페이지에 가입하고 다운로드 하셔야합니다.
https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex&loc=ko

LiveCycle DataService ES Express(원래 이름이 Flex DataService 2인가 그랬을 껍니다-_-;)
이건 Express버전으로 하면 무료입니다. 아래사이트도 로그인 후 다운로드 가능합니다.
http://www.adobe.com/cfusion/tdrc/index.cfm?product=flex

준비물이 다 되었으면 설치를 해 봅시다.
JDK는 뭐 다음신공으로 설치를 해줍시다.

Tomcat은 6.0으로 설치 버전이든, zip버전이든 어떻게든 설치를 해서 서버만 돌아가도록 합시다-_-;
zip버전에서는 JAVA_HOME이라는 환경변수가 있어야합니다. 자바가 설치된 디렉토리를 지정해주면 됩니다.

Flex Builder 2설치할 때  두개 중 한개를 선택하라는 부분이 있는데요.

사용자 삽입 이미지

위와 같이 나오는데
첫번째는 Flex Builder를 그냥 설치하겠다는 것인데 즉 자체적인 이클립스를 사용한다는 겁니다.
두번째는 기존에 사용하던 이클립스를 플러그인 형식으로 설치를 해서 기존의 이클립스를 사용한다는 겁니다.
첫번째로 하도록 합시다. 그냥 따로 씁시다-_-;

그다음 뭐 그냥 다음 신공으로 설치를 합시다.

LiveCycle Data Services는 설치할 때 Installation Options에서
사용자 삽입 이미지

두가지 선택문이 나오는데
첫번재는 JRun이라는 서버를 사용하겠다는 것이고,
두번째는 J2EE용 web application을 사용하겠다는 것인데, 톰캣을 써야하기 때문에 두번째꺼를 선택합시다.
(JRUN은 안해봤습니다-_-;)

다 설치를 한 다음에 설치된 폴더(디폴트로 c:\lcds)에 flex.war, sample.war, flex-admin.war 파일이 3개가 있는데 이것을 톰캣폴더에 있는 webapp폴더에 복사해줍시다.

톰캣은 WAR파일을 폴더에만 복사해두면 작동하면 자동으로 Deploy합니다 ^^

자 그러면 톰캣을 가동해봅시다.
가동이 완료되면 주소창에 http://localhost:8080/flex/ 이라고 적어봅시다.
사용자 삽입 이미지

위 그림처럼 뜨면 설치가 성공한겁니다 ^^
샘플도 실행해봅시다. http://localhost:8080/samples/dashboard/dashboard.mxml 를 실행해봅시다.
사용자 삽입 이미지

위와 같이 멋진 샘플화면이 뜰 껍니다 ^^

설치를 했다는 데에 의의를 둡시다-_-; 다음시간에는 헬로우월드(HelloWorld!)를 찍어봅시다-_-;

ps. 근데 저 샘플화면을 실행했을 때 플레쉬플레이어를 설치하라고 나와서 다시 설치를 했는데도 또 설치하라고 나오면 언인스톨하고 다시 설치하면 됩니다 ^^
2007/09/02 21:00 2007/09/02 21:00
AND

출처: http://urassa.tistory.com/24


포털 환경에서 Macromedia Flex 사용


포털은 통합 사용자 인터페이스에서 컨텐츠의 집계가 원활하게 이루어지도록 합니다. 그러나 일반적으로 포틀릿은 HTML로 렌더링되므로 어플리케이션을 구축할 때 HTML의 한계를 이어받게 됩니다. 페이지를 새로 고쳐야 하는 번거로움, 상태 전환이 없는(stateless) 클라이언트, 스마트 클라이언트측 데이터 조작의 부재, 제한적인 사용자 인터페이스 구성 요소 등이 그 한계라고 할 수 있습니다.

더 많은 수의 포털 고객들이 포털과 일반적인 어플리케이션의 사용자 경험을 보다 매력적으로 향상시켜 HTML의 한계를 극복하는 솔루션을 원하고 있습니다.

Macromedia Flex는 이러한 요구를 충족하는 프레젠테이션 서버로서 이 서버를 사용해 개발자는 데스크탑 어플리케이션의 사용성과 일반 웹 어플리케이션의 광범위함을 접목시킨 차세대 어플리케이션인 리치 인터넷 어플리케이션(RIA: Rich Internet Applications)을 구축할 수 있습니다. Flex를 사용하여 포틀릿의 사용자 인터페이스를 렌더링할 수 있으며 포털 내의 사용자 경험을 크게 향상시킬 수 있습니다.

본 백서는 Flex 프레젠테이션 서버를 사용하여 포털 어플리케이션에 풍부한 프런트 엔드를 제공하는 방법에 대해 설명합니다.

정보Macromedia Flex에 대한 자세한 내용

PDF 버전의 기술문서

배경 정보

포털이란?

포털이란 통합 사용자 인터페이스에서 서로 다른 소스의 컨텐츠를 모아주는 웹 어플리케이션을 의미합니다. 또한 포털은 일반적으로 내장된 자체 보안 인프라를 통해서나 Netegrity SiteMinder와 같은 타사 솔루션을 통합하여 SSO(Single Sing-On) 및 개인화된 기능을 제공합니다.

포틀릿이란?

포틀릿이란 Java 기반의 웹 구성 요소로서 포틀릿 컨테이너에서 관리합니다. 한편 포털은 플러그 가능한 사용자 인터페이스 구성 요소로 포틀릿을 사용합니다. 포틀릿의 컨텐츠는 일반적으로 HTML 또는 기타 마크업 언어로 렌더링되며 다른 포틀릿의 컨텐츠와 집계되어 포털 페이지를 형성합니다.

포틀릿 컨테이너란?

포틀릿 컨테이너는 포틀릿에 런타임 환경을 제공합니다. 포털은 포틀릿에서 요청을 실행할지 여부를 포틀릿 컨테이너에게 묻습니다. 포틀릿에서 생성한 컨텐츠를 집계하는 작업은 포틀릿 컨테이너가 하지 않고 포털에서 합니다.

포털 벤더

포털 벤더는 다음과 같습니다.

  • IBM
  • BEA
  • Oracle
  • Sun
  • Vignette
  • SAP
  • Plumtree

JSR-168이란?

과거 각기 다른 벤더들은 자체적으로 제작한 API를 통해 포틀릿을 개발했으며 해당 포틀릿을 실행하기 위해 런타임 환경을 구축했습니다. 이렇게 개발된 각양각색의 API는 서로 호환되지 않았으므로 ISV와 포털 고객들에게는 새로운 문제로 부각되었습니다. 이러한 문제를 해소하기 위해 고안된 것이 바로 JSR-186(Java Standardization Request 168)으로 그 취지는 포틀릿을 개발하고 실행할 때 필요한 표준을 확립하기 위한 것이었습니다. JSR-168의 등장에 힘입어 개발자들은 JSR-186 표준 준수 컨테이너에서 배포할 수 있는 포틀릿을 개발할 수 있게 되었습니다.

JSR-168에 대한 자세한 내용은 Java Community Process 웹 사이트인 www.jcp.org/en/jsr/detail?id=168*을 참조하십시오.

JSR-168 표준 채택

대부분의 포털 벤더는 JSR-168 스펙을 구현했거나 현재 구현하고 있습니다. 역호환의 경우 포털 벤더는 여전히 자신의 "pre-JSR 168" API를 지원하고 있습니다. IBM의 예를 들면 WSAD Portal Toolkit와 WebSphere Portal Server를 사용해 IBM의 API 기반 포틀릿과 JSR 168 기반 포틀릿을 모두 개발하고 실행할 수 있습니다.

JSR-168과 IBM API의 차이점에 대한 자세한 내용은 IBM의 Stefan Hepper가 쓴 www-106.ibm.com/developerworks/websphere/library/techarticles/0312_hepper/hepper.html* 기술문서를 참조하십시오.

본 기술문서에서 설명한 Flex/포털 통합은 JSR-168 준수 포털 서버, IBM API 기반 포틀릿이 포함된 WebSphere Portal Server, 일부 코드가 수정된 "pre-JSR 168" 벤더의 API 등에 모두 적용할 수 있습니다.


포털 환경에서 Macromedia Flex 사용하기

포털은 통합 사용자 인터페이스에서 컨텐츠의 집계가 원활하게 이루어지도록 합니다. 그러나 일반적으로 포틀릿은 HTML로 렌더링되므로 어플리케이션을 구축할 때 HTML의 한계를 이어받게 됩니다. Flex를 사용하여 포틀릿의 사용자 인터페이스를 렌더링하면 HTML의 한계를 극복할 수 있고 포털 내의 사용자 경험을 크게 향상시킬 수 있습니다.

예제

5개의 Flex 기반 포틀릿을 보여주는 Websphere 포털 페이지

그림 1. 5개의 Flex 기반 포틀릿을 보여주는 Websphere 포털 페이지

위에서 표시된 포털 페이지는 5개의 Flex 기반 포틀릿을 보여줍니다. 아래 통합 시나리오의 설명과 같이 Flex 기반 포틀릿도 HTML 기반의 포틀릿과 함께 존재합니다.

  • Mutual Fund Selector 포틀릿: 풍부한 사용자 상호 작용에 대한 예입니다. 이 포틀릿에서 사용자는 슬라이더와 다른 컨트롤을 사용하여 선택 기준을 지정할 수 있습니다. 지정한 기준에 부합하지 않는 뮤추얼 펀드는 자동으로 희미하게 표시됩니다. 사용자가 포인터를 심볼 위에 올려 놓으면 해당 뮤추얼 펀드에 대한 자세한 정보가 표시됩니다.
  • Real-Time Market Data 포틀릿: 실시간 주식시장 데이터 피드와 연결되어 있는 포틀릿의 예입니다. 차트에 표시된 선은 데이터 피드에서 수신된 새로운 데이터를 반영하기 위해 자동으로 조절됩니다.
  • Portfolio 포틀릿: DataGrid(필요에 따라 정렬 및 편집 가능), 아코디언 내비게이션 컨테이너 등 리치 사용자 인터페이스 구성 요소를 보여주는 포틀릿의 또 다른 예입니다. 사용자가 이 포틀릿을 최대화하면 주식 시황을 확인할 수 있고 특정 주식을 관리 대상 목록으로 드래그할 수 있습니다.
  • Video 포틀릿: MediaPlayback 구성 요소를 사용하여 완벽하게 통합된 방식으로 포털 내에서 비디오를 스트리밍할 수 있습니다. 이때 타사 플레이어는 필요하지 않습니다.
  • Chat 포틀릿: 서버에서 클라이언트로 전송된 데이터의 예입니다.

이점

포털 환경에서 Flex를 사용하여 얻을 수 있는 이점은 다음과 같습니다.

  • 향상된 사용자 경험
    • 데스크탑에서와 같은 사용자 경험을 갖춘 포틀릿을 제공할 수 있습니다.
    • Flex에서 DataGrid, 트리, TabNavigator, 아코디언, 차트 구성 요소, 슬라이드 등과 같은 리치 사용자 인터페이스 구성 요소를 사용할 수 있습니다.
    • Flex에서 드래그 앤 드롭, 필요한 곳에 확장 기능 추가 등과 같은 리치 사용자 인터페이스 메타포를 사용할 수 있습니다.
  • 불필요한 페이지 새로 고침

    참고: 포털 페이지를 새로 고치게 되면 사용자의 집중력은 감소하고 리소스와 대역폭 측면에서도 비용이 많이 소요됩니다. 기존 HTML 기반의 포틀릿과는 달리 Flex 기반의 포틀릿은 페이지를 새로 고치지 않고도 백 엔드 시스템과 통신할 수 있습니다.

  • 스마트 클라이언트측 데이터 조작
    • 일단 서버에서 다운로드된 데이터는 클라이언트측에서 조작할 수 있습니다. 예를 들어 클라이언트에서 검색된 항목들을 클라이언트측에서 정렬하거나 필터링할 수 있습니다. 이는 사용자 인터페이스의 응답성을 향상시키고 네트워크 트래픽을 줄이는 이점으로 이어집니다.
    • XMLSocket API나 Flash Communication Server를 사용해 데이터를 서버에서 클라이언트로 전송할 수도 있습니다.
    • 특정 어플리케이션의 상황에 맞을 경우 데이터를 클라이언트측에 저장할 수도 있습니다.
  • 네트워크 트래픽 감소

    페이지를 새로 고치지 않고도 백 엔드 시스템과 통신할 수 있고 클라이언트측에서 데이터를 조작할 수 있기 때문에 Flex 기반의 포틀릿은 전반적인 네트워크 트래픽을 크게 감소시킬 수 있습니다.

통합 시나리오

포틀릿 스펙은 다음과 같이 3가지 유형의 창 상태를 정의합니다.

  • 일반: 이 상태의 포틀릿은 일반적으로 다른 포틀릿과 페이지를 공유하므로 이 창 상태에서 렌더링되는 출력의 크기를 제한해야 합니다.
  • 최대화: 이 상태의 포틀릿은 일반적으로 포털 페이지에 렌더링되는 유일한 포틀릿입니다. 포틀릿은 창 상태가 최대화되면 보다 풍부한 컨텐츠를 생성할 수 있습니다.
  • 최소화: 포틀릿의 제목 표시줄만 표시됩니다.

일반 창 상태에서 Flex 기반의 포틀릿과 HTML 기반의 포틀릿은 동일한 포털 페이지에 함께 존재할 수 있습니다. 또한 포틀릿이 동일하더라도 현재 창의 상태에 따라 다른 렌더링 기술을 사용할 수 있습니다.

  • 예를 들어 포틀릿의 창 상태가 일반 상태인 경우 포틀릿의 UI는 HTML로 표시되고 최대화 상태인 경우 Flex로 표시될 수 있습니다.
  • 이와 상반되는 경우도 가능합니다. 즉, 일반 상태의 경우에는 Flex로, 최대화 상태의 경우는 HTML로 표시될 수 있습니다. 그러나 사용자는 대개 최대화 상태에서 가장 정교한 사용자 경험을 기대하기 때문에 이런 경우는 의미가 없습니다.
  • 마지막으로 포틀릿의 UI는 일반 및 최대화 상태에서 모두 Flex로 표시될 수 있습니다. 일반 상태에서 실행되는 포틀릿 크기가 아무리 작더라도 Flex를 사용하면 큰 이점을 볼 수 있습니다. 주식 시황 포틀릿을 예로 들어 보겠습니다. 기존의 HTML에서 이 포틀릿을 구현할 경우 사용자가 시세를 요청할 때마다 전체 포털 페이지가 새로 고쳐져야 합니다. 이렇게 단순한 작업에 값비싼 프로세스가 아닐 수 없습니다. 그러나 Flex 기반의 포틀릿을 사용하면 포털 페이지를 새로 고치지 않고도 백 엔드 시스템에서 데이터를 가져올 수 있습니다. 나중에 Flex 기반의 주식 시황 포틀릿의 예를 설명하겠습니다.

일반 상태의 Portfolio 포틀릿

그림 2. 일반 상태의 Portfolio 포틀릿

최대화 상태의 Portfolio 포틀릿

그림 3. 최대화 상태의 Portfolio 포틀릿

최대화 창 상태를 사용하여 복잡하고 독립적인 Flex 어플리케이션을 실행할 수 있습니다. 아래 스크린샷은 Flex로 패키징된 FlexStore 샘플 어플리케이션이 최대화된 상태에서 포틀릿으로 실행되고 있는 모습입니다.

Flex로 패키징된 FlexStore 샘플 어플리케이션이 최대화된 상태에서 포틀릿으로 실행되고 있는 모습

그림 4. Flex로 패키징된 FlexStore 샘플 어플리케이션이 최대화된 상태에서 포틀릿으로 실행되고 있는 모습

포틀릿 스펙은 뷰 모드(포틀릿에서 구현되어야 하는 유일한 모드), 편집 모드, 도움말 모드 등 3가지 포틀릿 모드를 정의합니다. 창 상태에서처럼 포틀릿의 사용자 인터페이스를 렌더링할 때 서로 다른 모드에서 Flex와 HTML 기술을 혼용하여 사용할 수 있습니다. 즉, 뷰 모드에서 Flex를, 도움말 모드에서는 HTML을 사용할 수 있습니다.


기술 구현

포틀릿의 사용자 인터페이스 렌더링하기

사용자가 포털 페이지를 요청할 경우 포털은 포틀릿 컨테이너에게 페이지의 각 포틀릿에 대한 사용자 인터페이스를 생성하도록 요구합니다. 포털은 포틀릿이 생성하는 조각들을 모아 페이지를 만든 다음 사용자가 볼 수 있도록 해당 페이지를 클라이언트에게 반환합니다.

특정 포틀릿의 사용자 인터페이스를 생성하려면 포틀릿 컨테이너는 포틀릿의 render() 메서드를 호출합니다. GenericPortlet에서 render() 메서드는 포틀릿 모드에 따라 메서드 호출을 doView(), doEdit() 또는 doHelp() 메서드로 보냅니다. 이러한 메서드는 보통 포틀릿 조각에 대한 마크업을 정의하는 JSP(JavaServer Page)에 요청을 보내기 전에 사용자 인터페이스와 관련된 로직을 실행합니다.

Flex는 이 워크플로에 완벽하게 통합됩니다. Flex를 사용해 포틀릿 사용자 인터페이스를 렌더링할 때 가장 두드러진 특징은 JSP에서 기존의 HTML 마크업을 작성하지 않고 Flex 어플리케이션을 단지 JSP에 임베드하면 된다는 것입니다. Flex 어플리케이션을 JSP에 쉽게 임베드하는 방법은 Flex와 함께 제공하는 JSP 태그 라이브러리의 MXML 태그를 사용하는 것입니다(아래의 helloworld.jsp 참조). 또한 HTML Object 태그를 코딩하여 Flex 어플리케이션을 페이지에 임베드할 수도 있습니다.

참고: Flex JSP 태그 라이브러리를 사용하면 JSP에 Flex 마크업 언어인 MXML을 입력할 수 있습니다. 이는 외부 MXML 파일을 지정하는 것과 전혀 다른 방법입니다.

다음 예제는 Flex 기반의 Hello World 포틀릿을 보여줍니다.

리스팅 1: HelloWorldPortlet.java

package samples.portlet;

import javax.portlet.*;
import java.io.IOException;

public class HelloWorldPortlet extends GenericPortlet {

    public void doView (RenderRequest request, RenderResponse response)
            throws PortletException, IOException {

        response.setContentType("text/html");
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/jsp/helloworld.jsp");
        rd.include(request,response);

    }

}

리스팅 2: helloworld.jsp

<%@ taglib uri="FlexTagLib" prefix="mm" %>
<mm:mxml source="/jsp/helloworld.mxml"/>

리스팅 3: helloworld.mxml

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" width="200" height="100">

    <mx:Label text="Hello World!"/>

</mx:Application>

물론 "Hello World!"를 표시하기 위해 Flex가 반드시 필요한 것은 아닙니다. 그러나 리치 사용자 인터페이스를 제작하기 위해서는 Flex가 있어야 한다는 얘기입니다. 이제 helloworld.mxml을 수정하여 포털 어플리케이션에서 포틀릿으로 렌더링되는 완벽한 리치 인터넷 어플리케이션(DataGrid, 트리, 차트 구성 요소, 드래그 앤 드롭 비헤이비어 등을 사용함)을 제작할 수 있습니다.

데이터 액세스하기: 프런트 컨트롤러 모델

기존의 포틀릿 워크플로에서 포틀릿은 작은 프런트 컨트롤러 역할을 담당합니다. 즉, 프로세싱 동작과 사용자 인터페이스 렌더링에 대한 모든 요청은 포틀릿 URL을 사용하는 portlet 클래스를 통해 라우팅됩니다. 그런 다음 portlet은 해당 요청을 Model(예: JavaBean, EJB 또는 웹 서비스)과 View 구성 요소(예: JSP 또는 서블릿)로 위임합니다. 포틀릿 URL은 해당 포틀릿 컨테이너가 생성하는 불투명한 URL입니다. 포틀릿 URL에는 액션 URL과 렌더 URL, 두 가지 유형의 URL이 있습니다.

  • 클라이언트에서 액션 URL을 요청하는 경우 컨테이너는 대상 포틀릿에서 processAction() 메서드를 호출합니다. processAction() 메서드가 실행된 다음 컨테이너는 페이지의 모든 포틀릿에 대한 render() 메서드를 트리거하게 됩니다.
  • 한편, 클라이언트에서 렌더 URL을 요청하는 경우 컨테이너는 해당 페이지의 모든 포틀릿에서 render() 메서드를 호출합니다.

Flex가 포털의 백 엔드와 통신하기 위해 사용자 경험이나 광대역 측면에서 보다 효율적인 방법을 제공하고 있지만 Flex 기반의 포틀릿은 이러한 프런트 컨트롤러 워크플로를 지원하고 있습니다. 사용자는 액션 URL과 렌더 URL을 매개 변수로 Flex 어플리케이션으로 전달할 수 있습니다. 그러면 Flex 어플리케이션은 이러한 URL을 사용하여 기존 HTML 기반의 포틀릿 조각이 하는 방식과 같이 요청을 포털로 전송합니다.

다음 예제(리스팅 4)는 액션 URL과 렌더 URL을 사용하는 Flex 기반의 포틀릿을 보여줍니다.

리스팅 4: URLDemoPortlet.java

package samples.portlet;

import javax.portlet.*;
import java.io.IOException;

public class URLDemoPortlet extends GenericPortlet {

    public void doView (RenderRequest request, RenderResponse response)
            throws PortletException, IOException {

        response.setContentType("text/html");
        PortletURL actionURL = response.createActionURL();
        actionURL.setPortletMode(PortletMode.VIEW);
        request.setAttribute("actionURL", actionURL.toString());

        PortletURL renderURL = response.createRenderURL();
        renderURL.setPortletMode(PortletMode.VIEW);
        request.setAttribute("renderURL", renderURL.toString());
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/jsp/urldemo.jsp");
        rd.include(request,response);

    }

}

리스팅 5: urldemo.jsp

<%@ taglib uri="FlexTagLib" prefix="mm" %>

<mm:mxml source="/jsp/urldemo.mxml">
    <mm:param name="actionURL" value="<%= request.getAttribute("actionURL") %>" />
    <mm:param name="renderURL" value="<%= request.getAttribute("renderURL") %>" />
</mm:mxml>

참고: 기타 상황 정보를 Flex 어플리케이션으로 전달할 때 동일한 매개 변수 전달 기법, 즉 포틀릿 초기화 매개 변수, 환경 설정 등을 사용할 수 있습니다.

리스팅 6: urldemo.mxml

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*"
    height="300" width="800" backgroundColor="#FFFFFF">

    <mx:Script>
        var actionURL: String;
        var renderURL: String;
    </mx:Script>

    <mx:Label text="{actionURL}"/>
    <mx:Label text="{renderURL}"/>

    <mx:Button label="Request Action URL" click="getUrl(actionURL)"/>
    <mx:Button label="Request Render URL" click="getUrl(renderURL)"/>

</mx:Application>

이 예제에서 보여준 포틀릿 URL 워크플로는 주로 일반적인 요청/응답 모델에서 구동하는 HTML 클라이언트를 기반으로 합니다. 이 모델의 취약점은 페이지 중심의 모델이므로 사용자 인터페이스(이 경우 포털 페이지를 가리킴)는 각 클라이언트 요청에 대한 응답 때마다 페이지를 새로 고쳐야 하는 번거로움이 있다는 점입니다. 이러한 경우 사용자의 집중력은 저하될 뿐만 아니라 대역폭의 사용량도 최적화될 수 없습니다. 리치 클라이언트 기술을 사용하면 이러한 한계를 극복할 수 있습니다. 즉, HTTP를 통한 XML 또는 SOAP를 사용하면 사용자 인터페이스 페이지를 새로 고칠 필요 없이 SOA(서비스 지향 아키텍처)에서 백 엔드 서비스와 통신할 수 있습니다. SOA 방식에 대해서는 다음 섹션에서 다루도록 하겠습니다.

그러나 Flex 어플리케이션이 액션 URL과 렌더 URL을 사용할 수 있는 점은 유용할 때가 있습니다. 예를 들어 Flex 어플리케이션에서 렌더 URL을 사용하여 포틀릿 컨테이너에게 창 상태를 변경하도록 요청할 수도 있습니다.

데이터 액세스하기: SOA 모델

Flex 클라이언트는 서비스 지향 아키텍처에서 백 엔드 서비스와 통신할 수 있습니다. Flex는 어플리케이션의 특정 데이터 액세스 요구 사항을 충족시키기 위해 3가지 데이터 서비스를 제공합니다.

  • WebService 서비스: 이 서비스를 통해 클라이언트 어플리케이션은 SOAP 기반의 웹 서비스를 호출할 수 있습니다.
  • RemoteObject 서비스: 이 서비스를 통해 클라이언트 어플리케이션은 해당 객체를 웹 서비스로 공개하지 않고도 미들티어에 배포되어 있는 Java 객체의 매서드를 호출할 수 있습니다. 그러면 Flex RemoteObject 서비스는 나머지 작업을 하게 됩니다. 클라이언트와 서버 간의 통신 프로토콜로 SOAP와 AMF(HTTP를 통한 바이너리 프로토콜) 중에서 선택할 수 있습니다.
  • HTTPService 서비스: 이 서비스를 통해 클라이언트 어플리케이션은 HTTP를 통한 XML을 사용하여 서버와 통신할 수 있습니다.

다음 예제는 웹 서비스를 사용하는 Flex 기반의 주식 시황 포틀릿을 보여줍니다.

리스팅 7: StockQuotePortlet.java

package samples.portlet;

import javax.portlet.*;
import java.io.IOException;

public class StockQuotePortlet extends GenericPortlet {

    public void doView (RenderRequest request, RenderResponse response)
            throws PortletException, IOException {

        response.setContentType("text/html");
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/jsp/stockquote.jsp");
        rd.include(request,response);

    }

}

리스팅 8: stockquote.jsp

<%@ taglib uri="FlexTagLib" prefix="mm" %>
<mm:mxml source="/jsp/stockquote.mxml"/>

리스팅 9: stockquote.mxml

<?xml version="1.0" encoding="UTF-8"?>

<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml"
    width="300" height="200"
    backgroundColor="#FFFFFF">

    <mx:WebService id="ws"
        wsdl="http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl">
        <mx:operation name="getQuote">
            <mx:request>
                <symbol>{symbol.text}</symbol>
            </mx:request>
        </mx:operation>
    </mx:WebService>

    <mx:TextInput id="symbol"/>
    <mx:Button label="Get Quote" click="ws.getQuote.send()"/>

    <mx:Label text="{ws.getQuote.result}"/>

</mx:Application>

보안

Flex 어플리케이션은 Macromedia Flash 플레이어 샌드박스 환경을 활용합니다. 이 모델에서 클라이언트 어플리케이션은 어플리케이션을 수행하는 서버와 통신만 할 수 있습니다. 해당 서버에 있는 프록시 서블릿을 통해 위에서 설명한 데이터 액세스 서비스(WebService, RemoteObject 및 HTTPService)에 액세스합니다. 이 프록시 서블릿은 WebServices, HTTPServices 및 RemoteObjects에 대한 요청을 차단하여 해당 요청을 적절하게 리디렉션한 다음 클라이언트로 응답을 반환합니다. 기존의 J2EE 보안 API 또는 Netegrity SiteMinder와 같은 타사 보안 인프라를 통해 프록시 서블릿 URL에 안전하게 액세스할 수 있습니다.

포틀릿 세션에 액세스하기

Flex는 Flex 클라이언트 어플리케이션이 포틀릿 세션 객체의 속성에 액세스(설정 및 수신)할 때 사용할 수 있는 세션 API를 제공합니다.

리스팅 10: 다음 예제는 세션 속성값을 가져오고 설정하는 Flex 기반의 포틀릿을 보여줍니다.

<?xml version="1.0" encoding="utf-8"?>

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

    <mx:RemoteObject id="sessionObj" source="servlet" showBusyCursor="true"/>

    <mx:HBox>
        <mx:TextInput id="fromSession" text="{sessionObj.session.result}"/>
        <mx:Button label="Get userName Session Attribute" click="sessionObj.session('get', 'userName')"/>
    </mx:HBox>

    <mx:HBox>
        <mx:TextInput id="toSession"/>
        <mx:Button label="Set userName Session Attribute"
                   click="sessionObj.session('set', 'userName', toSession.text)"/>
    </mx:HBox>

</mx:Application>

배포 옵션

Flex 프레젠테이션 서버는 웹 어플리케이션으로 어플리케이션 서버 내에 배포할 수 있습니다. Flex를 포틀릿 웹 어플리케이션의 일부로 패키징하거나 별도의 웹 어플리케이션으로 배포할 수 있습니다. 본 기술문서에서 나열된 예제는 이러한 두 가지 구성 측면에서 테스트되었습니다.


요약

포털은 통합 사용자 인터페이스에서 컨텐츠의 집계가 원활하게 이루어지도록 합니다. 그러나 일반적으로 포털 어플리케이션에서의 사용자 경험은 HTML의 한계로 인해 제한을 받게 됩니다. Flex를 사용하여 포틀릿의 사용자 인터페이스를 렌더링하면 포털에서의 사용자 경험을 크게 향상시킬 수 있습니다.

관련 리소스

AND

출처 : http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_15683&sliceId=2#exampleas2

An example of communication between JavaScript and Adobe Flash Player

AND