用到的相关组件
spring-flex-1.0.1.RELEASE.zip lib下所有包
blazeds_bin_3-0-0-544.zip lib下所有包
jackson-core-asl-1.0.1.jar
spring-flex-1.0.1.RELEASE.zip 依赖spring-core.jar 和 spring-webmvc.jar jackson-core-asl-1.0.1.jar
其它jar是google app 工程自带<!--StartFragment -->
首先web.xml
因为用到spring 所以把blazeds的默认设置改了。详细请看spring-flex-1.0.1.RELEASE.zip 中文档
<welcome-file-list>
<welcome-file>myblog.html</welcome-file>
</welcome-file-list>
<!-- 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>-->
<!-- <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>-->
<!-- for WebSphere deployment, please uncomment -->
<!--
<resource-ref>
<description>Flex Messaging WorkManager</description>
<res-ref-name>wm/MessagingWorkManager</res-ref-name>
<res-type>com.ibm.websphere.asynchbeans.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
-->
<servlet>
<servlet-name>SpringDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/web-application-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringDispatcherServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
web-application-config.xml 配置
<!--_messageBroker 这个名字是写死的。这都是官方文档的配置。我试着改名。里边某处好像用到这个服务名会报错。具体情况没去研究-->
<bean id="_messageBroker" class="org.springframework.flex.core.MessageBrokerFactoryBean" >
<!-- <property name="servicesConfigPath" value="classpath*:services-config.xml" />-->
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>/*=_messageBroker</value>
</property>
</bean>
<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter"/>
<!-- 方法一-->
<!-- <bean id="user" class="org.springframework.flex.remoting.FlexRemotingServiceExporter">-->
<!-- <property name="messageBroker" ref="mySpringManagedMessageBroker"/>-->
<!-- <property name="service" ref="userService"/>-->
<!-- </bean>-->
<!-- 方法二-->
<!-- <bean id="userService" class="com.UserServiceImpl">-->
<!-- <flex:remoting-destination /> -->
<!-- </bean>-->
<!-- 方法三-->
<bean id="userService" class="com.UserServiceImpl"/>
<flex:remoting-destination ref = "userService"/>
<!--方法一二三是指三指将服务暴露方式 原始的是在remote-config.xml中配置 spring-flex提供三种方式不需要改remote-config.xml-->
</beans>
请注意。整合的过程中感到几个莫名的问题
2009-12-13 17:03:03 com.google.appengine.tools.development.LocalResourceFileServlet doGet
WARNING: No file found for: /favicon.ico
2009-12-13 17:03:04 com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: Nested in org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.RuntimeException: Session support is not enabled in appengine-web.xml. To enable sessions, put <sessions-enabled>true</sessions-enabled> in that file. Without it, getSession() is allowed, but manipulation of sessionattributes is not.:
java.lang.RuntimeException: Session support is not enabled in appengine-web.xml. To enable sessions, put <sessions-enabled>true</sessions-enabled> in that file. Without it, getSession() is allowed, but manipulation of sessionattributes is not.
at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.throwException(StubSessionManager.java:67)
at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.setAttribute(StubSessionManager.java:63)
根据异常信息
在appengine-web.xml 配置中加上<sessions-enabled>true</sessions-enabled> 解决
org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_messageBroker' defined in ServletContext resource [/WEB-INF/config/web-application-config.xml]: Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanInitializationException: MessageBroker initialization failed; nested exception is java.lang.NoClassDefFoundError: java.lang.management.ManagementFactory is a restricted class. Please see the Google App Engine developer's guide for more details.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
nested exception is java.lang.NoClassDefFoundError: java.lang.management.ManagementFactory is a restricted class 此类好像是在google java 白名单之外 有网在找到相应解决方案
services-config.xml <system>下加入<manageable>false</manageable>
<system>
<manageable>false</manageable>
<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>
问题3:在本地一直调试成功。部署到google app 报
Fault Code : Server.Processing.DuplicateSessionDetected.
Error Message : Detected duplicate HTTP-based FlexSessions, generally due to the remote host disabling session cookies. Session cookies must be enabled to manage the client connection correctly.
问题有点闷:在这外链接上找到了解决方案 But, my suggession if you are not really concern with BlazeDS version, roll back to BlazeDS 3.0.0.544 将blazeds换成3.0 之前一直用3.2 部署有问题
http://iamsri.wordpress.com/2009/11/09/flex-tip-server-processing-duplicatesessiondetected/
至此问题全部解决 flex-spring 本人e文不大好。看spring-flex 文档有吃力。
忘记贴上前台代码了:
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
private function getUserList():void
{
RemoteService.execute("userService", "getUserList", [], resultUserList);
}
[Bindable]
private var obj:Object = new Object();
private function resultUserList(event:ResultEvent):void
{
var userList:ArrayCollection=event.result as ArrayCollection;
obj = userList[0];
}
]]>
</mx:Script>
<mx:TextArea id="ggg" x="109" y="122" text="{obj.id}"/>
<mx:Button label="click" click="getUserList();" x="144" y="193"/>
RemoteService.as
package
{
import mx.controls.Alert;
import mx.messaging.Channel;
import mx.messaging.ChannelSet;
import mx.messaging.channels.AMFChannel;
import mx.rpc.AbstractOperation;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class RemoteService
{
public function RemoteService()
{
}
private static var result:Object;
public static function execute(serviceName:String,methodName:String,param:Array,resultHandler:Function=null,faultHandler:Function=null):void{
var remote:RemoteObject = new RemoteObject();
remote.destination = serviceName;
var channelSet:ChannelSet = new ChannelSet();
var chan:Channel = new AMFChannel(null,"/messagebroker/amf");
channelSet.addChannel(chan);
remote.channelSet = channelSet;
var operator:AbstractOperation = remote.getOperation(methodName);
var resultFun:Function = resultHandler == null?autoResultHandler:resultHandler;
var faultFun:Function = faultHandler == null?autoFaultHandler:faultHandler;
remote.addEventListener(FaultEvent.FAULT,faultFun);
remote.addEventListener(ResultEvent.RESULT,resultFun);
operator.arguments = param;
operator.send();
}
private static function autoResultHandler(event:ResultEvent):void{
result = event.result as Object;
}
private static function autoFaultHandler(event:FaultEvent):void{
Alert.show(event.message.toString());
}
}
}