推荐-基于Flex三种通讯方式的Java配置与整合 精品
Fle与数据库的连接方式
Flex连接数据库的3种方式首先,做一点说明。
Flex是不能直接连接数据库的,这一点大家需要知道,它只能间接地连接数据库。
Flex 中提供了三种方式:HttpService,WebService 和RemoteObject。
其中HttpService可以直接获取XML中的数据,还可以通过JSP,ASP以及PHP读取数据库中的数据,这个比较简单,而且网上也有很多例子,我就不多说了。
WebService我不懂,请自己查资料。
我一直用的是JAVA对象连接数据库,感觉这个挺方便,而且J2EE的技术已经很成熟。
今天的教程就是以 Flex + JAVA + SQLServer获取数据库公告信息为例简单说一下RemoteObject的用法。
前提1.确保你安装了Flex Data Service。
这个对于单个CUP无限APP是免费的,可以去Adobe下载。
如果只是读取XML文件是不需要这个的,连接数据库就需要它了。
2.安装了Flex Builder或者有Flex SDK。
我这里使用的是Flex Builder(IDE就是方便啊 ^_^)。
3.安装了SQLServer数据库。
4.安装了JRUN或者tomcat或其它的J2EE容器,因为发布的时候我们的程序要运行在J2EE平台上。
5.安装了JDK。
第一步:创建数据库这里我们有一个公告表,表名为Bulletin。
结构如下:字段名称字段类型说明ID自动编号自动编号title Nvarchar(100)题目date datatime日期author Nvarchar(20)作者content ntext内容在数据库中创建这个表。
保存之后进入下一步。
第二步:在JAVA中编写获取公告的代码首先,我们要创建一个公告类来专门保存获取的公告信息,代码如下。
NoticeInfo.javapackage net.zhuoqun.connectDB;import java.util.Date;public class NoticeInfo {private String title; // 标题private String author; // 作者private String content;// 内容private Date dates; // 时间public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}……………… // 其它get 和 set 方法。
整合Flex和Java--配置篇
3、 将该工程发布到 tomcat 下,并启动 tomcat。 (注:一定要启动 tomcat,因为在后面 的设置中,它要验证工程的路径) 4、 然后在该工程上右键Flex Project NatureAdd Flex Project Nature
配置正确的显示
配置服务器路径
建议不要修改这里的配置
<mx:Script> <![CDATA[ import mx.rpc.events.ResultEvent; function gg(evnet:ResultEvent):void{ var ff:String = evnet.result as String; ggg.text = ff; } function remotingSayHello():void{ var sname:String = nameInput.text; h.hello(sname); } ]]> </mx:Script> <mx:RemoteObject destination="hello" id="h" result="gg(event)" endpoint="http://localhost:8080/flexweb/messagebroker/amf" > </mx:RemoteObject>
<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-mapping> <servlet-name>MessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping>
最佳实践:Flex Spring JAVA BLAZEDS整合
BlazeDS初始化时用于动态创建services, destinations, and adapters。
SpringRemotingDestinationBootstrapService扩展AbstractBootstrapService。
SpringRemotingDestinationBootstrapService 自动导出包含"@Service标注及以FlexService结尾"的Spring Bean为RemoteObject。
@SuppressWarnings("all")public class SpringRemotingDestinationBootstrapService extends AbstractBootstrapService {public static final String DEFAULT_INCLUDE_END_WITH_BEANS = "FlexService";private static Logger logger =LoggerFactory.getLogger(SpringRemotingDestinationBootstrapService.cla ss);private String destChannel;private String destSecurityConstraint;private String destScope;private String destAdapter;private String destFactory;private String serviceId;private String includeEndsWithBeans;@Override/***初始化入口*/public void initialize(String id, ConfigMap properties) { serviceId = properties.getPropertyAsString("service-id", "remoting-service");destFactory = properties.getPropertyAsString("dest-factory", "spring");destAdapter = properties.getProperty("dest-adapter");destScope = properties.getProperty("dest-scope");destSecurityConstraint =properties.getProperty("dest-security-constraint");destChannel = properties.getPropertyAsString("dest-channel", "my-amf");includeEndsWithBeans =properties.getPropertyAsString("includeEndsWithBeans",DEFAULT_INCLUDE_END_WITH_BEANS);Service remotingService = broker.getService(serviceId);if (remotingService == null)throw createServiceException("not found Service with serviceId:" + serviceId);createSpringDestinations(remotingService);}private ServiceException createServiceException(String message) {ServiceException ex = new ServiceException();ex.setMessage(message);return ex;}/***将Spring的Service Name自动定义为destination*/private void createSpringDestinations(Service remotingService) { WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(broker.getServletContext());List<String> addedBeanNames = new ArrayList();for (String beanName : wac.getBeanDefinitionNames()) {Class type = wac.getType(beanName);logger.debug("{}: {}", new Object[]{beanName,type.getName()});boolean isCreateSpringDestination = !type.isAnnotationPresent(com.grgbanking.platform.core.flex.NoneRemoti ngObject.class)|| beanName.endsWith(includeEndsWithBeans) || isCreateDestination(beanName, type);if (isCreateSpringDestination) {createSpringDestination(remotingService, beanName);addedBeanNames.add(beanName);}}("[Auto Export Spring toRemotingDestination],beanNames={}", addedBeanNames);}protected boolean isCreateDestination(String beanName, Class type) {return false;}/** <!-- 动态生成的配置内容 --> <destination id="sampleVerbose"><channels> <channel* ref="my-secure-amf" /> </channels> <adapter ref="java-object" /> * <security> <security-constraint ref="sample-users" /> </security> * <properties> <source>pany.SampleService</source>* <scope>session</scope> <factory>myJavaFactory</factory></properties>* </destination>*/protected void createSpringDestination(Service service, String destinationId) {flex.messaging.services.remoting.RemotingDestinationdestination = (flex.messaging.services.remoting.RemotingDestination) service.createDestination(destinationId);destination.setSource(destinationId);destination.setFactory(destFactory);if (destAdapter != null) {destination.createAdapter(destAdapter);}if (destScope != null) {destination.setScope(destScope);}if (destSecurityConstraint != null) {destination.setSecurityConstraint(destSecurityConstraint);}if (destChannel != null) {destination.addChannel(destChannel);}service.addDestination(destination);}2)修改SpringFactory并扩展FlexFactory根据destination的id,将Flex的destination映射为Spring的Beanpublic class SpringFactory implements FlexFactory {private static final String SOURCE = "source";/***This method can be used to initialize the factory itself.It is called*with configuration parameters from the factory tag which defines the id*of the factory.*/public void initialize(String id, ConfigMap configMap) {}/***This method is called when we initialize the definition of an instance*which will be looked up by this factory.It should validate that the*properties supplied are valid to define an instance.Any valid properties*used for this configuration must be accessed to avoid warnings about *unused configuration elements.If your factory is only used for *application scoped components,this method can simply return a factory*instance which delegates the creation of the component to the*FactoryInstance's lookup method.*/public FactoryInstance createFactoryInstance(String id, ConfigMap properties) {SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties);instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));return instance;} // end method createFactoryInstance()/***Returns the instance specified by the source and properties arguments.*For the factory,this may mean constructing a new instance, optionally*registering it in some other name space such as the session or JNDI, and*then returning it or it may mean creating a new instance and returning *it.This method is called for each request to operate on the given item*by the system so it should be relatively efficient.*<p>*If your factory does not support the scope property,it report an error*if scope is supplied in the properties for this instance.*/public Object lookup(FactoryInstance inst) {SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;return factoryInstance.lookup();}/***Spring工厂实例,执行实际的查找动作.**@author yrliang**/static class SpringFactoryInstance extends FactoryInstance { SpringFactoryInstance(SpringFactory factory, String id, ConfigMap properties) {super(factory, id, properties);}@Overridepublic String toString() {return"SpringFactory instance for id="+ getId() + " source=" + getSource() + " scope=" + getScope();}@Overridepublic Object lookup() {Logger logger =LoggerFactory.getLogger(SpringFactory.class);ApplicationContext appContext = WebApplicationContextUtils .getWebApplicationContext(flex.messaging.FlexContext.getServletCo nfig().getServletContext());String beanName = getSource();try {logger.debug("lookup(): bean id=" + beanName);//flex.messaging.FlexContext.getHttpRequest().getSession().getAttribute (arg0);return appContext.getBean(beanName);} catch (NoSuchBeanDefinitionException nexc) {ServiceException e = new ServiceException();String msg = "Spring service named '"+ beanName + "' does not exist.";e.setMessage(msg);e.setRootCause(nexc);e.setDetails(msg);e.setCode("Server.Processing");logger.error("",nexc);throw e;} catch (BeansException bexc) {ServiceException e = new ServiceException();String msg = "Unable to create Spring service named '" + beanName + "' ";e.setMessage(msg);e.setRootCause(bexc);e.setDetails(msg);e.setCode("Server.Processing");logger.error("",bexc);throw e;}}}}3)配置service-config.xml<?xml version="1.0" encoding="UTF-8"?><services-config><factories><factory id="spring"class="com.grgbanking.platform.core.flex.spring.SpringFactory"/> </factories><services><service-include file-path="remoting-config.xml" /><service-include file-path="proxy-config.xml" /><service-include file-path="messaging-config.xml" /><service id="spring-remoting-service"class="com.grgbanking.platform.core.flex.spring.SpringRemotingDestina tionBootstrapService"><!-- 其它生成的RemotingDestination默认属性<adapters><adapter-definition id="java-object"class="flex.messaging.services.remoting.adapters.JavaAdapter"default="true" /></adapters><default-channels><channel ref="my-amf" /></default-channels>--><properties><!--<service-id></service-id><dest-factory></dest-factory><dest-adapter></dest-adapter><dest-scope></dest-scope><dest-channel></dest-channel><dest-security-constraint></dest-security-constraint><includeEndsWithBeans></includeEndsWithBeans>--></properties></service></services>4)FLEX客户端调用this.blogFlexService = new RemoteObject("blogFlexService");//这里需要指定endpoint,因为是动态的RemotingDestination,而静态的RemotingDestination ,flex编译器会将endpoint编译进源代码.//这个也是flex编译器需要指定配置文件而导致使用flex经常会犯的错误之一.this.blogFlexService.endpoint = '../messagebroker/amf';3.公司应用案例这种整合最早是在2010年的FEEL View 5.0中使用,后台的统一平台,FEEL View5.1中都采用这种方法进行整合。
Flex_AS3与Java的Socket通信
Flex AS3与Java的Socket通信新建flash文件:SocketExample.fla添加按钮:btnSend修改文档类为:SocketExample新建AS3文件:SocketExample.as1.package {2. import flash.display.Sprite;3. import flash.events.*;4. import .Socket;5.6. public class SocketExample extends Sprite {7.8. private var socket:Socket;9.10. public function SocketExample( ) {11. socket = new Socket( );12.13. // Add an event listener to be notified when the connection14. // is made15. socket.addEventListener( Event.CONNECT, onConnect );16.17. // Listen for when data is received from the socket server18. socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );19.20. //var btnSend:Button = new Button();21. bel = "Send Data";22. btnSend.emphasized = true;23. btnSend.width = 150;24. btnSend.move(20, 20);25. addChild(btnSend);26.27. btnSend.addEventListener(MouseEvent.CLICK, sendData);28. }29.30. private function sendData( event:Event ) {31.32. if (!socket.connected) {33.34. // Connect to the server35. socket.connect( "192.168.2.103", 5678 );36. }37.38. trace("send...");39. socket.writeUTFBytes("example\n");40. socket.flush();41.42. }43.44. private function onConnect( event:Event ):void {45. trace( "The socket is now connected..." );46. }47.48. private function onSocketData( eventrogressEvent ):void {49. trace( "Socket received " + socket.bytesAvailable + " byte(s) of data:" );50.51. trace(socket.readMultiByte(socket.bytesAvailable, "UTF-8"));52. }53.54.55. }56.}Java服务器端:MyServer.java1.import java.io.*;2.import .*;3.4.public class MyServer {5. public static void main(String[] args) throws IOException{6. ServerSocket server=new ServerSocket(5678);7.8. while (true) {9. Socket client=server.accept();10. BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));11. PrintWriter out=new PrintWriter(client.getOutputStream());12. //while(true){13. String str=in.readLine();14. System.out.println(str);15. out.println("has receive....");16. out.flush();17. if("end".equals(str))18. break;19. //}20. client.close();21. }22. }23.}客户端控制台输出:send...The socket is now connected...Socket received 17 byte(s) of data:has receive....外加一些AS3的Socket方法:我们在使用ActionScript3.0进行Socket编程的时候需要关注下面的问题,我们将在今后的学习中逐个对下面的问题进行讨论,并尽量逐渐的改进我们的程序.1.与Socket服务器建立连接.2.向Socket服务器发送数据.3.从Socket服务器读数据.4.同Socket服务器进行握手,并确定收到了什么样的数据和如何处理这些数据.5.与Socket服务器断开,或者当服务器想与你断开的时候发消息给你.6.处理使用Sockets时候引发的错误.1.与Socket服务器建立连接.解决方法:我们通过调用Socket.connect( )或者XMLSocket.connect( )方法并监听网络连接的事件消息.讨论:连接一台Socket服务器你需要确定两个信息,一个是Socket服务器的域名或者IP 地址,另一个是服务器监听的端口号.无论你使用的是Socket还是XMLSocket类的实例,连接请求都是完全的一样的,两个类都是使用一个名叫connect()的方法,该方法有两个参数:host :该参数为字符串类型,可以是一个域名,例如"",也可以是一个IP 地址,例如"192.168.1.101".如果 Socket服务器与你该Flash影片发布的Web服务器是同一个,该参数为Null.port :该参数为一个表示Socket服务器监听端口的int值.该值最小为1024.除非在服务器中有一个policy文件,用于指定允许端口号小于1024.因为Flash Socket编程是一个异步的过程,connect()方法不会等到一个连接完成后再执行下一行代码的执行.如果你想在一个连接完全执行完之前与一个 Socket完全绑定,那么你将会得到一个意想不到的结果,并且你当前的代码将不能工作.在尝试一个新的Socket连接的时候我们最好先添加一个连接事件监听器.当一个连接建立成功,Socket或者XMLSocket会发出一个连接事件, 这就可以让你知道交互已经准备好了.下面举了一个Socket实例与本地Socket服务器的2900端口建立连接的例子:package {import flash.display.Sprite;import flash.events.*;import .Socket;public class SocketExample extends Sprite {private var socket:Socket;public function SocketExample( ) {socket = new Socket( );// Add an event listener to be notified when the connection// is madesocket.addEventListener( Event.CONNECT, onConnect );// Connect to the serversocket.connect( "localhost", 2900 );}private function onConnect( event:Event ):void {trace( "The socket is now connected..." );}}}如果你想通过XMLSocket与服务器建立连接代码也是基本一样的.首先你创建了一个连接事件监听器,然后调用connect()方法.所不同的是 Socket实例改为了XMLSocket:package {import flash.display.Sprite;import flash.events.*;import .XMLSocket;public class SocketExample extends Sprite {private var socket:XMLSocket;public function SocketExample( ) {socket = new XMLSocket( );// Add an event listener to be notified when the connection is made socket.addEventListener( Event.CONNECT, onConnect );// Connect to the serversocket.connect( "localhost", 2900 );}private function onConnect( event:Event ):void {trace( "The xml socket is now connected..." );}}}如果连接失败,可那是下面两种原因的一种:一种是连接立即失败和运行时错误,另一种是如果无法完成连接从而产生一个ioError或者 securityError事件.关于错误事件处理信息的描述,我们打算改日讨论.请牢记,当与一个主机建立一个Socket连接时,Flash Player要遵守如下安全沙箱规则.1.Flash的.swf文件和主机必须严格的在同一个域名,只有这样才可以成功建立连接.2.一个从网上发布的.swf文件是不可以访问本地服务器的.3.本地未通过认证的.swf文件是不可以访问任何网络资源的.4.你想跨域访问或者连接低于1024的端口,必须使用一个跨域策略文件.如果尝试连接未认证的域或者低端口服务,这样就违反了安全沙箱策略,同时会产生一个securityError事件.这些情况都可以通过使用一个跨域策略文件解决.无论是Socket对象还是XMLSocket对象的策略文件,都必须在连接之前通过使用flash.system.Security.loadPolicyFile()方法载入策略文件.具体如下:Security.loadPolicyFile("/crossdomain.x ml");获得的改策略文件不仅定义了允许的域名,还定义了端口号.如果你不设置端口号,那么Flash Player默认为80端口(HTTP协议默认端口).在<allow-access-from>标签中可以使用逗号隔开设置多个端口号.下面这个例子就是允许访问80和110端口.<?xml version="1.0"?><!DOCTYPE cross-domain-policy SYSTEM"/xml/dtds/cross-domain-policy.dtd"><cross-domain-policy><allow-access-from domain="*" to-ports="80,110" /></cross-domain-policy>2.向Socket服务器发送数据.解决方法:对于Socket对象来说,通过是用write方法(writeByte(),writeUTFBytes( )等方法.)先向缓存区写入数据,然后使用flush()方法发送数据.对于XMLSocket对象,使用send()方法.讨论:Socket和XMLSocket类向Socket服务器发送数据的方法是不相同的.让我们首先看一下Socket类的方法.当你使用Socket对象向服务器发送数据的时候,你首先要将数据写入到一个缓冲区中.Socket类设置了一系列的方法来写数据.每一个方法都用于写不同的数据类型的数据(或者不同的数据).这些方法分别是: writeBoolean( ), writeByte( ),writeBytes( ), writeDouble( ), writeFloat( ), writeInt( ), writeMultiByte( ), writeObject( ), writeShort( ), write- UnsignedInt( ), writeUTF(), 和writeUTFBytes( ). 这些方法大多数都只接受一个参数,该参数的类型同方法的名字相匹配.例如,writeBoolean()方法接受一个布尔值作为参数,而 writeByte( ), writeDouble( ), writeFloat( ), writeInt( ), writeShort( ), writeUnsignedInt( ) 方法接受一个数字型参数.writeObject()方法接受一个对象类型作为参数,但该对象必须序列化成为AMF格式.writeBytes( )方法允许你传一个ByteArray参数,并带有偏移量和长度两个参数.例如,下面这段代码,调用了一个writeBytes( )方法,该方法将ByteArray对象中的所有byt值都传出去了(偏移量为0,长度和ByteArray数组长度等长):socket.writeBytes(byteArray, 0, byteArray.length);writeUTF( )和writeUTFBytes( ) 方法允许你的发送字符串类型的参数.每个一个方法只接受一个字符串作为参数.writeUTFBytes( )方法简单的将字符串作为Bytes发送.writeUTF( )方法在写入真正数据之前,先写入byts的数量.writeMultiByte( )方法也允许字符串类型的参数,但是使用的为非默认字符集.该方法需要两个参数:字符串和字符集名称.在Flash和Flex的帮助文档中有一个自持所有字符集的列表,该列表中的标签和描述符是一一对应的.使用标签值作为writeMultiByte( )作为字符集.例如下面的代码发送了一个编码为Unicode的字符串:socket.writeMultiByte("example", "unicode");相一个Socket对象传数值的方法完全依赖于你所有数据的类型和服务所接受数据的类型.使用一个Socket对象,你完全可以使用 ActionScript写一个Telnet和POP mail客户端.这两种协议都支持ASCII字符指令.例如,在连接一个POP服务器之后,你可以通过使用USER指令指定一个用户.下面代码向一个 Socket对象发一条指令:// POP servers expect a newline (\n) to execute the preceding command. socket.writeUTFBytes("USER exampleUsername\n");向一个Socket对象写入数据其实并没有将数据发送到Socket服务器.每调用一个write方法都向Socket对象添加一个数据.例如,下面代码向一个Socket对象添加了四个byte的数据,但是没有一个发出了.socket.writeByte(1);socket.writeByte(5);socket.writeByte(4);socket.writeByte(8);当你想将这些累积的数据发送到Socket服务器需要调用flush()方法.flush()方法调用之后将把所有已经写入的数据发送出去,并清空缓冲区:socket.flush( );XMLSocket类是一个非常简单用于发送数据的API.写于发数据都是由send()这一个方法来完成的.send()方法可以接受任何数据类型的参数.它可以将所有的参数都转换为一个字符串类型并发送到服务器.通常参数为一个XML对象或者一个包含数据结构类似XML数据的字符串:xmlSocket.send(xml);然而,准确的格式完全依赖于服务器所能够接受的格式.如果服务器接受XML格式的数据,你必须发送XML格式的数据.如果服务器只接受URL编码的数据, 你也必须发送URL编码的数据.3.从Socket服务器读数据解决方法:对于Socket实例,先收到socketData事件,然后调用如下两个方法的一个,比如,readByte()或者readInt(),在事件控制器中确定不会去读过去的bytesAvailable.对于XMLSocket实例,先收到data事件,然后解析从事件控制器内部装载的XML数据.讨论:从一个socket连接接收的数据依赖于你使用的Socket的类型.socket和XMLSocket 都可以从服务器接受到数据,但是它们处于不同重量级的技术.让我们在讨论XMLSocket之前先关注下Socket类.我都知道socket在Flash中是一个异步的行为.因此,它就不能简单的创建一个Socket连接,然后就立刻尝试去读取数据.read方法不能等到从服务器传过来数据之后在返回.换句话说,你只能在客户端从服务器载入所有数据之后才可以读取数据.在数据可用之前读数据会产生一个错误.通过socketData事件广播到Socket实例,这样我们就可以知道什么时候数据可以被读取.那么我们要为socketData事件添加一个事件监听器,任何时候只要有新的数据从一个socket服务器发送过来,都会触发事件控制器.在事件处理器的内部我们写入我们要执行的代码去读取和处理收到的数据.从一个前端服务器读取数据,Socket类为我们提供了许多不同的方法,这些方法依赖于你所读得数据类型.例如,你可以通过readByte()方法读一个byte数据,或者通过一个使用readUnsignedInt()方法去读一个无符号整数.下面这个表列出来能够从服务器读取的数据类型,返回值, 和read方法每次读入的字节数.Table:Socket read methods for various datatypes方法:返回值类型描述字节数readBoolean( ):Boolean 从Socket读取一个Boolean值. 1 readByte( ):int 从Socket读取一个byte值. 1readDouble( ):Number 从Socket读取一个IEEE 754双精度浮点数.8readFloat( ):Number 从Socket读取一个IEEE 754单精度浮点数.4readInt( ):int 从Socket读取一个有符号32-bit整数值. 4 readObject( ):* 从Socket读取一个AMF-encoded对象. n readShort( ):int 从Socket读取一个有符号16-bit整数值. 2 readUnsignedByte( ):uint 从Socket读取一个无符号字节. 1 readUnsignedInt( ):uint 从Socket读取一个无符号32-bit整数 4readUnsignedShort( ):uint 从Socket读取一个无符号16-bit整数. 2 readUTF( ):String 从Socket读取一个一个UTF8字符串. n有两个额外的方法没有在上面这个表中描述.它们分别是readBytes()和readUTFBytes().readBytes()方法只可以让socket读数据但不能返回一个值,并且该方法需要3个参数:bytes:一个flash.util.ByteArray实例读取从socket中收到的数据.offset:一个uint值,指定从什么位置开始读取socket中收到数据的偏移量.默认值为0. length:一个uint值,用于指定读取bytes的数量.默认值为0,意思就是说将所有的可用的数据都放入ByteArray中.另一个readUTFBytes()方法,只需要一个长度参数用于指定UTF-8字节的读入数量,并且该方法会将所有读入的字节码转换成为字符串类型.注意:在从一个Socket读数据之前,首先要判断bytesAvailable的属性.如果你不知道要读入的数据类型是什么就去读数据的话,将会产生一个错误(flash.errors.EOFError).下面的例子代码连接了一个socket服务器,读取并显示每次从服务器发来的数据.package {import flash.display.Sprite;import flash.events.ProgressEvent;import .Socket;public class SocketExample extends Sprite {private var socket:Socket;public function SocketExample( ) {socket = new Socket( );// Listen for when data is received from the socket serversocket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );// Connect to the serversocket.connect( "localhost", 2900 );}private function onSocketData( eventrogressEvent ):void {trace( "Socket received " + socket.bytesAvailable + " byte(s) of data:" );// Loop over all of the received data, and only read a byte if there // is one availablewhile ( socket.bytesAvailable ) {// Read a byte from the socket and display itvar data:int = socket.readByte( );trace( data );}}}}在上面的这个例子中,如果一个socket服务器发送回一个消息(例如"hello"),当一个客户段连入服务器就会返回并输出下面类似的文字:Socket received 5 byte(s) of data:72101108108111注意:一旦数据从socket读出,它就不能再次被读.例如,读一个字节之后,这个字节就不能再"放回来",只能读后边的字节.当收到的数据为ASCII编码,你可以通过readUTFBytes()方法重新构建一个字符串.readUTFBytes()方法需要知道多少个字节需要转换为字符串.你可以使用bytesAvailable去读所有的字节数据:var string:String = socket.readUTFBytes(socket.bytesAvailable);XMLSocket类的动作和Socket类相比在从服务器接受数据的风格相似.两者都是通过事件监听器来监听数据接收通知的,这主要取决于Flash异步的Socket实现.然而,在处理实际数据的时候有很大的不同.有个XMLSocket实例在从服务器下载完数据后分发数据事件.通过flash.events.DataEvent.DATA常量定义的数据事件包含一个data属性,该属性包含了从服务器收到的信息.注意:使用XMLSocket从服务器返回的数据总是认为是一个字符串类型的数据.这样不用为任何数据类型的数据指定读取方法.这些从服务器返回的数据是没有经过任何处理的原始数据.因此,你不能通过XMLSocket连接立即使用XML,你发送和接收的都是纯字符串数据.如果你期望XML,在你处理数据之前,你必须首先将这些数据转换为一个XML的实例.下面的这段代码在初始化的时候通过XMLSocket连接到了本地服务器的2900端口.在连接成功之后,一个<test>消息会发送到服务器.onData事件监听者控制从服务器返回的响应.在本例中返回字符串<response><testsuccess='true'/></response>.你可以通过事件的 data属性发现为字符串数据,然后XML类的构造函数将字符串转换成为了XML实例.最后,通过使用E4X语法的XML实例的一部分信息.(关于通过使用E4X处理XML的更多详细信息,我们需要另外讨论.)package {import flash.display.Sprite;import flash.events.Event;import flash.events.DataEvent;import .XMLSocket;public class SocketExample extends Sprite {private var xmlSocket:XMLSocket;public function SocketExample( ) {xmlSocket = new XMLSocket( );// Connect listener to send a message to the server// after we make a successful connectionxmlSocket.addEventListener( Event.CONNECT, onConnect );// Listen for when data is received from the socket serverxmlSocket.addEventListener( DataEvent.DATA, onData );// Connect to the serverxmlSocket.connect( "localhost", 2900 );}private function onConnect( event:Event ):void {xmlSocket.send( "<test/>" );}private function onData( eventataEvent ):void {// The raw string returned from the server.// It might look something like this:// <response><test success='true'/></response>trace( event.data );// Convert the string into XMLvar response:XML = new XML( event.data );// Using E4X, access the success attribute of the "test"// element node in the response.// Output: truetrace( response.test.@success );}}}注意:在data事件分发数据之前,XMLSocket实例必须从服务器收到一个表示为空的byte('\\0').也就是说,从服务器仅仅只发送所需要的字符串是不够的,必须在结尾处加入一个表示为空的byte.4.同Socket服务器进行握手同Socket服务器进行握手,并确定收到了什么样的数据和如何处理这些数据.解决方法:创建不同的常量来声明协议的状态.使用这些常量将指定的处理函数映射到相应的状态.在一个socketData事件控制器中,通过状态映射调用这些函数的.讨论:建立Socket连接通常要处理握手这个环节.尤其是在服务器初始化需要向客户端发送数据.然后客户端通过一种特殊的方式相应这些数据,接着服务器因此再次响应.整个处理过程直到握手完成并且建立起一个"正常的"连接为止.处理服务器的不同响应是非难的,主要的原因是socketData事件控制器不能保存上下文的顺序.也就是说,服务器的响应不会告诉你"为什么"响应, 也不告诉你这些响应数据被那个处理程序来处理.要想知道如何处理这些从服务器返回的响应不能从响应的本身来获得,尤其在响应变化的时候.或许一个响应返回了两个字节码,另一个返回了一个整数值还跟了一个双精度浮点数.这样看来让响应本身处理自己是一大难题.我们通过创建一个状态量来标注不同的上下文,服务器通过这些上下文将数据发送到客户端.与这些状态量都有一个相关联的函数来处理该数据,这样你就可以很轻松的按照当前的协议状态去调用正确的处理函数.当你要与一个Socket服务器建立连接需要考虑如下几个步骤:1.当与服务器连接的时候,服务器立刻返回一个标志服务器可以支持的最高协议版本号的整数值.2.客户端在响应的时候会返回一个实际使用协议的版本号.3. 服务器返回一个8byte的鉴定码.4.然后客户端将这鉴定码返回到服务器.5.如果客户端的响应不是服务器端所期望的,或者,就在这个时候该协议变成了一个常规操作模式,于是握手结束.实际上在第四步可以在鉴定码中包含更多的安全响应.你可以通过发送各种加密方法的密匙来代替逐个发送的鉴定码.这通常使用在客户端向用户索要密码的时候, 然后密码成为了加密过的8byte鉴定码.该加密过的鉴定码接着返回到服务器.如果响应的鉴定码匙服务器所期望的,客户端就知道该密码是正确的,然后同意建立连接.实现握手框架,你首先要为处理从服务器返回的不同类型的数据分别创建常量.首先,你要从步骤1确定版本号.然后从步骤3收取鉴定码.最后就是步骤5的常规操作模式.我们可以声明如下常量:public const DETERMINE_VERSION:int = 0;public const RECEIVE_CHALLENGE:int = 1;public const NORMAL:int = 2;常量的值并不重要,重要的是这些值要是不同的值,两两之间不能有相同的整数值.下一个步骤我们就要为不同的数据创建不同处理函数了.创建的这三个函数分别被命名为readVersion( ), readChallenge( ) 和 readNormalProtocol( ). 创建完这三个函数后,我们就必须将这三个函数分别映射到前面不同状态常量,从而分别处理在该状态中收到的数据.代码如下:stateMap = new Object( );stateMap[ DETERMINE_VERSION ] = readVersion;stateMap[ RECEIVE_CHALLENGE ] = readChallenge;stateMap[ NORMAL ] = readNormalProtocol;最后一步是编写socketData事件处理控制器,只有通过这样的方式,建立在当前协议状态之上的正确的处理函数才可以被调用.首先需要创建一个 currentState的int变量.然后使用stateMap去查询与currentState相关联的函数,这样处理函数就可以被正确调用了.var processFunc:Function = stateMap[ currentState ];processFunc( ); // Invoke the appropriate processing function下面是一点与薄记相关的处理程序.在你的代码中更新currentState从而确保当前协议的状态.前面我们所探讨的握手步骤的完整的代码如下:package {import flash.display.Sprite;import flash.events.ProgressEvent;import .Socket;import flash.utils.ByteArray;public class SocketExample extends Sprite {// The state constants to describe the protocolpublic const DETERMINE_VERSION:int = 0;public const RECEIVE_CHALLENGE:int = 1;public const NORMAL:int = 2;// Maps a state to a processing functionprivate var stateMap:Object;// Keeps track of the current protocol stateprivate var currentState:int;private var socket:Socket;public function SocketExample( ) {// Initialzes the states mapstateMap = new Object( );stateMap[ DETERMINE_VERSION ] = readVersion;stateMap[ RECEIVE_CHALLENGE ] = readChallenge;stateMap[ NORMAL ] = readNormalProtocol;// Initialze the current statecurrentState = DETERMINE_VERSION;// Create and connect the socketsocket = new Socket( );socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData ); socket.connect( "localhost", 2900 );}private function onSocketData( eventrogressEvent ):void {// Look up the processing function based on the current statevar processFunc:Function = stateMap[ currentState ];processFunc( );}private function readVersion( ):void {// Step 1 - read the version from the servervar version:int = socket.readInt( );// Once the version is read, the next state is receiving// the challenge from the servercurrentState = RECEIVE_CHALLENGE;// Step 2 - write the version back to the serversocket.writeInt( version );socket.flush( );}private function readChallenge( ):void {// Step 3 - read the 8 byte challenge into a byte arrayvar bytes:ByteArray = new ByteArray( );socket.readBytes( bytes, 0, 8 );// After the challenge is received, the next state is// the normal protocol operationcurrentState = NORMAL;// Step 4 - write the bytes back to the serversocket.writeBytes( bytes );socket.flush( );}private function readNormalProtocol( ):void {// Step 5 - process the normal socket messages here now that// that handshaking process is complete}}}5.与Socket服务器断开与Socket服务器断开,或者当服务器想与你断开的时候发消息给你.解决方法:通过调用Socket.close( )或者XMLSocket.close( )方法显性的断开与服务器的连接.同时可以通过监听close事件获得服务器主动断开的消息.讨论:通常情况下我们需要对程序进行下清理工作.比如说,你创建了一个对象,当这个对象没有用的时候我们就要删除它.因此,无论我们什么时候连接一个 Socket服务器,都要在我们完成了必要的任务之后显性的断开连接.一直留着无用的Socket连接浪费网络资源,应该尽量避免这种情况.如果你没有断开一个连接,那么这个服务器会继续保持着这个无用的连接.这样一来就很快会超过了服务器最大Socket连接上线.Socket和 XMLSocket对象断开连接的方法是一样的.你只需要调用close()方法就可以了:// Assume socket is a connected Socket instancesocket.close( ); // Disconnect from the server同样的,XMLSocket对象断开连接的方法一样:// Assume xmlSocket is a connected XMLSocket instancexmlSocket.close( ); // Disconnect from the serverclose()方法用于通知服务器客户端想要断开连接.当服务器主动断开连接会发消息通知客户端.可以通过调用addEventListener()方法注册一个close事件的一个监听器.Socket 和 XMLSocket都是使用Event.CLOSE作为"连接断开"事件类型的;例如:// Add an event listener to be notified when the server disconnects// the clientsocket.addEventListener( Event.CLOSE, onClose );注意:调用close()方法是不会触发close事件的,只用服务器主动发起断开才会触发.一旦一个Socket断开了,就无法读写数据了.如果你想要从新这个连接,你只能再建立个新的连接了.6.处理使用Sockets时候引发的错误解决方法:使用try/catch处理I/O和EOF(end of file)错误.讨论:Socket和XMLSocket类对错误的处理很类似.不如,当调用connect()方法的时候,在下面任何一个条件成立的情况下Socket和 XMLSocket对象会抛出一个类型为SecurityError的错误.* 该.swf未通过本地安全认证.* 端口号大于655535.当调用XMLSocket对象的send()或者Socket对象的flush()的时候,如果socket还没有连接这两个方法都会抛出一个类型为 IOError的错误.尽管你可以将send()或者flush()方法放入try/catch结构块中,你也不能依赖于try/catch结构块作为你应用程序的逻辑.更好的办法是,在调用send()或者flush()方法之前使用一个if语句首先判断一下Socket对象的connected属性是否为True.例如,下面的代码使用了if语句作为程序逻辑的一部分,当Socket对象当前不是连接状态就调用connectToSocketServer()方法.但是我们依然需要将flush()方法放到try/catch语句块中.通过使用try /catch语句块将flush()方法抛出的错误写入到日志中:if ( socket.connected ) {try {socket.flush( );}catch( error:IOError ) {logInstance.write( "socket.flush error\n" + error );}}else {connectToSocketServer( );}所有的Socket类的read方法都能够抛出EOFError和IOError类型的错误.当你试图读一个数据,但是没有任何可用数据将触发EOF错误.当你试图从一个已经关闭的Socket对象中对数据时将会抛出I/O错误.除了Socket和XMLSocket类的方法能够抛出的错误以外,这些类的对象还会分发错误事件.有两种基本的错误事件类型,他们分别由 socketIOError和securityError错误引起.IOError事件为IOErrorEvent类型,当数据发送或接收失败触发该事件.SecurityError事件是SecurityErrorEvent类型,当一个Socket尝试连接一个服务器,但由于服务器不在安全沙箱范围之内或者端口号小于1024的时候触发该错误事件.注意:这两种安全策略引起的错误都可以通过跨域访问策略文件解决.。
Flex向Java调用
Flex向Java调用前几天由于搞项目需要用到Flex 向 Java 服务通信传输数据,搞了好大半天灰常痛苦,在网上的片段很少,现在我整合一下。
希望对以后要用到的童靴有一点用处。
我项目里面传输的是二进制数据。
Flex 向 Java servlet通信,Java服务端再返回数值到Flex客户端。
童鞋们先要下载Flex 的两个包(flex-messaging-common.jar,flex-messaging-core.jar)放置Java工程的lib下。
标签:Apache Flex JavaServlet代码片段(6)[文件] AllServlet.java ~ 3KB 下载(37)view sourceprint?package cn.tianqi.game.servlet;import java.io.DataOutputStream;import java.io.IOException;import java.util.Collection;import java.util.List;import java.util.Map;import java.util.zip.DeflaterOutputStream;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.tianqi.game.action.util.AmfDataServlet;import cn.tianqi.game.action.util.Configuration;import cn.tianqi.game.action.view.MapBean;import cn.tianqi.game.action.view.ResourceBean;import cn.tianqi.game.action.view.SysBean;import cn.tianqi.game.action.vo.ResourceVo;import flex.messaging.io.SerializationContext;import flex.messaging.io.amf.Amf3Output;public class AllServlet extends HttpServlet {private static final long serialVersionUID = 1L;private AmfDataServlet amfData=new AmfDataServlet();private ResourceBean catBean=ResourceBean.getInstance();private MapBean mapBean=MapBean.getInstance();private SysBean sysBean=SysBean.getInstance();public AllServlet() {super();}public void destroy() {super.destroy(); // Just puts "destroy" string in log// Put your code here}public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}@SuppressWarnings("unchecked")public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=utf-8");Mapmap=(Map)amfData.getObj(request.getContentLength(), request.getInputStream());String method=String.valueOf(map.get("method"));if(method.equals(Configuration.SYS_INIT)){Collection coll=catBean.resourceCat().values();//所有素材资源数据Collection coll2=catBean.mapResource().values();//所有地图素材资源数据Collection coll3=mapBean.selectAllMap().values();//所有地图资源数据List<ResourceVo> coll4=catBean.selectALLRes();//所有资源表数据send(response, sysBean.sysInit(coll,coll2,coll3,coll4));}else if(method.equals(Configuration.CAT_RESOURCE)){send(response, catBean.resourceCat().values());}elseif(String.valueOf(map.get("method")).equals(Configuration.MAP _RESOURCE)){send(response, catBean.mapResource().values());}elseif(method.equals(Configuration.CAT_RESOURCE_ADD)){ Map cat=(Map)map.get("data");send(response, catBean.saveResourceCat(cat));}elseif(method.equals(Configuration.MAP_RESOURCE_DATA)){ send(response, mapBean.selectAllMap().values());}else if(method.equals(Configuration.MAP_DATA_SAVE)){Map mds=(Map)map.get("data");send(response, mapBean.saveMap(mds));}}protected void send(HttpServletResponse response,Object obj) throws IOException{Amf3Output amf3=new Amf3Output(new SerializationContext());DeflaterOutputStream stream = new DeflaterOutputStream(newDataOutputStream(response.getOutputStream()));amf3.setOutputStream(stream);amf3.writeObject(obj);stream.finish();}public void init() throws ServletException {// Put your code here}}[文件] AmfDataServlet.java ~ 2KB 下载(28)view sourceprint?package cn.tianqi.game.action.util;import java.io.ByteArrayInputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import javax.servlet.ServletInputStream;import flex.messaging.io.SerializationContext;import flex.messaging.io.amf.Amf3Input;public class AmfDataServlet {/*** 解析HttpServletRequest上传的二进制数据* @param contentLength 上传的数据总长度(request.getContentLength())* @param stream 上传的数据(request.getInputStream())* @return Object*/public Object getObj(int contentLength, ServletInputStream stream) {Object obj = null;DataInputStream dis = new DataInputStream(stream);byte[] by = new byte[contentLength];try {int bytesRead = 0, totalBytesRead = 0;while (totalBytesRead < contentLength) {bytesRead = dis.read(by, totalBytesRead, contentLength);totalBytesRead += bytesRead;}Amf3Input amf = new Amf3Input(new SerializationContext()); InputStream is = new ByteArrayInputStream(by);amf.setInputStream(is);obj = amf.readObject();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return obj;}/*** 解析byte[]转成Object* @param bytes 数据* @return Object*/public Object getObj(byte[] bytes){Object obj=null;try {Amf3Input amf = new Amf3Input(new SerializationContext()); InputStream is = new ByteArrayInputStream(bytes);amf.setInputStream(is);obj=amf.readObject();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return obj;}}[文件] Servlet.as ~ 2KB 下载(24)view sourceprint?package cn.tianqi.game.servlet{import .URLLoader;import .URLLoaderDataFormat;import .URLRequest;import .URLRequestMethod;public class Servlet{private static var servlet:Servlet=null;private var httpUrl:String="http://192.168.1.101:8080/manager/";//private var httpUrl:String="http://localhost:8080/manager/";public function allServlet():URLRequest{var urlRequest:URLRequest=new URLRequest(httpUrl+"AllServlet");urlRequest.contentType = 'applicatoin/octet-stream';urlRequest.method=URLRequestMethod.POST;return urlRequest;}// public function resourceCatServlet():URLRequest // {// var urlRequest:URLRequest=new URLRequest(httpUrl+"CatInfoServlet");// urlRequest.contentType = "applicatoin/octet-stream";//urlRequest.method=URLRequestMethod.POST;// return urlRequest;// }public function fileUpload():URLRequest{var urlRequest:URLRequest=new URLRequest(httpUrl+"FileUpload");return urlRequest;}// public function saveResourceCat():URLRequest// {// var urlRequest:URLRequest=new URLRequest(httpUrl+"ResourceAddServlet");//urlRequest.method=URLRequestMethod.POST;// return urlRequest;// }// public function mapResource():URLRequest// {// var urlRequest:URLRequest=new URLRequest(httpUrl+"MapResourceServlet");//urlRequest.method=URLRequestMethod.POST;// return urlRequest;// }// public function saveMapResource():URLRequest// {// var urlRequest:URLRequest=new URLRequest(httpUrl+"MapResourceDataServlet");//urlRequest.method=URLRequestMethod.POST;// return urlRequest;// }public static function getServlet():Servlet{if(servlet==null){servlet=new Servlet();}return servlet;}}}[文件] flex-messaging-common.jar ~ 92KB 下载(53)[文件] flex-messaging-core.jar ~ 599KB 下载(49)[代码] [Java]代码view sourceprint?<?xml version="1.0" encoding="utf-8"?><mx:Applicationxmlns:mx="/2006/mxml"layout="absolute" minWidth="955" minHeight="600"> <mx:Script><![CDATA[import cn.tianqi.game.servlet.Servlet;import mx.collections.ArrayCollection;private var loader:URLLoader=null;private var v:URLVariables=null;private var urls:URLRequest=null;protected function mapResource_clickHandler(event:MouseEvent):void{loader=new URLLoader();loader.dataFormat = URLLoaderDataFormat.BINARY;loader.addEventListener(PLETE, loaderHandler);loader.addEventListener(SecurityErrorEvent.SECURITY_ERRO R, loaderHandler);loader.addEventListener(IOErrorEvent.IO_ERROR, loaderHandler);// v=new URLVariables();// v.type=2;//urls=Servlet.getServlet().mapResource();urls=Servlet.getServlet().allServlet();//urls.contentType = 'applicatoin/octet-stream';var obj:Object=new Object();obj.n="南泥湾";obj.w=201;obj.h=150;obj.ms="101010100000001111000011111000000000";var dt:ByteArray=new ByteArray();dt.writeByte(100);obj.dt=dt;var obj1:Object=new Object();obj1.method="mapDataSave";obj1.data=obj;var byteArr:ByteArray=new ByteArray();byteArr.writeObject(obj1);urls.data=byteArr;// urls.data=v;loader.load(urls);}protected function loaderHandler(event:Event):void{trace(event.type);switch(event.type){case PLETE:var byte:ByteArray = event.target.data as ByteArray;byte.uncompress();var obj:Object = byte.readObject();var arr:ArrayCollection=obj as ArrayCollection;break;}}]]></mx:Script><mx:Button id="mapResource" label="点击我" click="mapResource_clickHandler(event)"/></mx:Application>。
flex的三个参数
flex的三个参数Flex's Three Parameters.Flexbox, also known as Flexible Box Layout, is a layout module in CSS that gives you complete control over the layout of your web pages. It's a powerful tool that can be used to create complex layouts easily and responsively.Flexbox has three main parameters that you can use to control the layout of your elements: `flex-direction`,`flex-wrap`, and `justify-content`.1. flex-direction.The `flex-direction` property determines the direction in which your flex items are laid out. You can set it to`row`, `row-reverse`, `column`, or `column-reverse`.`row` is the default value, and it lays out your items horizontally from left to right.`row-reverse` lays out your items horizontally from right to left.`column` lays out your items vertically from top to bottom.`column-reverse` lays out your items vertically from bottom to top.2. flex-wrap.The `flex-wrap` property determines whether your flex items wrap or not. You can set it to `nowrap`, `wrap`, or`wrap-reverse`.`nowrap` is the default value, and it prevents yourflex items from wrapping.`wrap` allows your flex items to wrap, creating a new line of flex items when they reach the end of the container.`wrap-reverse` wraps your flex items in reverse order, creating a new line of flex items at the beginning of the container.3. justify-content.The `justify-content` property determines how your flex items are justified within the container. You can set it to `flex-start`, `flex-end`, `center`, `space-between`, or`space-around`.`flex-start` is the default value, and it aligns your flex items to the start of the container.`flex-end` aligns your flex items to the end of the container.`center` centers your flex items within the container.`space-between` distributes your flex items evenly within the container, with the first and last flex items touching the edges of the container.`space-around` distributes your flex items evenlywithin the container, with equal spacing between each flex item and the edges of the container.These three parameters give you a lot of control overthe layout of your flex items. By experimenting withdifferent values, you can create layouts that are both visually appealing and functional.中文回答:Flex 的三个参数。
基于Flex和J2EE架构的数据发布系统的设计与实现
基于Flex和J2EE架构的数据发布系统的设计与实现摘要:提出了开发基于Flex和J2EE架构的数据发布系统,应用Flex作为展现层实现,应用Hibernate作为持久层实现,结合Spring技术作为业务层实现,进行框架整合,从而设计了一套松耦合、可扩展的RIA数据发布系统,初步解决了当前数据发布中存在的问题。
关键词:RIA;数据发布;Flex;Spring框架;Hibernate框架为了解决Web应用程序中人机界面单调、交互性弱、开发效率低、用户体验差等一系列问题,产生了富因特网(Rich Internet Applications)技术,RIA程序是将桌面应用程序的用户交互体验与传统的Web应用的部署灵活性和成本分析结合起来的网络应用程序。
RIA中提供可承载已编译客户端应用程序(以文件形式,用HTTP传递)的运行环境,客户端应用程序使用异步客户/服务器架构连接现有的后端应用服务器,这是一种安全、可升级、具有良好适应性的新的面向服务模型。
作为最完善的RIA系统开发技术,Adobe Flex提供了一整套的RIA组件框架和运行时数据处理服务来构建复杂的网络应用程序,利用它可以开发出具有良好的软件体系结构、很好的兼容性和更具吸引力的用户体验的软件。
本文根据Web应用的经典分层理论,应用Flex 作为展现层实现,应用Hibernate作为持久层实现,并结合Spring技术作为业务层实现,进行框架整合,设计出一套足够灵活、松散耦合、可扩展性强、高效的数据发布系统。
1系统需求分析系统需求分析是系统项目成功的基础,需要按照软件工程方法进行全面合理的需求分析。
数据发布系统有着自身的特点和需求,现进行分析设计。
1.1系统流程分析系统参与者有系统管理员、数据管理员、普通用户3种,图1为参与者进入系统后的活动图。
图1系统活动图1.2系统功能性需求数据发布系统主要由3个功能模块组成:数据发布模块、用户管理模块、系统管理模块。
将 Flex 集成到 Java EE 应用程序的最佳实践
将Flex 集成到Java EE 应用程序的最佳实践传统的Java EE 应用程序通常使用某种MVC 框架(例如,Struts)作为前端用户界面,随着Flex 的兴起,基于RIA 的客户端能够给用户带来更酷的界面,更短的响应时间,以及更接近于桌面应用程序的体验。
本文将讲述如何将Flex 集成至一个现有的Java EE 应用程序中,以及如何应用最佳实践高效率地并行开发Java EE 和Flex。
开发环境本文的开发环境为Windows 7 Ultimate,Eclipse 3.4,Flex Builder 3(从参考资源获得下载链接)。
Java EE 服务器使用Resin 3.2,当然,您也可以使用Tomcat 等其他Java EE 服务器。
现有的Java EE 应用假定我们已经拥有了一个管理雇员信息的Java EE 应用,名为EmployeeMgmt-Server,结构如图1所示:图1. Java EE 工程结构这是一个典型的Java EE 应用,使用了流行的Spring 框架。
为了简化数据库操作,我们使用了内存数据库HSQLDB。
对这个简单的应用,省略了DAO,直接在Façade 中通过Spring 的JdbcTemplate 操作数据库。
最后,EmployeeMgmt 应用通过Servlet 和JSP 页面为用户提供前端界面:图2. EmployeeMgmt Web 界面该界面为传统的HTML 页面,用户每次点击某个链接都需要刷新页面。
由于Employee Management 系统更接近于传统的桌面应用程序,因此,用Flex 重新编写界面会带来更好的用户体验。
集成BlazeDS如何将Flex 集成至该Java EE 应用呢?现在,我们希望用Flex 替换掉原有的Servlet 和JSP 页面,就需要让Flex 和Java EE 后端通信。
Flex 支持多种远程调用方式,包括HTTP,Web Services 和AMF。
06 FlexJava通讯-Flex调用AO接口
作者:严瑞背景简介:新疆阿福迪公司进行Flex开发,需要开发有组档线的缓冲区分析功能,在这里感谢郑江涛提供的实现思路。
实现结果如下:1、开发环境:⏹Eclipse必要有J2EE开发环境;(我用的eclipse3.5)⏹Eclipse需要安装flex插件(我用的Flex sdk4.1.0)⏹Web工程lib需要加入arcobject.jar包(arcgis10.0)⏹在这个eclipse中,需要进行Flex和java通讯(请详看《flex和java通讯配置.pdf》,需要下载Blaseds.war包)2、功能实现思路:(1)根据圆心和半径构造一个圆,请看代码部分中:构造圆代码部分。
(2)根据第一步构造的圆,查询和这个圆相交的阻挡线图层(见代码)(3)如果能查到相交的阻挡线,则将线进行合并(见代码)。
(4)用合并后的线去分割圆,将圆分割为多个部分(见代码);(5)判断第五步中各个圆的部分,哪个部分包含圆心,则这个包含圆心的部分就是最终要求到的结果,返回前台(为json)。
(见代码)3、Flex调用AO注意事项:(1)Server的连接方式(见代码)(2)对象不能new,必须创建(见代码)4、代码Flex端<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="/mxml/2009"xmlns:s="library:///flex/spark"xmlns:mx="library:///flex/mx" minWidth="955" minHeight="600" xmlns:esri="/2008/ags"><fx:Script><![CDATA[import com.esri.ags.Graphic;import com.esri.ags.events.MapMouseEvent;import com.esri.ags.geometry.MapPoint;import com.esri.ags.geometry.Polygon;import com.esri.ags.symbols.SimpleFillSymbol;import com.esri.ags.symbols.SimpleLineSymbol;import mx.controls.Alert;import mx.rpc.events.ResultEvent;import com.esri.ags.utils.JSON;private function OnClick(event:MapMouseEvent):void{var mapPoint:MapPoint = event.mapPoint;var graphic:Graphic = new Graphic(mapPoint);myGraphicsLayer.add(graphic);Alert.show("aa");h.getBufferFeature(mapPoint.x.toString(), mapPoint.y.toString());}private function result(event:Object):void{var outlineSym:SimpleLineSymbol =new SimpleLineSymbol("solid", 0xFF0000, 1, 2);var polySym:SimpleFillSymbol =new SimpleFillSymbol("solid", 0xFF0000, 0.15, outlineSym);var jsonStr:String = event.result as String;//解析jsonvar jsonObj:Object = new Object();Alert.show("bb");jsonObj = JSON.decode(jsonStr);Alert.show("cc");var ptStr:String = jsonObj.ring;//将点坐标放到数组里面var ptArray:Array = ptStr.split(",");var rings:Array = new Array();var ring:Array = new Array();for(var i:int=0;i<ptArray.length;i+=2){var pt:MapPoint =new MapPoint(Number(ptArray[i]),Number(ptArray[i+1]));ring.push(pt);}rings.push(ring);var myPolygon:Polygon =new Polygon(rings,myMap.spatialReference);var gra:Graphic = new Graphic(myPolygon);gra.symbol = polySym;myGraphicsLayer.add(gra);myMap.addLayer(myGraphicsLayer);}private function clearGraphic():void{myGraphicsLayer.clear();}]]></fx:Script><fx:Declarations><esri:Extent xmin="857300.5841894592" ymin="3791501.427000717" xmax=" 875540.9956702823" ymax="3803042.575083013"><esri:SpatialReference wkid="32648"/></esri:Extent><s:RemoteObject id="h" destination="buffer" ><!--mx:method name="getHelloWorld" result="result(event)"/--><s:method name="getBufferFeature" result="result(event)"/></s:RemoteObject></fx:Declarations><esri:Map id="myMap" mapClick="OnClick(event)"><esri:ArcGISDynamicMapServiceLayerurl="http://127.0.0.1:8399/arcgis/rest/services/mountainBuffer/MapServer"/> <esri:GraphicsLayer id="myGraphicsLayer"/></esri:Map><s:Button id="button" label="清理图层" click="clearGraphic()"/><!--s:Button id="button" label="测试" click="yy()"/--></s:Application>Java端package mypacket.demo;import java.awt.Point;import java.io.IOException;import .UnknownHostException;import com.esri.arcgis.carto.FeatureLayer;import com.esri.arcgis.carto.IElement;import com.esri.arcgis.carto.IFeatureLayer;import com.esri.arcgis.carto.IGraphicsLayer;import com.esri.arcgis.carto.ILayer;import com.esri.arcgis.carto.IMap;import com.esri.arcgis.carto.IPolygonElement;import com.esri.arcgis.carto.MapServer;import com.esri.arcgis.carto.PolygonElement;import com.esri.arcgis.system.ServerInitializer;import com.esri.arcgis.server.*;import com.esri.arcgis.server.json.JSONObject;import com.esri.arcgis.geodatabase.IFeature;import com.esri.arcgis.geodatabase.IFeatureClass;import com.esri.arcgis.geodatabase.IFeatureCursor;import com.esri.arcgis.geodatabase.IQueryFilter;import com.esri.arcgis.geodatabase.ISpatialFilter;import com.esri.arcgis.geodatabase.QueryFilter;import com.esri.arcgis.geodatabase.SpatialFilter;import com.esri.arcgis.geodatabase.esriSpatialRelEnum;import com.esri.arcgis.geometry.*;import com.esri.arcgis.geoprocessing.gen.GenMethod.Type;import com.esri.arcgis.interop.AutomationException;import com.esri.arcgis.carto.IGraphicsContainer;import com.esri.arcgis.display.*;public class bufferJava {private static IMap map=null;IServerContext serverContext;IServerObjectManager som = null;IServerContext soc = null;MapServer mapServer = null;IGraphicsContainer graphicsContainer = null;//连接serverpublic bufferJava() throws UnknownHostException, IOException{String ip = "localhost";String user = "arcgismanager";String password = "123";String serverName = "mountainBuffer";String serverType = "MapServer";ServerInitializer serverInitializer = new ServerInitializer();serverInitializer.initializeServer(ip, user, password);ServerConnection serverConn = new ServerConnection();serverConn.connect(ip);som = serverConn.getServerObjectManager();soc = som.createServerContext(serverName, serverType);mapServer = (MapServer)soc.getServerObject();map = mapServer.getMap(mapServer.getDefaultMapName());}public String getBufferFeature(String x,String y) throws UnknownHostException, IOException {Double R = 500.0;System.out.println("x----------444---55--------"+x.toString());Double pointX = Double.parseDouble(x);Double pointY = Double.parseDouble(y);IPoint point = (IPoint) soc.createObject(com.esri.arcgis.geometry.Point.getClsid());point.setX(pointX);point.setY(pointY);point.setSpatialReferenceByRef(map.getSpatialReference());System.out.println("坐标系:"+point.getSpatialReference().getName());//缓冲区分析IPointCollection pointCollection = (IPointCollection) soc.createObject(Polygon.getClsid());Double degree;StringBuilder sb = new StringBuilder();//构造Json,用于返回结果的格式sb.append(" {"+"\"ring\":"+"["+"\r");//构造缓冲圆for(int i=0;i<360;i+=2){degree = i*(Math.PI/180);double x1 = pointX + Math.cos(degree)*R;double y1 = pointY +Math.sin(degree)*R;IPoint pt =(IPoint) soc.createObject(com.esri.arcgis.geometry.Point.getClsid());pt.setX(x1);pt.setY(y1);pt.setSpatialReferenceByRef(map.getSpatialReference());pointCollection.addPoint(pt, null, null);}//得到缓冲区的圆IPolygon polyCircle = (IPolygon)pointCollection;polyCircle.setSpatialReferenceByRef(map.getSpatialReference());IGeometry geometry = (IGeometry)polyCircle;//查询到和圆相交的山脊线IFeatureClass featureClass = this.queryLayerByName("mountain_project").getFeatureClass();ISpatialFilter spatialFilter = (ISpatialFilter) soc.createObject(SpatialFilter.getClsid());spatialFilter.setGeometryByRef(geometry);spatialFilter.setGeometryField("SHAPE");spatialFilter.setSpatialRel(esriSpatialRelEnum.esriSpatialRelIndexIntersects);IFeatureCursor featureCursor = featureClass.search(spatialFilter, false);////如果查到的山脊线不为空,合并山脊线//IGeometry geomUnion = (IGeometry) soc.createObject(Polyline.getClsid());ITopologicalOperator4 topo = (ITopologicalOperator4)geomUnion;IFeature feature = featureCursor.nextFeature();while(feature!=null){ITopologicalOperator4 topo2 = (ITopologicalOperator4)geomUnion;IGeometry geom = feature.getShapeCopy();geomUnion = topo.union(geom);geomUnion = topo2.union(geom);IPolyline line = (IPolyline)feature.getShapeCopy();feature = featureCursor.nextFeature();}IPolyline polyLine = (IPolyline)geomUnion;topo.simplify();polyLine.setSpatialReferenceByRef(map.getSpatialReference());////用线去切割圆//ITopologicalOperator4 topoCut = (ITopologicalOperator4)geometry;topoCut.simplify();IGeometryCollection geometryCollection = topoCut.cut2(polyLine);//判断哪个geometry包含圆心for(int j=0;j<geometryCollection.getGeometryCount();j++){IGeometry g = geometryCollection.getGeometry(j);IPolygon pG = (IPolygon)g;IRelationalOperator relationOperator = (IRelationalOperator)pG;Boolean bool = relationOperator.contains(point);if(bool==true){IPointCollection ptC = (IPointCollection)pG;for(int k=0;k<ptC.getPointCount();k++){IPoint p = ptC.getPoint(k);if(k!=(ptC.getPointCount()-1)){sb.append(" ["+p.getX()+","+p.getY()+"],"+"\r");}else if(k==(ptC.getPointCount()-1)){sb.append(" ["+p.getX()+","+p.getY()+"]"+"\r");}}}}sb.append(" ]," +"\"spatialReference\":{"+"\"wkid\":"+"32648"+"}");sb.append("}");soc.releaseContext();//返回到前台return sb.toString();}//得到要查询的图层private IFeatureLayer queryLayerByName(String name) throws AutomationException, IOException {for(int i=0;i<this.map.getLayerCount();i++){IFeatureLayer featureLayer = (IFeatureLayer) this.map.getLayer(0);if(featureLayer.getName().equals("mountain_project"));{return featureLayer;}}return null;}//得到和缓冲圆相交的山脊线private IFeatureCursor queryMountainLine(IFeatureClass featureClass, IGeometry geometry) throws UnknownHostException, IOException{ISpatialFilter spatialFilter = (ISpatialFilter) soc.createObject(SpatialFilter.getClsid());spatialFilter.setGeometryByRef(geometry);spatialFilter.setGeometryField("SHAPE");spatialFilter.setSpatialRel(esriSpatialRelEnum.esriSpatialRelIndexIntersects);IFeatureCursor featureCursor = featureClass.search(spatialFilter, true);return featureCursor;}}。
java与flex通信
Java与flex通信有三种方式:1 flex 与普通java类通信RemoteObject2 flex 与服务器交互HTTPService3 flex与webservice交互WebService下面讲RemoteObject和WebService两种方式一.RemoteObject控件BlazeDS是一个基于服务器的Java远程调用(remoting)和Web消息传递(messaging)技术,使得运行在浏览器上的Flex应用程序通过使用RemoteObject控件能够实现和后台的Java应用程序相互通信。
Java端创建一个java project 例如名为show new class创建一个showme类在里面写一个showout方法public class showme {public String showout(String value){return"show"+value;}}右击show new—folder 名为web(可以随便起)把blaseds中的WEB-INF和WETA-INF放到web中找到web-WEB-INF-flex-remoting-config 右击openwith-text-Editor 在</default-channels>和</service>之间加入如下代码<destination id="myservice"><properties><source>showme</source></properties></destination>destination标签中id可以随便设写flex端时候destination标签中id必须与java 端相同 source标签中的字段是showme类(而不是其中的方法showout)右击show-properties-Java Builder Path-source 修改Default output folder为show/web/WEB-INF/classesJava端的就完成了在tomcat的安装目录D:\Tomcat 6.0\conf\Catalina\localhost创建一个show.xml文件在里面写入java的路径注意:路径中不能有中文且是双斜杠<?xml version="1.0" encoding="UTF-8"?><Context docBase="C:\\Documents andSettings\\Administrator\\workspace\\show\\web"></Context>启动tomcatFlex端文件-新建-flex项目项目名为play 应用程序类型为web 应用程序服务器类型为J2EE 选择使用远程对象访问服务 BlazeDS点击下一步设置根文件夹根目录和上下根目录根文件夹为java的路径设置完点验证配置若有效会显示web根文件夹和跟URL有效同时输出文件夹自动修改了点击完成即可在play.mxml中粘贴代码<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="/mxml/2009"xmlns:s="library:///flex/spark"xmlns:mx="library:///flex/mx" minWidth="955" minHeight="600"><fx:Script><![CDATA[import mx.rpc.events.FaultEvent;import mx.rpc.events.ResultEvent;protected function remot_resultHandler(event:ResultEvent):void{// TODO Auto-generated method stub//访问成功后执行Labe1.text=event.result.toString();}protected function remot_faultHandler(event:FaultEvent):void{// TODO Auto-generated method stub//访问失败后执行Labe1.text="访问失败!";}protected function butt_clickHandler(event:MouseEvent):void{// TODO Auto-generated method stubremot.showout(text1.text);}]]></fx:Script><fx:Declarations><!-- 将非可视元素(例如服务、值对象)放在此处 --><s:RemoteObject id="remot" destination="myservice"result="remot_resultHandler(event)" fault="remot_faultHandler(event)"/> </fx:Declarations><s:Label id="Labe1" x="237" y="221" text="标签"/><s:Button id="butt" x="235" y="168" label="say"click="butt_clickHandler(event)"/><s:TextInput id="text1" x="235" y="195"/></s:Application>若有数据库的项目需要右击项目名--Properties--java Build Path--Libraries--Add External JARs 加入mysql驱动mysql-connector-java-5.1.7-bin.jar 还要在tomcat的lib目录下面也加上此驱动。
Flex基础
Flex安装配置
解决创建的错误如下图
找到Problems看到有一个错误后肉我们右键选重新创 建HTML模板。这里错误已经解决,但是新的问题又 来了,src是java的源文件夹存java源代码的地方,但 是现在被 flex占用了
Flex安装配置
更改flex的项目源文件为flex_src,右键项目属性找到 flex构建路径的主源文件夹把src改为flex_src如下图
使用ActionScript
While和do while
while循环在循环开始前检查条件;如果循环开始条件 不成立,则不会执行 do while 在循环结束后检查条件,这就适合无论测试条 件是否 成立,都至少将部分代码运行一次。
使用ActionScript
条件语句(if和switch)
Flex安装配置
然后把src文件夹 里面的flexweb.mxml移动到flex_src 文件夹里面。最终目录如下图
(二)实现Flex与JAVA通信
实现Flex与JAVA通信
在src目录创建Java文件MyTest如下图
实现Flex与JAVA通信 配置WebRoot/WEB-INF/flex/remoting-config.xml 如下图
Flex的ActionScript支持两种主流注释形式:行内注释和多行注释 行内注释
行内注释以双斜杠开头,从双斜杠到当前行末尾之间的文本是一条 注释。换行意味着注释结束。
多行注释
如果想添加更多的注释用多行注释,多行注释的开始位置以斜杠加 星号(/*)标示。结束位置以星号加斜杠(*/)
很多时候不方便在MXML创建组件中 的定义事件,如组件是根据动 态 数据创建的,这些事件就需要使用Actionscript代码来动态的定义 事件。
FLEX3通信方式简介
Flex与服务器端的通信方式Flex开发中最重要的内容之一,就是与服务器和数据库的通信。
而这样的通信方式我所知道的大概有七种,其中Blazeds与LCDS可以归结成一种。
如果要实现Flex与客户端应用程序之间的通信,我想主要用到的方法为:Socket通信。
而在Web方面,Flex提供了3个类实现与服务器端的通信:HTTPService,ReObject和WebService。
另外,我们还可以根据外部中间插件来让Flex与服务器端进行通信,我所了解的有Blazeds(Lcds),Red5(FMS)流媒体服务器,PHPRPC。
◆HTTPService类用于超文本传输协议(HTTP)实现与服务器的通信。
Flex应用程序用GET 或POST请求将数据发送到服务端,并处理该请求所返回的XML或字符串。
使用这个HTTPService类,可以与PHP页,ColdFusion页,JSP页,Javaservlet,RubyonRails,以及MicrosoftASP页进行通信。
◆RemoteObject类可以与服务器之间通过ActionScriptMessageFormat(AMF)对象进行通信。
通常来说,我们也可以把Blazeds与Lcds归于这一类。
RemoteObject也可以与java或coldFusion远程网关进行通信,或者通过开源项目(例如AMFPHP.SabreAMF或WebORB)与.NET 和PHP进行通信。
◆WebService类与web服务进行通信,使用基于SOAP的XML或XML,web服务通过web 服务描述语言(WSDL)定义其接口。
◆Socket类可以实现直接与应用程序进行通信,而不必在Web的基础上,通信的方法与JAVA 或.NET之间进行Socket的方法大致上是一样的,具体的,将在下面的章节中介绍。
关于Red5与FMS这两个流媒体服务器,应该说它们本身的优势在于多多媒体上,而实现Flex 与服务器端相连,也是它们最基本的功能之一。
flex调用java方法
一、建立Flex与Java交互的工程。
本文中讲到的交互是利用Blazeds的,因为这个是免费的,呵呵,我是穷人。
首先就是去下载Blazeds的压缩包,这个可以从官网或者CSDN、JavaEye上下到。
解压缩这个包,将里面的Blazeds.war解压,后面建立工程时要使用。
在MyEclipse中建立一个web工程,名为FlexTest。
将刚才解压的Blazeds.war包中的“META-INF”与“WEB-INF”文件夹以及文件夹中的内容拷贝到工程的WebRoot下。
WEB-INF中包含有Flex的配置文件以及Blazeds需要的Jar包。
这时我们就可以在这个工程中写入Java代码了。
本文以一个用户列表为例,建立用户实体类。
代码如下:注意,由于这个实体类需要当做Java代码中方法的返回值传递给Flex中的AS代码,所以需要继承Serializable接口,否则将导致异常的发生。
然后,在建立一个供Flex调用的Java类。
代码如下代码package ;import java.util.ArrayList;import java.util.List;import erBean;public class UserManager {public List<UserBean> getUserList() {List<UserBean> list = new ArrayList<UserBean>();for (int i = 0; i < 10; i++) {UserBean user = new UserBean();user.setUserName("用户" + i);user.setPassword("123");user.setAge(20 + i);user.setEmail("user" + i + "@");list.add(user);}return list;}}这里就不连接数据库去操作了,因为本文重点放在Flex调用Java上,所以写个桩数据用以测试。
flex和java 集成,主要讲述flex获取java的数据服务
So far, you know how to combine Flex and Java using HTTP and web services. The lastchapter surveyed a bunch of alternative mechanisms to achieve this. Most of thesemechani sms i nvolve loosely coupled text-based data i nterchange. Most of theminteract by pulling data. Only one of them, Hessian, transmits binary data. Only one,Hessi an agai n (wi th addi ti onal i nfrastructure powered by the new Java IO), allowsdata push.Now, we delve into more tightly coupled scenarios and efficient binary data transmis-si on usi ng AMF (Acti on Message Format). The AMF speci fi cati on can be accessedonline at . This chapter looks at both pull- and push-based interactions—using data services and media servers. Adobe offers two alterna-tives for data services—the commercial LifeCycle Data Services (LCDS) and the opensource BlazeDS—and it offers a suite of products for media servers: Flash Media Server(FMS) products. There are a few open source alternatives to these as well.In this chapter, I will analyze these products in the context of their applicability torich, engaging enterprise-grade applications. Functionally they can be divided intothe following three topics:Remoting and RPCMessaging and data push Media streaming 257INTEGRATING VIA DATA AND MEDIA SERVICESBy Shashank Tiwari Chapter 7At this point of the book, remoting and RPC should be familiar territory, so let’s start there.Remoting and RPCFlex applications can access the Java server side using data services. They can access Java objects and nvoke remote methods on them. The Flex framework ncludes a cl ent-s de component called RemoteObject . This object acts as a proxy for a data service destination on the server. When config-ured properly, this object handle can be used to invoke RPCs. Before we get into the nitty-gritty of this object and destination configuration, let’s step back and look at the data services architecture.Data services architecture Figure 7-1 is a pictorial summary of the data services architecture. The view is biased to highlight thefunctional elements. It includes technical aspects but skips the internal details in many places. As you look deeper into the nuts and bolts in this chapter, many of these details will emerge.As Figure 7-1 depicts, data services includes the following:Gateway to intercept server-bound callsParser to make sense of AMF messagesSerializer and deserializer to transform objects between ActionScript 3.0 (AS3) and JavaManager to coordinate with and delegate responsibility to server-side objectsMessaging service provider to send and receive messagesBy data services, I mean a class of products that enable remoting and messaging over AMF and proto-cols like Real Time Messaging Protocol (RTMP). RTMP is a proprietary protocol developed by Adobe Systems for streaming audio, video, and data over the Internet. More information on RTMP can be found on W i k i ped i a at /wiki/Real_Time_Messaging_Protocol and at /documentation/rtmp .As mentioned, there are two data services implementations from Adobe and a few open source alter-natives. Following are the most popular ones:LifeCycle Data Services (Adobe): /products/livecycle/dataservices/BlazeDS (open source from Adobe): /wiki/display/blazeds/Granite Data Services (GDS):/WebORB for Java : /weborb/java/OpenAMF :/projects/openamf/OpenAMF is not a very active project at the time of writing. The last release dates back to 2006. This project’s mission was to port AMFPHP to Java. AMF was a closed specification back then, and AMFPHP was a reverse-engineered open source option for PHP servers. OpenAMF is closer to Flash remoting than data services.This chapter sticks mostly to LCDS and BlazeDS, but the same concepts apply to the alternatives. LCDS and BlazeDS are quite similar in form and structure and share the same codebase. BlazeDS can be thought of as a marginally scaled-down version of LCDS.258CHAPTER 7Figure 7-1. Data services architecture: an overviewData services uses AMF3 (Action Message Format version 3) to transmit binary data between Flex and Java. The genesis of this product lies in the Flash remoting server, which used to support AMF0 as the binary protocol. Flash remoting still exists, in many forms, but data services replaces it as a better alternative.Whichever data service we choose, it is a web application from a Java server perspective. Let’s dig a bit deeper to see what this means. (Of course, we are talking only about data services for Java. There are remoting servers for other technologies,but that is beyond the scope of this book.)259INTEGRATING VIA DATA AND MEDIA SERVICESIt’s a web applicationWeb applications are applications built on the technology that powers the Web. The HTTP protocol and the associated programming paradigm are a prominent part of this technology set. In Java, the raw low-level HTTP and related infrastructure is abstracted out as a higher-level API and managed components. At the heart of this abstraction is the Servlet specification, which wraps HTTP methods and HTTP protocol handling in objects. Web applications written in Java are packaged with all assets,associated libraries, class files, and any other resources into a special archive file format: a web appli-cation archive (WAR). These WAR files are deployed on a servlet container or an application server (which contains a servlet container).Most data servi ces, especi ally LCDS and BlazeDS, are web appli cati ons and exi st as WAR fi les. The remoting gateway is a servlet, and data service elements are web components. A little later, in the sec-tion “Downloading and deploying the web application,” you will see how deploying LCDS or BlazeDS is identical to deploying any other web application distributed in a WAR file format.In both BlazeDS and LCDS, the primary communication responsibilities are handled by a message bro-ker, which is created on startup by a servlet called the MessageBrokerServlet . The application server’s standard class loader loads it like any other servlet. This message broker is extremely flexible, and all types of available services and endpoints can be configured for it fairly easily. All such configurations reside in an XML configuration file, which I talk about later in the section “Configuring data services.”Protocols, channels, destinations, and endpointsOne of the primary advantages of data services is their use of AMF to transmit data between Flex and Java. AMF is a binary protocol, and the Flash Player natively supports it. Therefore, transmission using AMF is fast and efficient. AMF is a high-level (application layer) protocol that uses HTTP for commu-nication. Almost all data services dialog happens over HTTP or its secure alternative, HTTPS. AMF spec-i f i cat i on i s now ava i lable under the open source l i cense and i s access ible for download at /pub/labs/amf/amf3_spec_121207.pdf . When remot ng, AMF s marshaled and unmarshaled at both ends (Java and Flex) for the data interchange to work.The data services messaging module and media server use RTMP. LCDS and FMS support RTMP, but BlazeDS does not. BlazeDS uses HTTP tunneling and AMF long pooling to achieve a push-based model.Red5 (/red5), an open source alternative to Flash Media Server, partially reverse-engineers RTMP and provides streaming capabilities over this derived protocol.Apart from AMF over HTTP and RTMP, the Flash Player also supports Transmission Control Protocol (TCP) over Sockets. TCP is a protocol from the Internet protocol suite that facilitates reliable ordered delivery of byte streams. Secure versions of the protocol, such as AMF and HTTP over Secure Sockets Layer (SSL) and RTMP over Transport Layer Security (TLS), can be used as well. Both SSL and TLS are cryptographic protocols that facilitate secure communication over the Internet. TLS is a newer gener-ation protocol compared to SSL. Although similar, SSL and TLS are not interchangeable. TLS 1.0 is a standard that emerged after SSL 3.0. These protocols nvolve endpo nt authent cat on, message ntegri ty, and key-based encrypti on. Both protocols support a bunch of cryptographi c algori thms including RSA. RSA is a popular cryptographic algorithm for public key cryptography, which involves two different keys, one to encrypt a message and another to decrypt it.260CHAPTER 7INTEGRATING VIA DATA AND MEDIA SERVICES The Flash Player does not support the entire repertoire of protocols and even misses the ubiquitousUser Datagram Protocol (UDP), whi ch i s very useful for multi casti ng.Multicasting i s a method ofi nformati on deli very to multi ple desti nati ons si multaneously whereby messages are deli vered overeach link of the network only once. Copies of the message are created only if the links to the destina-tions bifurcate.You will not be able to take advantage of protocols like UDP with data services.Protocols help make effecti ve and effi ci ent communi cati on possi ble, but hi gher-level abstracti onsincrease the usability of these protocols. These higher-level abstractions help you focus on businesslogi c and reduce the burden of deali ng wi th low-level communi cati on handli ng. One such usefulhigher-level construct in Flex is called destination.Destinations are one of the key abstractions available in the Flex framework and data services. Server-side entities are mapped to logical names and configured to be invoked using these logical names.These confi gured server-si de elements, or desti nati ons, have a handle (logi cal name) and exposeserver-side functionality to remote clients. Many Flex client components, especially those that facili-tate remoting—for example RemoteObject—map to a destination. The section “Configuring data serv-ices,” which comes a little later, illustrates the configuration files. In that section, you will learn how todefine, configure, and use a destination. Then, in the section “Extending data services for advancedremoti ng use cases,” you wi ll see how to use custom extensi ons as desti nati ons. In data servi ces,almost all server-side elements that facilitate remoting and messaging are configured as destinations.HTTPService and WebService, when routed through a data service proxy, also map to a destination.When you i nteract wi th a server-si de servi ce vi a a desti nati on, you use a messagi ng channel to communicate back and forth.A messaging channel is a bundle that defines a protocol and an end-point set. An endpoint set means a URI, a listening port number, and an endpoint type definition. Forexample, an AMF channel could be established with the help of the AMF channel implementationclass (mx.messaging.channels.AMFChannel) and an endpoint definition, which could be a combina-tion of an endpoint type (flex.messaging.endpoints.AmfEndpoint) and its availability via a URI (say/sampleapp/messagebroker/amf) over a certain listening port (which by default for AMF is 8100).Sometimes, services need special adapters to communicate with server-side elements. These adaptersmay translate the message and act as the classical conduit that helps different programming interfacescommunicate and interact with each other. (An adapter by definition is something that modifies anAPI to make i t adapt to the requi red i ntegrati on scenari o.) Data servi ces defi ne a set of bui lt-i nadapters and provide an API to create your own.That is enough theory; time now to roll our sleeves up and see data services in action. We first installdata services and then quickly create a small example application to see how it works.Installing a data serviceThe last section claimed data services to be a Java web application. You will see that claim reinforcedby deploying a data service like any other Java web application in a Java application server (with aservlet container). Once we have deployed it successfully, we will go ahead and configure it so that weare ready to build an example application.261Downloading and deploying the web application For the purposes of illustration, we will pick BlazeDS as the data service and choose JBoss Application Server (AS) as the Java application server. If the data service is LCDS and the application server is any other, such as Apache Tomcat, BEA WebLogic, IBM WebSphere, Apache Geronimo, Caucho Resin, or GlassFish, the situation is not very different. Each of these application servers has its own directory struc-ture and styles of deployment. Deploying BlazeDS or LCDS involves the same level of complexity as deploying any other Java web application packaged as a WAR. Adobe Labs has published some notes on the specific installation instructions for a few of the popular application servers. These notes are online at /wiki/index.php/BlazeDS:Release_Notes#Installing_BlazeDS .The first step is to get all the required software and to install it.Getting the software and installing it BlazeDS is available under the open source GNU LGPL license.Go to /wiki/display/blazeds/BlazeDS and download the latest stable release build. You will have a choice to download the binary or the source versions. The binary version is what you should choose unless you intend to make modifications to the code. The distribution is available as a ZIP file. When you unzip the archive file, you will find a file called blazeds.war . This is the WAR file that has everything in it needed to use BlazeDS. In addition, you may find the following files:blazeds-samples.war : A set of sample applications blazeds-console.war : Monitoring application for BlazeDS deployments If this is the first time you are deploying BlazeDS, it’s recommended you deploy blazeds-samples.war and verify that the sample applications run without a problem.The other piece of the puzzle is the Java application server. I will assume that you have downloaded and installed one for your use. In this example, we download the latest stable release of JBoss AS from the communi ty download page accessi ble at /projects/download/. At the time of writing, version 4.2.2.GA is the latest stable release. This may differ depending on when you download it. The JBoss AS download is an archive file that is ready to use as soon as it’s expanded in the file system. (It may at most require a few environment variable settings.) On the PC, we just unzip it within a directory on the main partition.The JBoss AS dshown in Figure 7-2.BlazeDS runs w i th any Java appl i cat i support these JDK versions.Deploying the WAR file application in JBoss versing down the server ➤default ➤folders and copy ng the WAR f the bin appli cati on. In our case, JBoss i 262CHAPTER 7INTEGRATING VIA DATA AND MEDIA SERVICES port 8080 for HTTP requests, and so the URL for samples looks like this: http://localhost:8080/ blazeds-samples/. If you are able to access the samples application, you are ready to move to thenext step of configuring data service.With LCDS, the deployment is no different. The WAR file in LCDS has a different name—flex.war as opposed to blazeds.war—and it has a few extra features compared to BlazeDS, but from a deploy-ment standpoint things don’t change.GDS, the open source alternative to LCDS, has a slightly different approach to software distribution. GDSis distributed as multiple bundles, each integrating with one Java server-side technology. Also, GDS is dis-tributed as source and not binary, which means you need to set up the development environment tobuild the software. If you are a Java developer who also writes Flex applications, you may already havethe development environment set up. The required pieces of software areEclipse 3.2+ (with JDK 5+)Flex 3 SDK (If you use Flex Builder, you already have it.)Flex 3 Ant tasks (/wiki/index.php/Flex_Ant_Tasks)Once the environment is set up, you could get hold of one of these bundles:graniteds-ejb3-1.0.0.zip: Hooks to EJBgraniteds-seam-1.0.0.zip: Integrates with Seam (stateful web beans)graniteds-spring-ejb3-1.0.0.zip: Provides Spring servicesgraniteds-guice-1.0.0.zip: Provides services for Google Guicegranite-pojo-1.0.0.zip: Interfaces with plain Javagranite-chat-1.0.0.zip: Includes Java New I/O (NIO) and Comet-based data pushThe choice of bundle depends on your requirements. Also, the bundle version numbers could vary depending on when you download the files. As of now, the release version is 1.0.0. Each of these bun-dles i s an Ecli pse project. Once you get the bundle you need, unzi p i t and i mport i t i nto Ecli pse. Subsequently, you build it using Ant tasks.Configuring data servicesIn BlazeDS and LCDS, there is more to configure than code. In both these cases, a message broker servlet is the central manager of all communication and service invocations. Configuring data servicesis equivalent to configuring this message broker. In the web.xml file where you set up this servlet, you define the configuration file it should read. The portion of web.xml where you define this is as follows: <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>263You may not i ce that the value for the services.configuration.file is /WEB-INF/flex/services-config.xml . This is the default configuration, and most often there is no need to change it.However, if you need the configuration file to be at a different location or have a different name, you know where to make the modifications so that the new values are picked up.All servi ce and endpoi nt confi gurati ons are speci fi ed i n thi s confi gurati on fi le, whi ch by default i s called services-config.xml . From a functi onal standpoi nt, a data servi ce tri es to accompli sh the following:Facilitate remote procedure calls to Java objects on the server and transmit data between AS3and Java classes.Provide proxy services, especially for HTTPService and WebService , where security restrictions (the lack of a cross-domain definition via crossdomain.xml ) disallow these services otherwise.Send/Receive messages between Flex and Java and between two different Flex clients.Manage data for the application. This topic is not discussed in this book at all. BlazeDS does not provide this off the shelf, but LCDS does.Therefore, Adobe partitions the configuration file into four different pieces, each corresponding to one of the functional responsibilities just listed. Each of these pieces resides in a separate file, and all are included in the original configuration file by reference. The default names for these four files, in the same order in which they correspond to the functional areas listed previously, are remoting-config.xml proxy-config.xml messaging-config.xml data-management-config.xml The portion of services-config.xml at /flex/WEB-INF from our BlazeDS installation, where three of these four files are included (BlazeDS does not have data management features), is as shown here:<?xml version="1.0" encoding="UTF-8"?><services-config><services><service-include file-path="remoting-config.xml" /><service-include file-path="proxy-config.xml" /><service-include file-path="messaging-config.xml" /></services>A few aspects like logging, security, and channel definitions are cross-cutting concerns and are used across services, so these are defined in services-config.xml itself. All other service configurations and definitions typically fall in one of the four files (or three if we are using BlazeDS) I spoke about.In this chapter, there is no intent to cover every single aspect of configuration. Only a few important ones are sampled and explained. For an exhaustive syntax-level account of each allowed configura-tion, it’s advisable to refer to the LiveDocs. For BlazeDS, you could refer specifically to a LiveDocs sec-t i on t i tled “About serv i ce conf i gurat i on f i les,” wh i ch can be found onl i ne at /blazeds/1/blazeds_devguide/help.html?content=services_config_2.html .Let’s survey a few configuration options to get a flavor of things.264CHAPTER 7INTEGRATING VIA DATA AND MEDIA SERVICES Common configuration Let’s start with logging. BlazeDS and LCDS use log4j for logging. Logging-related configurations reside in services-config.xml itself. The most important aspect of configura-tion is the logging level. The permissible values and their respective meanings are as follows: ALL: Logs every single message.DEBUG: Includes internal Flex activities. This is an appropriate level during development andtroubleshooting, and is an incremental expansion beyond INFO. Therefore, all errors, warningsand information messages are included.INFO: Logs additional information that may be pertinent to developers or administrators. Thislevel builds on top of the WARN level.WARN: Includes warnings as well as errors.ERROR: Logs only errors that cause service disruption.NONE: Logs nothing.If you are familiar with log4j logging levels, then you have seen this before.Next come channel definitions. In terms of importance, this rates above the logging-level definitions. Channels are the vital protocol and endpoint combination that make communication possible betweenthe Flex client and the server. In BlazeDS, the default AMF channel configurations look like this: <channels><channel-definition id="my-amf" class=➥"mx.messaging.channels.AMFChannel"><endpoint url="http://{}:{server.port}/➥{context.root}/messagebroker/amf"class="flex.messaging.endpoints.AMFEndpoint"/></channel-definition><channel-definition id="my-secure-amf"class="mx.messaging.channels.SecureAMFChannel"><endpoint url="https://{}:{server.port}/➥{context.root}/messagebroker/amfsecure"class="flex.messaging.endpoints.SecureAMFEndpoint"/><properties><add-no-cache-headers>false</add-no-cache-headers></properties></channel-definition><channel-definition id="my-polling-amf"class="mx.messaging.channels.AMFChannel"><endpoint url="http://{}:{server.port}/➥{context.root}/messagebroker/amfpolling"class="flex.messaging.endpoints.AMFEndpoint"/><properties><polling-enabled>true</polling-enabled><polling-interval-seconds>4</polling-interval-seconds></properties></channel-definition></channels>265Three di fferent AMF channels are defi ned usi ng the precedi ng confi gurati on. In each case, a fully qualified class name specifies the class that implements the channel. The channel is accessible via a configured endpoint. The endpoints include a set of tokens, namely , server.port , and context.root . When a SWF is loaded in a browser, as happens with all Flex applications, these tokens are replaced with the correct values, and the endpoints are configured properly. In AIR and even with RTMP channels (in RTMP, server.port needs a specific port number definition), these tokens are not resolved automatically, and so channels don’t work as expected, if configured using tokens.To test a channel, it may a good idea to try and access the endpoint URL with the browser and see whether you get a success message, such as 200 OK , or not. Where required, channels could accept additional properties. As an example, a polling AMF channel defines the polling interval using proper-ti es. An i nteresti ng fact i s that property setti ngs can create enti rely di fferent channels. AMF and polling AMF channels have the same class for implementing the channels, but they have different sets of properties and therefore different behavior.Using services-config.xml , the channel configurations are done at compile time. It’s also possible to configure channels and associate them with destinations at run time. More information about config-uration at run time is covered in the section “Configuring at run time” later in this chapter.The third important common configuration pertains to security. Exhaustive and complex security defini-tions are possible with data services, but we will go with the defaults for now. We shall deal with security configurations in data services in the section “Additional useful data services tips” later in this chapter.Although this chapter has not exhaustively covered the configuration options, you know the basics of configuration by now. You will learn more about configuration as you explore the other topics that relate to data services.Our new focus is to get data services into action. The three configuration files, remoting-config.xml ,proxy-config.xml , and messaging-config.xml , configure services, so we will look at these in the next few sections as we implement such services using BlazeDS or LCDS.Calling remote methods and serializing objectsYou know AMF is an efficient binary protocol and a data service lets you exchange data between Flex and Java. Let’s dig deeper so you can see what you need to do to leverage this mechanism in your Flex appli cati on. Because “seei ng i s beli evi ng” and, li ke pi ctures, worki ng code speaks louder than words, we will first create a simple example application that will establish RPC over AMF using a data service. In this example, our data service is BlazeDS.A simple example in actionThe example application is fairly simple.It displays a list of people and the country they come from. A person is identified by an ID, first name, and last name. A country is identified by a name. The initial list is populated from an XML data file that has four names in it. A user is allowed to add names to the list and delete existing ones.To demonstrate data services and remoting, the list and the methods to manipulate the list are kept on the server. These remote Java objects and their methods are accessed from a Flex client.We create this example using Flex Builder 3, but we could also do without it and compile directly using mxmlc , the command-l i ne comp i ler, or use Flex Ant tasks, ava i lable from w i th i n Ecl ipse. The 266command-line compiler and the Flex Ant tasks are available free of charge. The command-line com-piler comes bundled with the free Flex 3 SDK. The Flex Ant tasks software bundle can be downloadedfrom /wiki/index.php/Flex_Ant_Tasks.As a first step, we create a new Flex project, choose Web application as the application type and J2EEas the server technology. We name this project VerySimpleRemotingExample. Figure 7-3 shows these settings in the New Flex Project dialog.Figure 7-3. The initial screen for new Flex project creation in Flex Builder 3You will see that Flex Builder offers only two choices for a data service, namely LifeCycle Data Servicesand ColdFusion Flash Remoting. At first, this often causes confusion among developers, when using BlazeDS. Choose LifeCycle Data Services as the option in the current dialog box when using BlazeDS. Inthe next dialog box, you will have an opportunity to point to either the BlazeDS WAR or the BlazeDS directories, deployed on your application server.In the very first screen, a choice is offered to create a combined Java/Flex project using WTP. WTP,which stands for Web Tools Platform, is the set of tools available within Eclipse to create Java web applications. The WTP project is hosted at /webtools/. You can go to the project page to get more information on WTP.The “data services” software available for the Flex framework consists of web applications that run ina web container. Any custom logic you write with the data services either will be part of a web appli-cation or will be accessed from a web application. Therefore, if you are starting from scratch, choos-ing to create a joint project is often useful. If your Java-side application already exists, as in the case of267。
myflex
FLEX与C#、PHP、JAVA语言通信全面解析以下介绍几种最为常见和实用的FLEX与现有开发语言通信的方法:1.C#2.PHP3.JAVA1.Flex与C#通信(.net开发中常用)Flex端代码:public static function SendMessage(objXML:XML,objResultHandle:Function):void {var objHttpService:HTTPService = new HTTPService();objHttpService.url = "http://localhost:8085/upfiledata.aspx"; //发送到的C#页面objHttpService.resultFormat = "e4x";objHttpService.addEventListener(ResultEvent.RESULT,objResultHandle);objHttpService.method = "POST";objHttpService.contentType = "application/xml";objHttpService.send(objXML); //objXML 要发送的数据}public function objResultHandle(evt:ResultEvent):void{evt //接收到的数据}C#端:protected void Page_Load(object sender, EventArgs e){XmlDocument objProtocolDom = new XmlDocument();objProtocolDom.Load(Request.InputStream); //objProtocolDom接收来自Flex端所发送的数据流Response.ContentType = "text/xml";Response.Write(objResultDom.OuterXml); //向Flex端下发数据流}2.Flex与php通信Flex代码:<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="/2006/mxml"creationComplete="onInit()" xmlns="*" layout="absolute"backgroundGradientColors="[#ffffff, #c0c0c0]"><mx:Script><![CDATA[public function onInit():void{userRequest.send();}]]></mx:Script><mx:HTTPService id="userRequest" url="request.php" useProxy="false"method="POST"><mx:request xmlns=""><username>{username.text}</username><emailaddress>{emailaddress.text}</emailaddr ess></mx:request></mx:HTTPService><mx:Form x="22" y="10" width="356"><mx:HBox><mx:Label text="Username"/><mx:T extInput id="username"/></mx:HBox><mx:HBox><mx:Label text="Email Address"/><mx:T extInput id="emailaddress"/></mx:HBox><mx:Button label="Submit" click="userRequest.send()"/></mx:Form><mx:DataGrid id="dgUserRequest" x="22" y="128"dataProvider="{er}"><mx:columns><mx:DataGridColumn headerText="User ID" dataField="userid"/><mx:DataGridColumn headerText="User Name" dataField="username"/> </mx:columns></mx:DataGrid><mx:T extInput x="22" y="292" id="selectedemailaddress"text="{dgUserRequest.selectedItem.emailaddress}"/></mx:Application>php代码:<?php/* Thanks to Pete Mackie for the code below */Define(’DATABASE_SERVER’, ’localhost’);Define(’DATABASE_USERNAME’, ’root’);Define(’DATABASE_PASSWORD’, ’root’);Define(’DATABASE_NAME’, ’flextest’);# Connect to the database$mysqli = new mysqli(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME);# Check connectionif (mysqli_connect_errno()) {printf("MySQL connect failed: %s\n", mysqli_connect_error());exit();}# Quote variable to make safefunction quote_smart($value) {global $mysqli;# Stripslashesif (get_magic_quotes_gpc())$value = stripslashes($value);# Quote if not integerif (!is_numeric($value))$value = $mysqli->real_escape_string($value);return $value;}if (!empty($_POST) && $_SERVER[’REQUEST_METHOD’] == ’POST’) { if ($_POST[’emailaddress’] && $_POST[’username’]) {# Add the user$query = sprintf("Insert INTO users VALUES (’’, ’%s’, ’%s’)",quote_smart($_POST[’username’]), quote_smart($_POST[’emailaddress’]));if (!@$mysqli->query($query)) {printf("’flextest’ user database query insert error: %s\n", $mysqli->error);$mysqli->close();exit();}}}# Return a list of all the usersif (!$result=@$mysqli->query("Select * from users")) {printf("’flextest’ user database query select error: %s\n", $mysqli->error);$mysqli->close();exit();}$xml_return = "<users>";while ($user = mysqli_fetch_array($result, MYSQLI_ASSOC)) {$xml_return .="<user><userid>".$user[’userid’]."</userid><username>".$user[’username’]."</usernam e><emailaddress>".$user[’emailaddress’]."</emailaddress></user>\n";}$xml_return.= "</users>";$mysqli->close();echo $xml_return;?>3.FLEX与JAVA之间的通信这里介绍一种方法:使用BlazeDS实现Java和Flex通信BlazeDS 是一个基于服务器的Java 远程控制(remoting) 和Web 消息传递(messaging) 技术,它能够使得后端的Java 应用程序和运行在浏览器上的Adobe Flex 应用程序相互通信。
FLEX简明教程
FLEX简明教程因为大家对JA V A都很熟悉,所以这个文档就是从FLEX和JA V A的一些比较来进行讲解,FLEX的核心语言是ActionScript,而FLEX3用到的相应是ActionScript3,所以这里学习FLEX其实就学习ActionScript,因为我也是新手,有说得不正确的地方还希望大家指出来更正。
1、基本数据类型和JA V A的区别ActionScript3的常用基本类型大致有以下几个:int ,uint,Number,Boolean,String,这几个基本类型中,值得注意的是Number类型,它是ActionScript3中浮点型的数据,相当于JA V A的Long和Float的集合。
2、类和包的声明,导入包。
ActionScript3的类声明和导入包和JA V A是一样的,包声明和C#类似,用一对大括号把类包围在package里面,下面声明一个com.zhongrx包下的一个Test类package com.zhongrx{import flash.text.TextFieldType;public class Test{}}3、修饰符ActionScript3可用作类、属性、方法的常用修饰符有:public ,private,protected, internal,其中public ,private的作用范围和JA V A是一样的,而internal则和JA V A的default一样(同一包中可访问),在没有指明修饰符时默认是internal,值得注意的是protected,它的作用范围比JA V A要小,JA V A中protected可以被其及其子类和同一包中的对象访问,而ActionScript3的protected却只能被其及其子类访问,外部不能访问。
4、变量和函数声明的区别ActionScript3中,函数和变量和JA V ASCRIPT类似,变量声明格式如下:修饰符var 变量名: 变量类型,比如我声明一个类型为字符串的私有的变量name,其结果如下:private var name:String;函数的声明格式如下:修饰符function 函数名():返回值类型{ },比如声明一个没有返回值,名为test 的公有函数,其结果如下:public function test():void{}值得注意的是无论是ActionScript3的属性和函数都可以声明为无类型,可以把上面的属性和函数声明修改成如下:private var name:*;public function test():*{}*号代表无类型,意思是其类型声明的属性或者是方法的返回值可以在运行的过程中随意转换成其它类型。
j2ee项目整合flex
应一个朋友请求,给他写一个J2EE与FLEX的整合DEMO,前些生活工程紧,没来得及,现在有点时刻,呵呵,耽搁了这么久,先对这位朋友讲个对不起啦!写了这么多,因此我顺便贴我的空间里吧,校内日志我也摘抄了一份!我用的环境是MyEclipse6.0+JDK5.0+Tomcat5.5+Flex3.0BuilderForEclipsePlugin+LCDS MyEclipse6.0的安装,不讲了JDK5.0的安装,不讲了LCDS能够到下载地址〔官方〕:要注册Adobe账号,只是是免费使用的FlexBuilder3下载往网上寻一个FB3_WWEJ_Plugin().exe,安装完成后,在你的MyEclipse中Help->SoftwareUpdates->ManageConfiguration->AddanExtensionLocation指向你FB3_WWEJ_Plugin().exe的安装路径就能够了!或在你的Eclipse的安装名目下,有个links文件夹,在里面新建一个文件,里面写着X:/ProgramFiles/Adobe/FlexBuilder3Plug-in,“X〞表示你安装FlexBuilder3Plug-in的盘符!1.首先创立一个Web工程,如如下面图:2.然后把那个工程部署到Tomcat效劳器上的,我用的是Tomcat5.5.。
3.接下来,假如你已把LCDS安装好了的话,那么你就到LCDS文件夹下面把lcds下的WEB-INF里的lib,flex两个文件夹考到你的FlexDemo工程里的WEB-INF下。
4.接下来确实是基本向现有的工程中添加FLEX特性了。
回到你的MyEclipse中在你的工程上右击->FlexProjectNature->addFlexProjectNature,如如下面图:点Next注重了!!!!!那个地方的Rootfolder要指向你Tomcat下的Webapps里的工程下面,RootURL是你用来调试用的,localhost后面的FlexDemo名子要和上面Rootfolder里的FlexDemo要相同,Contextroot那个地方也是的,outputfolder那个地方要指向你MyEclipse工程里的WebRoot下面,如此就好了,如如下面图:那个地方点一下ValidateConfiguration进行校验一下,就能够了!!然后点Finish完成!接下来确实是基本配置环境了,关于初学者来讲,这非常烦恼也非常乱,只是不要紧,你一点点理清了,也不是件难事!呵呵,俺确实是基本如此过来的!回到你的MyEclipse中在你的工程上右击->Properties会出现下面图形:点FlexBuildPath选项,在Sourcepath选项卡中,点AddFolder在弹出的对话框中写上flex_src。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于Flex三种通讯方式的Java配置与整合20XX年8月13日目录一、前言在项目开发过程中,很多时候需要给第三方提供一些接口来处理项目中的一下数据,然而在使用flex的AMF通信方式来配置我们的java web project的时候,我们就无法来处理这样的需求,所以这个时候我们可以合理的引入httpservice通讯方式和webservice通讯方式来弥补java服务端这一缺陷。
下面我们提一下flex三种通讯方式:(#)这里简单说明一下LCDS与blanzeds的区别。
BlazeDS可以看成是LCDS的一个子集,而且是一个开源产品,在一般的项目中完全可以替代LCDS。
(抱歉,adobe官方的图片找不到了,所以找了张有水印的)这份是adobe公司给的对比二、基础信息准备基础准备,在这里我们使用的IDE是myeclipse10.7.1(因为在使用jar包的时候使用的是myeclipse自带包)。
JDK使用的是1.6.0.45基本配置与框架使用web层:1)spring-flex 1.0.3(AMF)2)struts 2.3.15.1(httpservice)3)cxf 2.7.6(webservice)service层:1)spring 3.1 [使用myeclipse自带]DAO层:1)hibernate 3.3 [使用myeclipse自带]下载jar包1.spring-flex 1.0.3(AMF)这里我们使用的是1.0.3这个版本。
2.blazeds(AMF)adobe blazeds-bin-4.0.0.14931.zip登录,下载blazeds,最新版本为4.0.0.14931。
3.backport-util-concurrent 3.1(AMF)这个在下载时请注意版本,这里下载backport-util-concurrent-Java60-3.1.zip,这个为jdk1.6下的jar文件。
4.struts-2.3.15.1(httpservice)配置过SSH的程序员都知道,在eclipse中使用软件自带的struts时,在项目中展现的形式是这样的形式,而不能直接加入到WEB-INF/lib 文件夹下面。
5.cxf 2.7.6(webservice)这里使用cxf框架来对webservice中spring的整合。
三、具体配置方案与测试1.第一步我们先来配置SH(spring + hibernate)1)创建java web project2)增加spring支持点击Next > 按钮下一步Finish3)增加hibernate支持点击Next > 按钮下一步点击Next > 按钮下一步点击Next > 按钮下一步这里配置数据库连接信息,点击Next > 按钮进入下一个步骤Finish 完成hibernate的配置4)配置项目中的web.xml文件,使其支持spring、hibernate服务。
5)配置applicationContext.xml文件,增加spring事务管理功能配置spring通过service层来管理数据库事务。
其中,和由eclipse自动产生。
6)测试spring、hibernate配置是否成功a)在数据库中新建表Person,包含id(int自增)、name(varchar(16))和age(int)三字段。
b)增加hibernate annotation配置方式类Person.java注意:这里由于ID是自增类型所以需要增加@GeneratedValue(strategy = GenerationType.AUTO) 的注解c)建立DAO层java类PersonDAO.javad)建立service层java类Person.javae)配置spring,增加上面几个类的服务支持f)编写测试类报错误信息ng.NoClassDefFoundError: org/objectweb/asm/Type原因是缺少asm-3.3.jar包,可以从前面准备的struts-2.3.15.1中获取,并服务在项目的WEB-INF/lib文件夹下。
运行成功,控制台输出:1,name,10测试成功,spring、hibernate整合(包含数据)没有问题。
接下去,我增加flex与spring直接的通讯整合。
2.增flex-spring服务支持,是项目支持AMF通讯协议(FSH)1)解压blazeds-bin-4.0.0.14931.zip中blazeds.war文件2)复制./blazeds/WEB-INF/lib下的jar包到项目的WEB-INF/lib文件夹下3)复制./blazeds/WEB-INF/flex下的jar包到项目的WEB-INF文件夹下4)删除messaging-config.xml、proxy-config.xml、remoting-config.xml和version.properties文件5)修改services-config.xml文件删除<service />和< security />部分增加6)增加flex-spring jar包将backport-util-concurrent.jar和org.springframework.flex-1.0.3.RELEASE.jar复制到项目的WEN-INF/lib文件夹下。
7)配置web.xml使项目支持flex-spring8)配置spring文件使其支持flex remote修改beans头文件为增加flex支持7)测试AMF通讯配置方式是否正确a)java web项目中增加dest类。
PersonDest.javab)在spring中配置PersonDest为flex RemoteObject对接类c)建立flex测试applicationPerson.asfsh_fb.mxmld)测试结果运行结果界面数据库3.增struts服务支持,是项目支持http通讯协议(httpservice)1)解压下载的struts-2.3.15.1-all.zip文件。
2)解压struts-2.3.15.1/apps/ struts2-blank.war文件。
struts2-blank项目是struts2的一个基础配置项目,接下来我们可以使用这个项目来参考配置我们的struts框架。
3)复制struts2-blank/WEB-INF/lib中的jar文件到我们项目的WEB-INF/lib文件夹中。
4)复制struts2-blank/WEB-INF/classes中的struts.xml文件到我们的src文件目录下。
5)配置web.xml使其支持struts服务6)建立action类PersonAction.javapublic String save() {System.out.println("action save");try {setServlet();String name = request.getParameter("name");int age = Integer.parseInt(request.getParameter("age"));Person person = new Person();person.setName(name);person.setAge(age);personService.save(person);PrintWriter out = response.getWriter();out.print("<rtn>success</rtn>");} catch (Exception e) {e.printStackTrace();}return"success";}public List<Person> query() throws Exception {System.out.println("action query");List<Person> list = null;try {setServlet();list = personService.query();PrintWriter out = response.getWriter();out.print("<rtn>" + list.size() + "</rtn>");} catch (Exception e) {e.printStackTrace();}return list;}private void setServlet() {ActionContext ctx = ActionContext.getContext();request = (HttpServletRequest)ctx.get(ServletActionContext.HTTP_REQUEST);response = ServletActionContext.getResponse();response.setContentType("text/xml");}public PersonService getPersonService() {return personService;}7)配置对应的spring和struts文件springstruts运行项目报错误信息:缺少struts使用spring管理的jar包,从下载的struts2的lib文件夹中找到并添加struts2-spring-plugin-2.3.15.1.jar到项目中。
8)测试httpservice通讯编写flex application文件运行结果:点击按钮发送请求:配置成功。
4.增cxf服务支持,是项目支持sopa通讯协议(webservice)1)添加cxf项目核心jar包,重复的以高版本为准cxf-2.7.6.jar、wsdl4j-1.6.3.jar、neethi-3.0.2.jar和xmlschema-core-2.0.3.jar四个jar包2)修改web.xml支持cxf服务3)增加webservice服务类PersonWSI.javaPersonWS.java4)修改spring文件5)运行测试webservice是否发布成功输入地址:运行成功,配置完成。
至此,3种协议的服务配置结束。
四、总结到现在还是有些地方不太清楚,希望在项目中可以发现新问题、新思路,不断磨合这套系统使其更加符合实际需求。