关于整合,网上确实一大堆,但也有Flex高人说了很经典的一句,网上一大堆,错误两大堆,所以我特意将我的整合记录下来,分享给大家。
经常有人问s2sh整合flex,这里特意标题为java,意为纠正错误,因为有了flex,Struts2就是多余了,不要被现在的框架蒙骗得不知道怎么走出胡同,flex跟java通信,方式方法很多种,而且也很合理,我这里是采用的 S(pring 3.05)+H(ibernate ) + BlazeDS + Flex 4,简称 SH整合Flex,由Flex直接调用Service层,数据调用Flex用的RemoteObject方式,方式方法很多种,我喜欢这个,还有WebService。
整合有两种,一种是Flex 3用得比较多的,直接和现有的java 放在一起,我以前是这样;还有一种是,Java一个项目,Flex一个项目,Flex往JAVA项目里生成文件,我选择的是后者,主要是协作方便,JAVA和Flex开发。
很多东西是死的,用熟了,就好了。配置文件基本上是死的,照配就行了,如下:
官方(Adobe)下载BlazeDS(-turnkey-4.0.0.14931)后,文件包里有个blazeds.war文件,是JAVA的部署文件,把此文件解压,把flex文件夹拷贝到Java项目的web\WEB-INF下面,有些人的项目是webRoot/WEB-INF/,都一样。进去看一下,Flex下面共五个文件,
1) messaging-config.xml
2) proxy-config.xml
3) remoting-config.xml 重点,做项目经常会配置他
4) services-config.xml
5) version.properties忽略不计,可以删除
先不管他,一会再回来找他们。
<!-- flex --> <!-- Http Flex Session attribute and binding listener support --> <listener> <listener-class>flex.messaging.HttpFlexSession</listener-class> </listener>
<!-- MessageBroker Servlet --> <servlet> <servlet-name>MessageBrokerServlet</servlet-name> <display-name>MessageBrokerServlet</display-name> <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class> <init-param> <param-name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> |
commons-httpclient-3.0.1.jar
commons-logging.jar
flex-messaging-common.jar
flex-messaging-core.jar
flex-messaging-opt.jar
flex-messaging-proxy.jar
flex-messaging-remoting.jar
我是从blazeds.war解压的目录下WEB-INF\lib拿的,前两个,项目一般都已经有了。看情况处理吧!
1 . commons-logging.properties
我是从blazeds.war解压的目录下WEB-INF\classes拿的,源码如下:
# suppress logging for 3rd-party libraries using commons-logging # Flex logging is not configured here. It is configured through in the logging section of flex-config.xml org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl org.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog
|
2. log4j.properties
#log4j.rootLogger=DEBUG,stdout,file log4j.rootLogger=INFO,stdout,file log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n #[start]%d{yyyy/MM/dd/ HH:mm:ss}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=/logs/oscache.log log4j.appender.file.MaxFileSize=100KB log4j.appender.file.MaxBackupIndex=5 log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n #[start]%d{yyyy/MM/dd/ HH:mm:ss}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
log4j.logger.org.apache.commons=ERROR log4j.logger.com.opensymphony.oscache.base=INFO |
先前放着的四个配置文件现在开始动了,打开flex/services-config.xml
丢上这么一段:
<factories> <factory id="flexFactory" class="com.gwtjs.flex.FlexFactoryImpl" /> </factories> |
class="com.gwtjs.flex.FlexFactoryImpl" 这是自己写的,马上就来了
package com.gwtjs.flex;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import flex.messaging.FactoryInstance; import flex.messaging.FlexFactory; import flex.messaging.config.ConfigMap;
public class FlexFactoryImpl implements FlexFactory { private Log log = LogFactory.getLog(getClass());
public FactoryInstance createFactoryInstance(String id, ConfigMap properties) { log.info("Create FactoryInstance."); SpringFactoryInstance instance = new SpringFactoryInstance(this, id,properties); //获取 destination 的 ID instance.setSource(properties.getPropertyAsString(SOURCE,instance.getId())); return instance; }
public Object lookup(FactoryInstance instanceInfo) { log.info("Lookup service object."); return instanceInfo.lookup(); }
public void initialize(String id, ConfigMap configMap) { } }
|
package com.gwtjs.flex;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils;
import flex.messaging.FactoryInstance; import flex.messaging.FlexFactory; import flex.messaging.config.ConfigMap; import flex.messaging.services.ServiceException;
public class SpringFactoryInstance extends FactoryInstance {
private Log log = LogFactory.getLog(getClass());
public SpringFactoryInstance(FlexFactory factory, String id, ConfigMap properties) { super(factory, id, properties); }
public Object lookup(){ log.info("实例化 SpringFactoryInstance 并通过 SpringFactoryInstance 的 lookup() 方法查找 FlexService 接口对象"); ApplicationContext appContext = WebApplicationContextUtils .getWebApplicationContext(flex.messaging.FlexContext .getServletConfig().getServletContext());
String beanName = getSource();
try{ 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");
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");
throw e;
}
} } |
从这里开始,每次重复——》标上红色,记着吧。
写个Dao接口,并实现,自己写吧,我有现成的;写services接口和实现类,如下:
package com.gwtjs.flex.service;
import com.gwtjs.model.MemberFavorites; import com.gwtjs.model.utils.Pager;
public interface MemberFavoritesService {
public Pager<MemberFavorites> getFavorites(); } |
package com.gwtjs.flex.service.impl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import com.gwtjs.dao.MemberFavoritesDao; import com.gwtjs.flex.service.MemberFavoritesService; import com.gwtjs.model.MemberFavorites; import com.gwtjs.model.utils.Pager;
/** * * @author ZhengGuang Dong * <p> * 用的spring自动注入,没有用配置文件,注意这个名称:memberFavoritesService,在flex配置文件会见到它,dao也是自动注入的, * 方法 getFavorites返回的是自己封装的一个对象,里面有记录总数和list记录集,并使用了泛型,这里你可以改成自己的,只是在测试的时候对应上就可以了。 * </p> */ @Service("memberFavoritesService") //① public class MemberFavoritesServiceImpl implements MemberFavoritesService {
@Autowired private MemberFavoritesDao memberFavoritesDao;
@Override public Pager<MemberFavorites> getFavorites() { Pager<MemberFavorites> p = memberFavoritesDao.findAll(MemberFavorites.class, 0, 22, "id",false); System.out.println(p.getTotalCounts()+" : "+p); return memberFavoritesDao.findAll(MemberFavorites.class, 0, 22, "id",false); }
}
|
贴上service层是为了让大家看清Java和Flex的联系,返回什么类型,什么对象,不重要,搞清他们的联系,自己搞吧!你搞你的。
定义flex的调用接口,打开WEB-INF/flex/remoting-config.xml
<destination id="memberFavoritesService"> <!--③flex调用的就是这个id--> <properties> <!-- flexFactory对应services-config.xml对应工厂 ② --> <factory>flexFactory</factory> <!--source对应service层的接口定义 ① --> <source>memberFavoritesService</source> <!--作用域啥 --> <scope>application</scope> </properties> </destination> |
Java项目就算完了,接着就是flex项目了
1 . 先把Java项目的服务启动,我用的是tomcat7 ,支持web 3.0
建flex项目,第一项,《项目位置》基本上没什么,就输入了项目的名称,其它没什么,next到《服务器设置》时,要注意的注意地方就来了,服务器技术勾选上使用远程对象访问服务(R),并选择BlazeDS(B),
l 上下文我的是根"/",你根据你的tomcat配置输入,
l 根文件夹我的是绝对路径,直接指向了先前的JAVA项目的web/目录下面,
l 根URL是服务器的URL,我的是http://localhost:8282
如图:
填完了,验证一下,点一下验证按钮,看看结果如何!
注意本页下面的选项“输出文件夹”:,就是Flex和Java分开开发二者的重点
我是指定的绝对路径,直接指到JAVA项目的web下面的member,因为我的这个项目是准备用flex开发vip模块,你根据你的需要设定。搞完了,就下一步吧。其它的没什么
<?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" creationComplete="init()" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent;
[Bindable] private var array:ArrayCollection = new ArrayCollection(); [Bindable] private var total:int = 0; public function favoritesServiceResult(event:ResultEvent):void{ total = event.result.totalCounts; array = event.result.entityList; trace("请求成功:\n请求数: "+total,array); } public function favoritesServiceFaultResult(event:FaultEvent):void{ trace(event.message); } //装载页面时执行的方法, public function init():void{ favoritesRemote.getFavorites(); } ]]> </fx:Script> <fx:Declarations> <!-- 对应WEB-INF/flex/remoting-config.xml 标注的③ --> <s:RemoteObject id="favoritesRemote" destination="memberFavoritesService" result="favoritesServiceResult(event)" fault="favoritesServiceFaultResult(event)" showBusyCursor="true"> </s:RemoteObject> </fx:Declarations> <mx:AdvancedDataGrid id="adg1" x="355" y="185" designViewDataType="flat" dataProvider="{array}"> <mx:columns> <mx:AdvancedDataGridColumn dataField="module" headerText="模块名称"/> <mx:AdvancedDataGridColumn dataField="object" headerText="对象名称"/> <mx:AdvancedDataGridColumn dataField="addTime" headerText="收藏时间"/> <mx:AdvancedDataGridColumn dataField="imgUrl" headerText="图片" /> </mx:columns> </mx:AdvancedDataGrid>
</s:Application> |
结果如图:
结束,这里只谈整合,或许有时间再写点实例。