将 Flex 集成到 Java EE java+Flex分离配置
? ? ?
? 如何将 Flex 集成至该 Java EE 应用呢?现在,我们希望用 Flex 替换掉原有的 Servlet 和 JSP 页面,就需要让 Flex 和 Java EE 后端通信。Flex 支持多种远程调用方式,包括 HTTP,Web Services 和 AMF。不过,针对 Java EE 开发的服务器端应用,可以通过集成 BlazeDS,充分利用 AMF 协议并能轻易与 Flex 前端交换数据
1.下载jar包 2.创建项目java_flex 首先我们要从网上下载相应的jar包blazeds-bin-4.0.1.21287.zip将jar包解压把lib里面的所有jar复制到项目的lib目录下, 然后修改web.xml文件在 web.xml 中添加 HttpFlexSession 和 Servlet 映射。HttpFlexSession 是 BlazeDS 提供的一个 Listener,负责监听 Flex 远程调用请求,并进行一些初始化设置: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>java_flex</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>flex.messaging.HttpFlexSession</listener-class> </listener> <servlet><!-配置flexservlet-> <servlet-name>messageBroker</servlet-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>messageBroker</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> </web-app> BlazeDS 所需的所有配置文件均放在 /WEB-INF/flex/ 目录下。BlazeDS 将读取 services-config.xml 配置文件,该配置文件又引用了 remoting-config.xml、proxy-config.xml 和 messaging-config.xml 这 3 个配置文件,所以,一共需要 4 个配置文件。 services-config.xml :
<?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> <security> <login-command class="flex.messaging.security.TomcatLoginCommand" server="Tomcat" /> <!-- Uncomment the correct app server <login-command class="flex.messaging.security.TomcatLoginCommand" server="JBoss"> <login-command class="flex.messaging.security.JRunLoginCommand" server="JRun"/> <login-command class="flex.messaging.security.WeblogicLoginCommand" server="Weblogic"/> <login-command class="flex.messaging.security.WebSphereLoginCommand" server="WebSphere"/> --> <!-- <security-constraint id="basic-read-access"> <auth-method>Basic</auth-method> <roles> <role>guests</role> <role>accountants</role> <role>employees</role> <role>managers</role> </roles> </security-constraint> --> </security> <channels> <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint" /> <properties> <polling-enabled>false</polling-enabled> </properties> </channel-definition> <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel"> <endpoint url="https://{server.name}:{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.name}:{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> <!-- <channel-definition id="my-http" class="mx.messaging.channels.HTTPChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/http" class="flex.messaging.endpoints.HTTPEndpoint"/> </channel-definition> <channel-definition id="my-secure-http" class="mx.messaging.channels.SecureHTTPChannel"> <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/httpsecure" class="flex.messaging.endpoints.SecureHTTPEndpoint"/> <properties> <add-no-cache-headers>false</add-no-cache-headers> </properties> </channel-definition> --> </channels> <logging> <target class="flex.messaging.log.ConsoleTarget" level="Error"> <properties> <prefix>[BlazeDS] </prefix> <includeDate>false</includeDate> <includeTime>false</includeTime> <includeLevel>false</includeLevel> <includeCategory>false</includeCategory> </properties> <filters> <pattern>Endpoint.*</pattern> <pattern>Service.*</pattern> <pattern>Configuration</pattern> </filters> </target> </logging> <system> <redeploy> <enabled>false</enabled> <!-- <watch-interval>20</watch-interval> <watch-file>{context.root}/WEB-INF/flex/services-config.xml</watch-file> <watch-file>{context.root}/WEB-INF/flex/proxy-config.xml</watch-file> <watch-file>{context.root}/WEB-INF/flex/remoting-config.xml</watch-file> <watch-file>{context.root}/WEB-INF/flex/messaging-config.xml</watch-file> <watch-file>{context.root}/WEB-INF/flex/data-management-config.xml</watch-file> <touch-file>{context.root}/WEB-INF/web.xml</touch-file> --> </redeploy> </system> </services-config> 由于 BlazeDS 需要将 Java 接口 FlexService 暴露给 Flex 前端,因此,我们在配置文件 remoting-config.xml 中将 FlexService 接口声明为一个服务:
<?xml version="1.0" encoding="UTF-8"?> <service id="remoting-service" class="flex.messaging.services.RemotingService"> <adapters> <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/> </adapters> <default-channels> <channel ref="my-amf"/> </default-channels> <destination id="test"> <properties> <source>org.demo.service.impl.FlexServiceImpl</source> <!-- 注意路径 --> <scope>application</scope> </properties> </destination> </service> proxy-config.xml :
<?xml version="1.0" encoding="UTF-8"?> <service id="proxy-service" class="flex.messaging.services.HTTPProxyService"> <properties> <connection-manager> <max-total-connections>100</max-total-connections> <default-max-connections-per-host>2</default-max-connections-per-host> </connection-manager> <allow-lax-ssl>true</allow-lax-ssl> </properties> <adapters> <adapter-definition id="http-proxy" class="flex.messaging.services.http.HTTPProxyAdapter" default="true"/> <adapter-definition id="soap-proxy" class="flex.messaging.services.http.SOAPProxyAdapter"/> </adapters> <default-channels> <channel ref="my-amf"/> </default-channels> <destination id="DefaultHTTP"> </destination> </service> messaging-config.xml:
<?xml version="1.0" encoding="UTF-8"?> <service id="message-service" class="flex.messaging.services.MessageService"> <adapters> <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" /> <!-- <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> --> </adapters> <default-channels> <channel ref="my-polling-amf"/> </default-channels> </service>接下来我们就是写java代码了(这里我没用框架)。 BaseDao
package org.demo.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.jsp.jstl.sql.ResultSupport; import org.apache.tomcat.dbcp.dbcp.BasicDataSource; public class BaseDao { private static BasicDataSource bds = new BasicDataSource(); static { bds.setDriverClassName("com.mysql.jdbc.Driver"); bds.setUrl("jdbc:mysql://localhost:3306/myweb"); bds.setUsername("root"); bds.setPassword("123456"); } public Connection getConnection(){ try { //Class.forName("oracle.jdbc.driver.OracleDriver"); //return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL","liu","liu"); return bds.getConnection(); } catch (Exception e) { e.printStackTrace(); } return null; } public void closeReSources(ResultSet rs,Statement st,Connection conn){ try { if(rs!=null)rs.close(); if(st!= null) st.close(); if(conn != null)conn.close(); } catch (SQLException e) { e.printStackTrace(); } } public int excuteUpdate(String sql,Object...params){ Connection conn = null; PreparedStatement pst = null; int rt = 0; try{ conn = getConnection(); pst = conn.prepareStatement(sql); if(params != null && params.length>0){ for (int i = 0; i < params.length; i++) { pst.setObject(i+1,params[i]); } } rt = pst.executeUpdate(); }catch(Exception e){ e.printStackTrace(); }finally{ closeReSources(null,pst,conn); } return rt; } public javax.servlet.jsp.jstl.sql.Result excuteQuery(String sql,Object...params){ Connection conn = null; PreparedStatement pst = null; ResultSet rs = null; javax.servlet.jsp.jstl.sql.Result r = null; try{ conn = getConnection(); pst = conn.prepareStatement(sql); if(params != null && params.length>0){ for (int i = 0; i < params.length; i++) { pst.setObject(i+1,params[i]); } } rs = pst.executeQuery(); //将ResultSet封装成Result r = ResultSupport.toResult(rs); }catch(Exception e){ e.printStackTrace(); }finally{ closeReSources(rs,conn); } return r; } }实体类FileInfo: package org.demo.po; import java.sql.Timestamp; public class FileInfo { private Integer id; private String name; private String realPath; private Timestamp date; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRealPath() { return realPath; } public void setRealPath(String realPath) { this.realPath = realPath; } public Timestamp getDate() { return date; } public void setDate(Timestamp date) { this.date = date; } }要暴露给flex的接口FlexService:
package org.demo.service; import java.util.List; import org.demo.po.FileInfo; public interface FlexService { public List<FileInfo> getData(int num); } FlexServiceI的实现类FlexServiceImpl:
package org.demo.service.impl; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.SortedMap; import javax.servlet.jsp.jstl.sql.Result; import org.demo.dao.BaseDao; import org.demo.po.FileInfo; import org.demo.service.FlexService; public class FlexServiceImpl extends BaseDao implements FlexService { @Override public List<FileInfo> getData(int num) { List<FileInfo> files = new ArrayList<FileInfo>(); try { Result r = super.excuteQuery("select * from tb_uploads limit "+num); if(r.getRowCount()!=0&&r!=null){ for(SortedMap row :r.getRows()){ FileInfo f = new FileInfo(); f.setId(Integer.valueOf(row.get("id").toString())); f.setName(row.get("name").toString()); f.setRealPath(row.get("realpath").toString()); f.setDate(Timestamp.valueOf(row.get("date").toString())); files.add(f); } } } catch (Exception e) { throw new RuntimeException(e); } return files; } }项目结构如下:
新建flex项目---第一步 新建flex项目---第二步 因此,需要填入 java_flex 项目的 web 根目录,该目录下必须要存在? flex项目结构如下: 为了能在 Flex 中实现远程调用,我们需要定义一个 RemoteObject 对象。可以通过 ActionScript 编码创建该对象,也可以直接在 MXML 中定义一个 RemoteObject 对象
<s:RemoteObject id="flexServiceRo" destination="test" result="resultHandler(event)" fault="faultHandler(event)"/> java_flex.mxml代码如下:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="init()"> <fx:Style source="java_flex.css"/> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.utils.ArrayUtil; [Bindable] private var arr:ArrayCollection; private function init():void { var num:int = 10; flexServiceRo.getData(num); } protected function getData_clickHandler(event:MouseEvent):void { } //获取数据 protected function flexService_resultHandler(event:ResultEvent):void { var obj:Object = new Object; arr = event.result as ArrayCollection; DataTable.dataProvider=arr; } protected function faultHandler(event:FaultEvent):void { Alert.show(event.fault.toString()); } ]]> </fx:Script> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> <s:RemoteObject id="flexServiceRo" destination="test" result="flexService_resultHandler(event)" fault="faultHandler(event)"/> </fx:Declarations> <s:Button id="getData" y="70" width="107" height="45" label="获取数据" click="getData_clickHandler(event)" horizontalCenter="-89"/> <s:DataGrid id="DataTable" width="876" height="417" horizontalCenter="-46" requestedRowCount="4" verticalCenter="-73"> <s:columns> <s:ArrayList> <s:GridColumn width="100" dataField="id" headerText="id"></s:GridColumn> <s:GridColumn width="100" dataField="name" headerText="name"></s:GridColumn> <s:GridColumn width="300" dataField="realPath" headerText="realPath"></s:GridColumn> <s:GridColumn width="100" dataField="date" headerText="date"></s:GridColumn> </s:ArrayList> </s:columns> <s:typicalItem> <fx:Object dataField1="示例数据" dataField2="示例数据" dataField3="示例数据"></fx:Object> </s:typicalItem> <s:ArrayList> </s:ArrayList> </s:DataGrid> </s:Application>弄好后运行效果如下图: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |