12
返回列表 发新帖
楼主: Sky-Tiger

Java EE and Flex: A compelling combination

[复制链接]
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
11#
 楼主| 发表于 2009-2-6 23:40 | 只看该作者
Listing 9. Web descriptor with HTTP servlet and BlazeDS specified

<?xml version = '1.0' encoding = 'utf-8'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee">
   <display-name>JavaWorld Flex/Java EE Part 2 Article</display-name>
   <description>Server-side functionality for JavaWorld Flex/Java EE Part 2 Article</description>

   <!-- Http Flex Session attribute and binding listener support -->
   <listener>
      <listener-class>flex.messaging.HttpFlexSession</listener-class>
   </listener>

   <!-- MessageBroker Servlet -->
   <servlet>
      <servlet-name>MessageBrokerServlet</servlet-name>
      <display-name>MessageBrokerServlet</display-name>
      <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
      <init-param>
         <param-name>services.configuration.file</param-name>
         <param-value>/WEB-INF/flex/services-config.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet>
      <servlet-name>ArticleServer</servlet-name>
      <servlet-class>javaworld.dustin.servlets.ArticleServer</servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>MessageBrokerServlet</servlet-name>
      <url-pattern>/messagebroker/*</url-pattern>
   </servlet-mapping>

   <servlet-mapping>
      <servlet-name>ArticleServer</servlet-name>
      <url-pattern>/articles</url-pattern>
   </servlet-mapping>
   
   <session-config>
      <session-timeout>35</session-timeout>
   </session-config>
   <mime-mapping>
      <extension>html</extension>
      <mime-type>text/html</mime-type>
   </mime-mapping>
   <mime-mapping>
      <extension>txt</extension>
      <mime-type>text/plain</mime-type>
   </mime-mapping>
</web-app>

It is important to make sure that the expanded WEB-INF contents from the blazeds.war file get reassembled back into the example application's WAR file, because BlazeDS JAR files will be needed. We also need to ensure that the services-config.xml and remoting-config.xml files that we edit for our application get assembled into our WAR file.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
12#
 楼主| 发表于 2009-2-6 23:41 | 只看该作者
Before moving on to editing the BlazeDS configuration files for the object remoting, it is appropriate to create the Java objects that will be remotely accessed. Listing 10 shows the Java class (TopArticlesServer) that the Flex client will interact with.
Listing 10. TopArticlesServer.java: Java class to be remotely accessed by Flex

package javaworld.dustin.remoting;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import static javaworld.dustin.remoting.TopArticleConstants.*;

/**
* Simple Java class to be used in Flex/Java remoting example. Represents the
* top articles on JavaWorld.
*
* @author Dustin
*/
public class TopArticlesServer
{
   /** Map of year+rank key to article corresponding to that year and rank. */
   private static final Map<String, TopArticle> topArticles =
      new HashMap<String, TopArticle>();

   static
   {
      final TopArticle article200801 =
         new TopArticle(
            "Hello, OSGi, Part 1: Bundles for Beginners",
            "Sunil Patil",
            2008,
            "http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html",
            1);
      topArticles.put("2008_01", article200801);

      final TopArticle article200802 =
         new TopArticle(
            "Eclipse 3.3 or NetBeans 6.0?",
            "Andrew Binstock",
            2008,
            "http://www.javaworld.com/javaworld/jw-03-2008/jw-03-java-ides0308.html",
            2);
      topArticles.put("2008_02", article200802);

      final TopArticle article200803 =
         new TopArticle(
            "Is Tomcat Enterprise Ready?",
            "Jeff Hanson",
            2008,
            "http://www.javaworld.com/javaworld/jw-01-2008/jw-01-tomcat6.html",
            3);
      topArticles.put("2008_03", article200803);

      final TopArticle article200804 =
         new TopArticle(
            "iBATIS, Hibernate, and JPA: Which is Right for You?",
            "K. L. Nitin et al",
            2008,
            "http://www.javaworld.com/javaworld/jw-07-2008/jw-07-orm-comparison.html",
            4);
      topArticles.put("2008_04", article200804);

      final TopArticle article200805 =
         new TopArticle(
            "Merging and Branching in Subversion 1.5",
            "John Ferguson Smart",
            2008,
            "http://www.javaworld.com/javaworld/jw-01-2008/jw-01-svnmerging.html",
            5);
      topArticles.put("2008_05", article200805);

      final TopArticle article200806 =
         new TopArticle(
            "Understanding JPA, Part 1",
            "Aditi Das",
            2008,
            "http://www.javaworld.com/javaworld/jw-01-2008/jw-01-jpa1.html",
            6);
      topArticles.put("2008_06", article200806);

      final TopArticle article200807 =
         new TopArticle(
           "Four Harmful Java Idioms, and How to Fix Them",
           "John O'Hanley",
           2008,
           "http://www.javaworld.com/javaworld/jw-07-2008/jw-07-harmful-idioms.html",
           7);
      topArticles.put("2008_07", article200807);

      final TopArticle article200808 =
         new TopArticle(
            "Asynchronous HTTP Comet Architectures",
            "Gregor Roth",
            2008,
            "http://www.javaworld.com/javaworld/jw-03-2008/jw-03-asynchhttp-test.html",
            8);
      topArticles.put("2008_08", article200808);

      final TopArticle article200809 =
         new TopArticle(
            "Introduction to Hibernate Search",
            "Dr. Xinyu Liu",
            2008,
            "http://www.javaworld.com/javaworld/jw-07-2008/jw-07-hibernate-search.html",
            9);
      topArticles.put("2008_09", article200809);

      final TopArticle article200810 =
         new TopArticle(
            "Open Source Java Projects: Java Native Access",
            "Jeff Friesen",
            2008,
            "http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html",
            10);
      topArticles.put("2008_10", article200810);
   }

   /** No-arguments constructor necessary for object binding. */
   public TopArticlesServer() {}

   /**
    * Provide the article corresponding to the provided year and rank desired.
    *
    * @param year Publication year of article.
    * @param rank Rank of desired article.
    * @return Article matching provided year and rank; the article will have a
    *    rank of zero (0) if no actual matching article was found.
    * @throws IllegalArgumentException Thrown if the publication year or rank
    *    are not valid.
    */
   public TopArticle getRankedArticle(final int year, final int rank)
   {
System.err.println("getRankedArticle() received ranking of " + rank);
      TopArticleUtil.validateArticleRankAndYearInput(year, rank);
      final String extraDigit = rank < 10 ? "0" : "";
      final String key =
         String.valueOf(year) + "_" + extraDigit + String.valueOf(rank);
      TopArticle topArticle = topArticles.get(key);
      if (topArticle == null)
      {
         final Calendar today = Calendar.getInstance();
         topArticle =
            new TopArticle(
               DEFAULT_TITLE + " (No Match!)",
               DEFAULT_AUTHOR,
               DEFAULT_YEAR,
               DEFAULT_URL,
               NO_MATCHING_ARTICLE_RANK);
      }
      return topArticle;
   }
}

The getRankedArticle(int,int) method in TopArticlesServer returns an instance of TopArticle. Listing 11 shows the definition of TopArticle.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
13#
 楼主| 发表于 2009-2-6 23:41 | 只看该作者
Listing 11. TopArticle.java: Encapsulates data to be returned to the Flex client

package javaworld.dustin.remoting;

import java.io.Serializable;

/**
* Class representing a popular article published on JavaWorld.
*
* @author Dustin
*/
public final class TopArticle implements Serializable
{
   /** Title of article. */
   private String title;

   /** Name of article's author. */
   private String author;

   /** Year in which this article was published. */
   private int yearPublished;

   /** Article's URL. */
   private String url;

   /** Article's rank in terms of page hits in publication year. */
   private int rank;

   /** No-arguments constructor. */
   public TopArticle()
   {
      title = TopArticleConstants.DEFAULT_TITLE;
      author = TopArticleConstants.DEFAULT_AUTHOR;
      yearPublished = TopArticleConstants.DEFAULT_YEAR;
      url = TopArticleConstants.DEFAULT_URL;
      rank = TopArticleConstants.NO_MATCHING_ARTICLE_RANK;
   }

   /**
    * Constructor accepting arguments to populate my state.
    *
    * @param newTitle Title of the article being instantiated.
    * @param newAuthor Author of the article being instantiated.
    * @param newYearPublished Publication year of this article; should be a four
    *    digit year.
    * @param newUrl URL/URI pointing to this article.
    * @param newRank Rank of this article in terms of page hits in publication
    *    year; should be between 1 and 10.
    * @throws IllegalArgumentException Thrown if the year or rank do not fall
    *    into their respective allowable ranges.
    */
   public TopArticle(
      final String newTitle,
      final String newAuthor,
      final int newYearPublished,
      final String newUrl,
      final int newRank)
   {
      TopArticleUtil.validateArticleRankAndYearInput(newYearPublished, newRank);

      this.title = newTitle;
      this.author = newAuthor;
      this.yearPublished = newYearPublished;
      this.url = newUrl;
      this.rank = newRank;
   }

   /**
    * Provide the article's author's full name.
    *
    * @return Full name of the article's author.
    */
   public String getAuthor()
   {
      return this.author;
   }

   /**
    * Set/change the author of this article.
    *
    * @param newAuthor New full name of this article's author.
    */
   public void setAuthor(final String newAuthor)
   {
      this.author = newAuthor;
   }

   /**
    * Provide the title of the article.
    *
    * @return Article title.
    */
   public String getTitle()
   {
      return this.title;
   }

   /**
    * Set/change the title of this article.
    *
    * @param newTitle New title for this article.
    */
   public void setTitle(final String newTitle)
   {
      this.title = newTitle;
   }

   /**
    * Provide the URL of this article.
    *
    * @return Article's URL.
    */
   public String getUrl()
   {
      return this.url;
   }

   /**
    * Set/change the URL/URI pointing to this article.
    *
    * @param url Uniform Resource Locator (URL) or URI pointing to this article.
    */
   public void setUrl(final String url)
   {
      this.url = url;
   }

   /**
    * Provide the year this article was published.
    *
    * @return Year in which this article was published.
    */
   public int getYearPublished()
   {
      return this.yearPublished;
   }

   /**
    * Set/change the year this article was published.
    *
    * @param yearPublished Year that this article was published.
    */
   public void setYearPublished(final int yearPublished)
   {
      this.yearPublished = yearPublished;
   }

   /**
    * Provide the rank of this article in its year of publication.
    *
    * @return Rank of this article in its year of publication.
    */
   public int getRank()
   {
      return this.rank;
   }

   /**
    * Set/change the ranking that this article received in its publication year.
    *
    * @param newRank Ranking for this article in its publication year.
    */
   public void setRank(final int newRank)
   {
      this.rank = newRank;
   }

   /**
    * Provide String representation of this article.
    *
    * @return Article's string representation.
    */
   @Override
   public String toString()
   {
      final StringBuffer buffer = new StringBuffer();
      buffer.append("Title: ").append(this.title).append("; ");
      buffer.append("URL: ").append(this.url).append("; ");
      buffer.append("Author: ").append(this.author).append("; ");
      buffer.append("Year Published: ").append(this.yearPublished).append("; ");
      buffer.append("Rank: ").append(this.rank).append("; ");
      return buffer.toString();
   }
}

In Listing 11, the "get" and "set" methods, and the constructor that does not accept arguments, are all necessary for BlazeDS to associate the ActionScript object with the Java object.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
14#
 楼主| 发表于 2009-2-6 23:41 | 只看该作者
We need an ActionScript class, shown in Listing 12, to bind to the Java version of TopArticle that can be manipulated by the Flex client code. Notice that although the TopArticle Java class in Listing 11 has no obvious sign of any binding to the ActionScript class, the ActionScript class does have an explicit binding to the Java class.
Listing 12. ActionScript.as: ActionScript version of TopArticle

package javaworld.dustin
{
   [Bindable]
   [RemoteClass(alias="javaworld.dustin.remoting.TopArticle")]
   public class TopArticle
   {
      /** Title of Article. */
      private var _title:String;

      /** Author of Article. */
      private var _author:String;

      /** Article's URL. */
      private var _url:String;

      /** Year of publication. */
      private var _year:int;

      /** Rank of article in publication year. */
      private var _rank:int;

      /** No-arguments constructor. */
      public function TopArticle(
         newTitle:String = "None Specified",
         newAuthor:String = null,
         newYearPublished:int = 0,
         newUrl:String = null,
         newRank:int = 0)
      {
         _title = newTitle;
         _author = newAuthor;
         _year = newYearPublished;
         _url = newUrl;
         _rank = newRank;
      }

      /**
       * WRITE (set/change) title property.
       *
       * @param newTitle New title.
       */
      public function set title(newTitle:String):void
      {
         _title = newTitle;
      }

      /**
       * READ title property.
       *
       * @return My title.
       */
      public function get title():String
      {
         return _title;
      }

      /**
       * WRITE (set/change) author property.
       *
       * @param newAuthor Author of article..
       */
      public function set author(newAuthor:String):void
      {
         _author = newAuthor;
      }

      /**
       * READ author property.
       *
       * @return Author of article..
       */
      public function get author():String
      {
         return _author;
      }

      /**
       * WRITE (set/change) url property.
       *
       * @param newUrl New URL.
       */
      public function set url(newUrl:String):void
      {
         _url = newUrl;
      }

      /**
       * READ url property.
       *
       * @return My URL..
       */
      public function get url():String
      {
         return _url;
      }

      /**
       * WRITE (set/change) year property.
       *
       * @param newYear Publication year of article.
       */
      public function set yearPublished(newYear:int):void
      {
         _year = newYear;
      }

      /**
       * READ year property.
       *
       * @return Year of publication.
       */
      public function get yearPublished():int
      {
         return _year;
      }

      /**
       * WRITE (set/change) rank property.
       *
       * @param newRank Rank of article.
       */
      public function set rank(newRank:int):void
      {
         _rank = newRank;
      }

      /**
       * READ rank property.
       *
       * @return Rank of publication.
       */
      public function get rank():int
      {
         return _rank;
      }

      /**
       * Provide String representation of me.
       *
       * @return String representation of this article.
       */
      public function toString():String
      {
         return  "[TopArticle: Title: " + this.title + "; Author: " + this.author
               + "; URL: " + this.url + "; Year: " + this.yearPublished
               + "; Ranking: " + this.rank + "]";
      }
   }
}

Now we need to edit the remoting-config.xml file to indicate the use of the TopArticlesServer Java class. Listing 13 shows the edited version.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
15#
 楼主| 发表于 2009-2-6 23:41 | 只看该作者
Listing 13. Modified remoting-config.xml BlazeDS remoting configuration file

<?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="TopArticlesDestination">  
      <properties>  
         <source>javaworld.dustin.remoting.TopArticlesServer</source>  
      </properties>  
   </destination>

</service>

The remoting-config.xml file in Listing 13 demonstrates the assigning of a destination that the Flex client can call, and associating that destination with the Java TopArticlesServer class. This remoting-config.xml file is specified in the more general BlazeDS services-config.xml configuration file, shown in Listing 14.
Listing 14. Modified services-config.xml BlazeDS configuration file

<?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://localhost:8080/{context.root}/messagebroker/amf"
                 class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>

        <channel-definition id="my-http" class="mx.messaging.channels.HTTPChannel">
            <endpoint url="http://localhost:8080/{context.root}/messagebroker/http"
                 class="flex.messaging.endpoints.HTTPEndpoint"/>
        </channel-definition>

    </channels>

    <logging>
        <target class="flex.messaging.log.ConsoleTarget" level="Error">
            <properties>
                <prefix>[BlazeDS-JavaWorld] </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>

When built with the mxmlc compiler, a Flex client that will call a BlazeDS destination must specify the location of the services-config.xml file with the -services mxmlc compiler option. It must also specify the context root of the deployed server application with the -context-root mxmlc compiler option.
The final Flex application

Listing 15 shows the final MXML code for the example Flex client.
Listing 15. Final version of main MXML file



<?xml version="1.0" encoding="UTF-8" ?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                xmlns:jw="components.*"
                width="1100" height="400"
                applicationComplete="uponInitialization();">
   <mx:Style>
   .articleTitle
   {
      font-weight: bold;
   }
   .formLabel
   {
      font-weight: bold;
   }
   .gridLabel
   {
      font-weight: bold;
      font-size: 14;
   }
   </mx:Style>

   <mx:Script>
   <![CDATA[
   import flash.events.MouseEvent;
   import mx.collections.ArrayCollection;
   import mx.controls.Alert;
   import mx.core.ContainerCreationPolicy;
   import mx.events.ListEvent;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.Fault;
   import mx.utils.ObjectUtil;
   import javaworld.dustin.TopArticle;

   [Bindable]
   private var years:ArrayCollection = new ArrayCollection(
      [ {label:"2008", data:2008},
        {label:"2009", data:2009},
        {label:"2010", data:2010} ]);

   [Bindable]
   private var ranks:ArrayCollection = new ArrayCollection(
      [ {label:"1", data:1},
        {label:"2", data:2},
        {label:"3", data:3},
        {label:"4", data:4},
        {label:"5", data:5},
        {label:"6", data:6},
        {label:"7", data:7},
        {label:"8", data:8},
        {label:"9", data:9},
        {label:"10", data:10} ]);

   [Bindable]
   private var selectionsMade:Boolean = false;

   private const unselectedColor:int = 0x0000FF;

   public function uponInitialization():void
   {
      articles.send();
   }

   public function requestAuthorBio(clickEvent:ListEvent):void
   {
      const authorName:String = dataGrid.selectedItem.author;
      authorBiographyService.obtainAuthorBiographyWithFullName.send(authorName);
   }

   public function faultHandler(event:FaultEvent):void
   {
      const fault:Fault = event.fault;
      const faultString:String =
           "FAULT CODE: " + fault.faultCode + "\n\n"
         + "FAULT DETAIL: " + fault.faultDetail + "\n\n"
         + "FAULT STRING: " + fault.faultString + "\n\n"
         + "FAULT CODE: " + fault.faultCode + "\n\n";
      Alert.show( "FAULT!\n\n" + faultString );
      trace( "FAULT!\n\n" + faultString );
   }

   public function resultHandler(event:ResultEvent):void
   {
      trace("Response from service received.";
      // The ResultEvent includes a property "message" that contains
      //   the actual payload/contents of the result.  This is useful
      //   when no fault is occurring, but no data is being displayed
      //   in the component either.
   }

   /**
    * Display selected author's biography.
    *
    * @param event The event associated with a response to a Web service call.
    */
   public function displayAuthorBiography(event:ResultEvent):void
   {
      authorBioTextArea.text =
         authorBiographyService.obtainAuthorBiographyWithFullName.lastResult;
   }

   /**
    * Retrieve best articles.
    *
    * @param event Event associated with mouse click.
    */
   public function retrieveBestOf(event:MouseEvent):void
   {
      remoteObject.getRankedArticle(
         yearSelection.selectedItem.label, rankSelection.selectedItem.label);
   }

   /**
    *
    */
   public function checkSelectionsMade(event:ListEvent):void
   {
      if (yearSelection.selectedIndex != -1)
      {
         yearItem.setStyle("color", "black";
      }
      if (rankSelection.selectedIndex != -1)
      {
         rankItem.setStyle("color", "black";
      }
      selectionsMade =   yearSelection.selectedIndex != -1
                      && rankSelection.selectedIndex != -1;
   }
   ]]>
   </mx:Script>

   <mx:HTTPService id="articles"
                   url="http://localhost:8080/jw-jee-flex/articles"
                   method="GET"
                   resultFormat="e4x"
                   fault="faultHandler(event);"
                   result="resultHandler(event);" />

   <mx:WebService id="authorBiographyService"
                  wsdl="http://localhost:8080/jw-jee-flex/AuthorService?WSDL"
        load="authorBioTextArea.visible=true;"
        useProxy="false">
      <mxperation name="obtainAuthorBiographyWithFullName"
                    result="displayAuthorBiography(event);"
                    fault="faultHandler(event);" />
   </mx:WebService>

   <mx:RemoteObject id="remoteObject"
                    destination="TopArticlesDestination"
          showBusyCursor="true"
          fault="faultHandler(event);" />

   <mx:TabNavigator id="tabNavigator"
                    creationPolicy="{ContainerCreationPolicy.ALL}">
      <mx:Panel id="mainPanel"
                label="Select All-Time Articles"
                title="Some of Dustin's Favorite JavaWorld Articles"
                width="{application.width-100}" height="{application.height-150}">
         <mx:Label text="A Small Sample of Favorite JavaWorld Articles"
                   styleName="gridLabel" />
         <mxataGrid id="dataGrid"
                      width="{mainPanel.width*0.9}"
                      rowCount="5" dataProvider="{articles.lastResult.article}"
                      editable="false"
            itemClick="requestAuthorBio(event);">
               <mx:columns>
                   <mxataGridColumn id="titleColumn"
                                      dataField="title"
                                      headerText="Article Title"
                                      width="{dataGrid.width*0.25}"
                                      editable="false" />
                   <mxataGridColumn id="authorColumn"
                                      dataField="author"
                                      headerText="Article Author"
                                      width="{dataGrid.width*0.25}"
                                      editable="false" />
                   <mxataGridColumn id="urlColumn"
                                      dataField="url"
                                      headerText="Article URL"
                                      editable="true">
                     <mx:itemRenderer>
                        <mx:Component>
                           <jw:UrlLabel />
                        </mx:Component>
                     </mx:itemRenderer>
                   </mxataGridColumn>
               </mx:columns>
         </mxataGrid>
         <mx:TextArea id="authorBioTextArea" visible="false"
                      width="{dataGrid.width}" height="25" />
      </mx:Panel>

      <mx:Panel id="bestOfPanel" label="Best of (Yearly)"
                title="Best of JavaWorld Articles">
         <mx:Form id="bestOfForm">
       <mx:FormItem id="yearItem" label="Select Year"
                    fontWeight="bold" color="{unselectedColor}">
          <mx:ComboBox id="yearSelection" dataProvider="{years}"
                       prompt="Select Year of Publication"
             change="checkSelectionsMade(event);" />
       </mx:FormItem>
       <mx:FormItem id="rankItem" label="Select Rank"
                    fontWeight="bold" color="{unselectedColor}">
          <mx:ComboBox id="rankSelection" dataProvider="{ranks}"
                       prompt="Select Ranking of Publication"
             change="checkSelectionsMade(event);" />
       </mx:FormItem>
       <mx:FormItem id="titleItem" label="Article Title" fontWeight="bold"
          enabled="{selectionsMade}">
          <mx:Label id="titleLabel"
                    text="{remoteObject.getRankedArticle.lastResult.title}" />
       </mx:FormItem>
       <mx:FormItem id="authorItem" label="Author"
                    fontWeight="bold" enabled="{selectionsMade}">
          <mx:Label id="authorLabel"
                    text="{remoteObject.getRankedArticle.lastResult.author}" />
       </mx:FormItem>
       <mx:FormItem id="urlItem" label="URL"
                    fontWeight="bold" enabled="{selectionsMade}">
          <mx:Label id="urlLabel"
                    text="{remoteObject.getRankedArticle.lastResult.url}" />
       </mx:FormItem>
       <mx:Button id="submitButton" label="Retrieve Article"
                  click="retrieveBestOf(event);" enabled="{selectionsMade}" />
    </mx:Form>
      </mx:Panel>

   </mx:TabNavigator>
</mx:Application>

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
16#
 楼主| 发表于 2009-2-6 23:41 | 只看该作者
The source code in Listing 15 includes the object remoting and provides additional ActionScript examples. The portion of the Flex application that uses the object remoting to obtain information from the server regarding the best articles on JavaWorld gets its own tab, demonstrating the Flex TabNavigator component. This new version of the client application also demonstrates the ComboBox component.

The Flex application shows new concepts other than just object remoting. It also demonstrates more ActionScript logic and the need to include ActionScript logic within CDATA tags due to the presence of the "&&" (and operator), which can be confusing to an XML parser. The enabled attribute is also applied to several components in this part of the example. This attribute is initially set to false, disabling the component. The component's enable attribute only becomes true when a certain condition occurs. In this case, the selection of a year and of a rank lead to enabling of the components.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
17#
 楼主| 发表于 2009-2-6 23:42 | 只看该作者
Executing the example

Figures 4 through 9 show the Flex application being executed.

Figure 4 demonstrates the Flex client loading up. The data to populate the DataGrid with article information is retrieved via HTTPService, as you saw in "Java EE and Flex: A compelling combination, Part 1."

Flex client populated by HTTPService calls
Figure 4. Flex client populated by HTTPService calls (Click to enlarge.)

Figure 5 demonstrates that the WebService call works and provides the biography information for the author of the selected article.

Web service returning biography information about selected article author
Figure 5. Web service returning biography information about selected article author (Click to enlarge.)

Figure 6 demonstrates the tab that is focused on the object remoting to provide information about the most popular articles on JavaWorld in 2008. The button and the fields that will display retrieved data are disabled until the desired ranking and year of publication are selected.

TabNavigator, Form, ComboBox, and Button Components Demonstrated
Figure 6. TabNavigator, Form, ComboBox, and Button components demonstrated (Click to enlarge.)

Figure 7 demonstrates an active ComboBox component used to provide publication years that could be selected. (Of course, only 2008 is supported on the back end, but multiple years make the ComboBox demonstration more interesting.)

Flex ComboBox in Action
Figure 7. Flex ComboBox in action (Click to enlarge.)

Figure 8 demonstrates the ComboBox again, this time in conjunction with selection of a desired article ranking. Once selected, the ComboBox's text color changes from blue to black.

Selected ComboBox color has changed
Figure 8. Selected ComboBox color has changed (Click to enlarge.)

With the publication year and ranking selected, the user can click the Retrieve Article button, shown in Figure 9. When this button is clicked, the selected year and rank are submitted to the server via object remoting, and the matching article information provided by the Java-based back end is displayed.

Selected ComboBox color has changed
Figure 9. Article results obtained via remoting and displayed

I'm using the Retrieve Article button here to demonstrate another Flex component. However, it's common in Flex applications not to use a button at all, but instead have the client automatically request the information as soon as all required fields have been selected.

There is much more to Flex

Flex offers you an opportunity to create rich interactive clients that make the most of your Java enterprise back end. The Flex client example covered in the two parts of this article has demonstrated Flex communication with a Java EE-based server using standard HTTP (HTTPService), using SOAP-based Web services (WebService), and using object remoting. The client example also demonstrates several aspects of Flex, including some of its components, its powerful property binding and data binding, its ability to be extended with custom components, and its support for CSS.

There's much more to learn about Flex. BlazeDS also supports messaging, and GraniteDS (an open source third-party product) offers other remote communication mechanisms. Flex's other attractive features include fluid animation and other effects, audio and video support, skinning, accessibility features, and much more. To see some of these features, try out the examples at the Flex Showcase.

使用道具 举报

回复
论坛徽章:
131
乌索普
日期:2017-09-26 13:06:30马上加薪
日期:2014-11-22 01:34:242014年世界杯参赛球队: 尼日利亚
日期:2014-06-17 15:23:23马上有对象
日期:2014-05-11 19:35:172014年新春福章
日期:2014-04-04 16:16:58马上有对象
日期:2014-03-08 16:50:54马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14
18#
发表于 2009-2-10 23:47 | 只看该作者
东西真多

使用道具 举报

回复
论坛徽章:
131
乌索普
日期:2017-09-26 13:06:30马上加薪
日期:2014-11-22 01:34:242014年世界杯参赛球队: 尼日利亚
日期:2014-06-17 15:23:23马上有对象
日期:2014-05-11 19:35:172014年新春福章
日期:2014-04-04 16:16:58马上有对象
日期:2014-03-08 16:50:54马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14
19#
发表于 2009-2-10 23:48 | 只看该作者
flex还是不错的, 不过sap现在又看上silverlight了

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表