推荐-基于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。
- 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种协议的服务配置结束。
四、总结到现在还是有些地方不太清楚,希望在项目中可以发现新问题、新思路,不断磨合这套系统使其更加符合实际需求。