Flex + Java w jednym projekcie w Flex Builderze – część II

31 Lipiec 2009 – 21:41

Czas na stworzenie prostej aplikacji wykorzystującej Jave (BlazeDS) i Flex w jednym projekcie Flex Buildera. Będzie to klasyczne “Hello World” :)

Wymagane oprogramowanie:

  • Flex Builder 3.0.2 – dostępny do ściągnięcia w wersji trial ze stron Adobe lub w specjalnej wersji dla studentów lub bezrobotnych programistów ze strony Free RIA Tools,
  • BlazeDS 3.2.0.3978 – dostępny na stronach Adobe Open Source (jest to wersja z samymi binariami – dostępna jest także wersja z zintegrowanym Tomcatem) – rozpakowujemy w dowolne miejsce, np.: C:\Work\BlazeDS
  • Tomcat 6.0.20 – dostępny na stronach Apache Software Foundation – rozpakowujemy w dowolne miejsce, np.: C:\apache-tomcat-6.0.20
  • BlazeMonster – bardzo przydatne narzędzie do testowania świeżo stworzonych metod BlazeDS – do ściągnięcia z bloga Sujit Reddy G.

Do dzieła!

Po odpaleniu Flex Buildera tworzymy nowy projekt wybierając w sekcji “Server technology” opcję “J2EE” i zaznaczając “Create combined Java/Flex project using WTP”:

FlexJava01

Następnym krokiem jest stworzenie lokalnej instancji serwera Tomcat – wskazujemy katalog z rozpakowanymi binariami Tomcata:

FlexJava02

FlexJava03

oraz wskazanie lokalizacji pliku blazeds.war:

FlexJava04

Następny ekran i projekt jest już utworzony:

FlexJava05

Struktura nowego projektu powinna przedstawiać się następująco:

FlexJava06

Katalog flex_src to nasz główny katalog ze kodem Flexa, src z kodem Java, a WebContent to nasz lokalny serwer WWW.
Aby upewnić się czy wszystko działa dodajmy do kodu Flexa kawałek prostego kodu:

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Label text="Hello World!" horizontalCenter="0" verticalCenter="0" />
</mx:Application>

i odpalmy całą aplikację na serwerze – klikamy prawym klawiszem myszy na projekcie wybieramy Run -> Run on Server, a następnie Next, Next, Finish:

FlexJava07

W oknie konsoli Flex Buildera widzimy logi uruchamianego Tomcata, a na koniec otrzymujemy przepiękny error HTTP Status 404 :)
Jednak nie ma się co zrażać! Wracamy do Flex Buildera i wciskamy klawisz F11 (Run debug) w efekcie czego otwiera nam się domyślna przeglądarka, a w niej nasza mikro-aplikacja:

FlexJava08

Taadaa! Serwer śmiga aż miło. Czas przystąpić do stworzenia czegoś bardziej konkretnego! Do dzieła!
Na początek tworzymy nową klasę w Javie – File -> New -> Other -> Class:

FlexJava09

i dodajemy do niej dwie metody: helloWorld i repeatAfterMe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.imrahil.tutorial;

public class HelloWorld
{
    public String helloWorld()
    {
        return "Server said: Hello World!";
    }
   
    public String repeatAfterMe(String sayHello)
    {
        return "You said: " + sayHello;
    }
}

Skompilowana klasa powinna znaleźć się w katalogu /WebContent/WEB-INF/classes/com/imrahil/tutorial.
Żeby jednak BlazeDS potrafił z niej skorzystać trzeba ją dodać do pliku remoting-config.xml, który powinien wyglądać następująco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service"
   class="flex.messaging.services.RemotingService">

    <adapters>
        <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
    </adapters>

    <default-channels>
        <channel ref="my-amf"/>
    </default-channels>
   
    <destination id="HelloWorld">
        <properties>
            <source>com.imrahil.tutorial.HelloWorld</source>
        </properties>
    </destination>
</service>

Przy okazji można wywalić pliki: messaging-config.xml oraz proxy-config.xml bo z tych opcji nie będziemy wogóle korzystać. Trzeba jednak zmodyfikować wtedy plik services-config.xml, który powinien wyglądać tak:

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
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>
<services-config>

    <services>
        <service-include file-path="remoting-config.xml" />
    </services>

    <security>
        <login-command class="flex.messaging.security.TomcatLoginCommand" server="Tomcat"/>
    </security>

    <channels>
        <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

    <logging>
        <target class="flex.messaging.log.ConsoleTarget" level="Debug">
            <properties>
                <prefix>[BlazeDS] </prefix>
                <includeDate>false</includeDate>
                <includeTime>false</includeTime>
                <includeLevel>false</includeLevel>
                <includeCategory>false</includeCategory>
            </properties>
            <filters>
                <pattern>Endpoint.*</pattern>
                <pattern>Service.*</pattern>
                <pattern>Configuration</pattern>
            </filters>
        </target>
    </logging>

    <system>
        <redeploy>
            <enabled>false</enabled>
        </redeploy>
    </system>
</services-config>

Cenną zmianą jest zwłaszcza opcja target=”Debug” w sekcji <logging /> – pozwoli nam ona obserwować odpowiedzi BlazeDS w konsoli serwera Tomcat.

Czas zatem stworzyć aplikację Flex komunikującą się z nowo stworzonymi metodami Javy.

Tworzymy nową MXML Application i piszemy:

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
32
33
34
35
36
37
38
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="left">

    <mx:RemoteObject id="myservice" fault="faultHandler(event)" showBusyCursor="true" destination="HelloWorld">
        <mx:method name="helloWorld" result="resultHandler(event)" />
        <mx:method name="repeatAfterMe" result="resultHandler(event)" />
    </mx:RemoteObject>

    <mx:Script>
       <![CDATA[
           import mx.rpc.events.ResultEvent;
           import mx.rpc.events.FaultEvent;
           
           private function resultHandler(evt:ResultEvent):void
           {
               outputTxt.text += evt.message.body.toString() + "\n";
           }

           private function faultHandler(fault:FaultEvent):void
           {
               outputTxt.text =  "Code: " + fault.fault.faultCode + "\n";
               outputTxt.text += "Message: " + fault.fault.faultString + "\n";
               outputTxt.text += "Detail: " + fault.fault.faultDetail + "\n";
           }
       ]]>
    </mx:Script>

    <mx:Label text="Output:"/>
    <mx:TextArea width="500" height="100" id="outputTxt"/>
    <mx:Button label="Hello World!" click="myservice.getOperation('helloWorld').send();"/>
   
    <mx:HBox width="100%">
        <mx:Button label="Repeat After Me:" click="myservice.getOperation('repeatAfterMe').send(myText.text);"/>
        <mx:TextInput id="myText" text="Sent to Server"/>
    </mx:HBox>
   
    <mx:Button label="Invoke wrong method" click="myservice.getOperation('wrongMethod').send();"/>
</mx:Application>

Uwaga! Jeśli po odpaleniu w przeglądarce (klawisz F11 lub CTRL+F11 w Flex Builderze) i wywołaniu metody helloWorld wyskakuje nam błąd Client.Error.MessageSend (a konkretniej: Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url: ‘http://localhost:8080/WebContent/messagebroker/amf’) to  prawdopodobnie trzeba zmodyfikować parametr Context root w opcjach projektu: Preferences -> Flex Server -> Context root.
Właściwą wartością jest nazwa projektu, czyli w naszym przypadku: BlazeDS-Hello-World. Trzeba jeszcze zrestartować serwer (lub wyczyścić mu cache: prawy klawisz myszy na serwerze w zakładce Servers i opcja Clean)

Gdy już wszystko ustawimy jak trzeba to pod adresem: http://localhost:8080/BlazeDS-Hello-World/hello_world.html znajdziemy naszą śliczną aplikację:

FlexJava10

Jeśli ktoś nie miał tyle czasu, żeby samemu stworzyć powyższą aplikację ten może ściągnąć pełen kod wraz z plikami projektu Flex Buildera.

ps.: kod Flexowy bazuje w pewnej części na kodzie Wade’a Arnolda z tego wpisu.

  1. 2 Responses to “Flex + Java w jednym projekcie w Flex Builderze – część II”

  2. [RPC Fault faultString="Send failed" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 404: url: 'http://localhost:8080/WebContent/messagebroker/amf'"]

    Solution:

    To resolve, change the serverContextRoot to point to your Project name instead of WebContent folder.

    Here how it is done in .flexProperties file created by eclipse

    serverContextRoot=”/WebContent”

    change this to

    serverContextRoot=”/your project name”

    By lukasz.r on paź 3, 2009

  3. “Katalog flex_src to nasz główny katalog ze kodem Flexa, src z kodem Java, a WebContent to nasz lokalny serwer WWW.”

    Dlaczego napisałeś, że WebContent to nasz lokalny serwer WWW? Przecież tam masz pliki konfiguracyjne i treści np. klasy. Na serwerze lokalnym masz wszystkie pliki aplikacji w tym WebContent, ogólnie cały context.root. Dobrze piszę, czy ja coś źle rozumiem?

    Pozdrawiam

    By tomek on lut 7, 2010

Odpowiedz