??xml version="1.0" encoding="utf-8" standalone="yes"?> UML是一U通用的徏模语aQ其表达能力相当的强Q不仅可以用于Y件系l的建模Q而且可用于业务徏模以及其它非软gpȝ建模。UMLl合了各U面向对象方法与表示法的优点Q至提出之日起就受到了广泛的重视q得C工业界的支持? 本章按视图、模型元素、图以及公共机制依次介绍UML的构造和基本元素Q以使得读者对UML有一个M了解Q其具体l节在后箋章节中详l描q?/p> d工具QeDraw、jude Ƣ迎大家l箋支持和关注我的博客: http://blog.csdn.net/IBM_hoojo 也欢q大家和我交、探讨IT斚w的知识?/p> emailQ?a href="mailto:hoojo_@126.com">hoojo_@126.com 如果你觉得本文不错的话,请你点击屏幕右下方的 1. UML的组?/font> UMLp?View)、图(Diagram)?a name="OLE_LINK13">模型元素(Model Element)?a name="OLE_LINK14">通用机制(General Mechanism){几个部分组成? a) 视图(View)Q?是表辄l的某一斚w的特征的UML建模元素的子集,由多个图构成Q是在某一个抽象层上,对系l的抽象表示? b) ?Diagram)Q?是模型元素集的图形表C,通常是由弧(关系Q和点Q其他模型元素)怺q接构成的? c) 模型元素(Model Element)Q代表面向对象中的类、对象、消息和关系{概念,是构成图的最基本的常用概c? d) 通用机制(General Mechanism)Q用于表C其他信息,比如注释、模型元素的语义{。另外,UMLq提供扩展机Ӟ使UML语言能够适应一个特D的ҎQ或q程Q,或扩充至一个组l或用户? 2. UML视图的分c?/font> UML是用来描q模型的Q用模型来描q系l的机构或静态特征,以及行ؓ或动态特征。从不同的视角ؓpȝ构架建模QŞ成系l的不同视图? (1) 用例视图(Use Case View)Q?/strong>从用L角度看到的或需要的pȝ功能Q是被称为参与者的外部用户所能观察到的系l功能的模型图? (2) 逻辑视图(Logical View)Q?/strong>展现pȝ的静态或l构l成及特征,也称为结构模型视?Structural Model View)或静态视?Static View)? (3) q发视图(Concurrent View)Q?/strong>体现了系l的动态或行ؓ特征Q也UCؓ行ؓ模型视图(Behavioral Model View)或动态视?Dynamic View)? (4) lg视图(Component View)Q?/strong>体现了系l实现的l构和行为特征,也称为实现模型视?Implementation Model View)? (5) 配置视图(Deployment View)Q?/strong>体现了系l实现环境的l构和行为特征,也称为环境模型视?Environment Model View)或物理视?Physical View)? 视图是由囄?/b>的,UML提供9U不同的图: (1) 用例?/a>(Use Case Diagram)Q描q系l功能; (2) cd(Class Diagram)Q描q系l的静态结构; (3) 对象?Object Diagram)Q描q系l在某个时刻的静态结构; (4) lg?Component Diagram)Q描qC实现pȝ的元素的l织Q? (5) 配置?Deployment Diagram)Q描qC环境元素的配|,q把实现pȝ的元素映到配置上; (6) 状态图(State Diagram)Q描qCpȝ元素的状态条件和响应Q? (7) 时序?Sequence Diagram)Q按旉序描述pȝ元素间的交互Q? (8) 协作?Collaboration Diagram)Q按照时间和I间序描述pȝ元素间的交互和它们之间的关系Q? (9) zd?Activity Diagram)Q描qCpȝ元素的活动; 建模Ҏ?b>建模语言和徏模过E?/b>两部分构成。其中徏模语a是用来表q设计方法的表示法,建模q程是对设计中所应采取的步骤的描q。UML是一U徏模语aQ它在很大程度上独立于徏模过E。在实际建模中,建模人员最好把UML用于以用案驱动的、以体系机构Z心的、P代的和渐增式的开发过E中? 一般而言QY件系l的体系l构l出了Y件系l的l织、组成系l的构造元素及其接口的选择、系l的行ؓ和体pȝ构风格等信息。也是_它不仅关心系l的l构和行为等功能性需求,而且也涉及系l的性能、易理解性、易复用性等非功能性需求。如下图所C,UML利用用户模型视图、结构模型视图、行为模型视图、实现模型视囑֒环境模型视图来描qY件系l的体系l构? Ҏ它们在不同架构视囄应用Q可以把9U图分成Q?/b> (1) 用户模型视图Q用例图Q?/a> (2) l构模型视图Q类囑֒对象Q? (3) 行ؓ模型视图Q状态图、时序图、协作图和活动图Q动态图Q; (4) 实现模型视图Q组件图Q? (5) 环境模型视图Q配|图? 用户模型视图׃门描q?b>最l用戗分析h员和试人员看到的系l行为的用案l成Q它实际上是从用戯?/b>来描q系l应该具有的功能。用h型视图所描述的系l功能依靠外部用h者另外一个系l来Ȁz,为用h者另一pȝ提供服务Q从而实现用h另一pȝ与系l的交互。系l实现的最l目标是提供用户模型视图中所描述的功能。在UML中,用户模型视图是由用案囄?/b>? l构模型视图描述l成pȝ?b>cR对象以及它们之间的关系{静态结构,用来支持pȝ的功能需求,xq系l内部功能是如何设计的。结构模型视囄cd和对象图构成Q?b>主要供设计h员和开发h员?/b>? 行ؓ模型?/b>图主要用来描qŞ?b>pȝq发与同步机制的U程和进E?/b>Q其x的重Ҏpȝ的性能、易伸羃性和pȝ的吞吐量{非功能性需求。行为模型视囑ֈ用ƈ发来描述资源的高效用、ƈ行执行和处理异步事g。除了讲pȝ划分为ƈ发执行的控制U程之外Q行为模型还必须处理通信和这些线E及q程之间的同步问题。行为模型视图主要供pȝ开发h员和pȝ集成人员使用Q它?b>序列图、协作图、状态图和活动图l成? 实现模型视图用来描述pȝ的实现模块它们之间的依赖关系以及资源分配情况。这U视图主要用于系l的配置理Q它是由一些独立的构gl成的。实现模型视囄构g囄?/b>。其中构件是代码模块Q不同类型的代码模块形成不同的构件。实现模型视图主要供开发h?/b>使用? 环境模型视图用来描述物理pȝ?b>g拓扑l构。例如,pȝ中的计算机和讑֤的分布情况以及它们之间的q接方式Q其中计机和设备统UCؓ节点。在UML中环境模型视图是由部|图来表C的。系l部|图描述了系l构件在节点上的分布情况Q即用来描述软g构g到物理节点的映射。部|图主要?b>开发h员、系l集成h员和试人员使用? 上面每一U视囑֏映了pȝ的一个特定方面,不同人员可以单独的用其中每一U视图,从而可以关注特定的体系l构问题。但在通常情况下,׃pȝ的最l目标是提供用户模型视图中描q的功能以及其它一些非功能性需求,因此Q用h型视图是其它视图的核心基Q其它视囄构造都依赖与用h型视图中所描述的类宏V? l心的读者已l发玎ͼ每一UUMLN是由多个囄成的Q每一U图都是体系l构某个侧面的表C,各种囑֮际上是一致的Q所有的囑֜一L成了pȝ的完整视图。如下图所C,UML中d提供了用案图、类图、对象图、序列图、协作图、状态图、活动图、构建图和部|图9U图。根据它们描q的是系l的静态结构还是动态行为,可以它们分为静态图和动态图两类。再q一步介l这9中UML图时Q先了解下什么是模型元素Q? 3. UML的徏模机?/b> UML有两套徏模机Ӟ静态徏模机制和动态徏模机制。静态徏模机制包括用例图、类图、对象图、包、组件图和配|图。动态徏模机制包括状态图、时序图、协作图、活动图? (1) 用例图:用例的可视化工具Q它提供计算机系l的高层ơ的用户视图Q表CZ外部zd者的角度来看pȝ是怎样使用的? 用例图(用案图)是用于描qCl用案,参与者以及它们之间的q接关系。一个用案图描述了一l动作序列,每一个序列表C系l的外部设施Q系l的参与者)与系l本w的交互。从一个特定参与者的角度看,一个用案完成对其有价值的工作。如?.5所C,用案图仅仅是从参与者用系l的角度来描q系l中的信息,即站在系l外部查看系l应该具有什么功能,而ƈ不描q该功能在Y件内部是如何实现的。用案可以应用于整个pȝQ也可以应用于系l的一个部分,包括子系l、单个的cL者接口。通常Q用案不仅代表这些元素所期望的行为,而且q可以把q些元素用作开发过E中试用案的基? 用例囑括以?斚w内容Q? (a) 用例(Use Case) (b) 参与?Actor) (c) 依赖、泛化和兌关系 用例囄例: (2) cdQ描q类、接口、协作以及它们之间关pȝ图? cd是用于描qCl类、接口、协作以及它们之间的静态关pR在面向对象pȝ的徏模中Q类图是最为常用的图,它用来阐明系l的静态结构。事实上cL对一l具有相同属性、操作、关pd语义的对象的描述Q其中对cȝ属性和操作q行描述时的一个最重要的细节就是它的可见性? cd以以多种形式q接Q例如关联、泛化、依赖和实现{。一个典型的pȝ中通常有若q个cd。一个类图不一定要包含pȝ中所有的c,一个类可以加到几个cd中? cdCZQ? (3) 对象图:表示在某一旉上一l对象以及它们之间的关系的图。对象图可以被看做是cd在系l某一时刻的实例? 对象图是cd的实例,用来描述特定q行时刻一l对象之间的关系。也是_对象用于描述交互的静态部分,它由参与协作的有兛_象组成。但不包括在对象之间传递的M消息? 在创建对象图Ӟ建模人员q不需要用单个的对象图来描q系l中的每一个对象。事实上Q绝大多数系l中都会包含成百上千的对象。用对象来描q系l的所有对象以及它们之间的关系一般是不太现实的。因此,建模人员可以选择所感兴的对象极其之间的关pL描述? 对象图中所使用的符号和cd中用的W号几乎完全相同Q区别仅在于对象囄对象名带有下划线Q而且cMcM间关pȝ所有的实例都要d来? (4) lg?/a>Q描qY件组件以及组件之间的关系Q组件本w是代码的物理模块,lg囑ֈ昄了代码的l构? lg图(构g图)是用于描qCl构件之间的l织和依赖关p,用于建模pȝ的静态实现视图。构件可以是可执行程序集、库、表、文件和文档{,它包含了逻辑cL者逻辑cȝ实现信息Q因此结构模型视囑֒实现模型视图之间存在映射关系? 构徏图中也可以包括包或子pȝQ它们都是用于将模型元素l成较大的组块? lg图例图: (5) 配置?/a>Q描q系l硬件的物理拓扑l构以及在此l构上执行的软g。配|图可以昄计算节点的拓扑结构和通信路径、结点上q行的Y件组件、Y件组件包含的逻辑单元Q对象、类Q等。配|图常常用于帮助理解分布式系l? 配置图(部v图)用来描述pȝq行是进行处理的节点以及在节点上zd的构件的配置。部|图用来对系l的环境模型视图q行建模。在大多数情况下Q部|图用来描述pȝg的扩普结构? 在UML中,建模人员可以用类图来描述pȝ的静态结构,可以用序列图、协作图、状态图、活动图来描q系l的动态行为,而用部v图来描述软g所执行所需的处理器和设备的拓扑l构? (6) 状态图Q通过cd象的生命周期建立模型来描q对象随旉变化的动态行为? 状态图实际上是一U由状态、变q、事件和zdl成的状态机。状态图描述从状态到状态的控制,常用于系l的动态特性徏模。在大多数情况下Q它用来对反应型对象的行为徏模? 在UML中,状态图可以用来对一个对象按事g排序的行为徏模。一个状态图是强调从状态到状态的控制的状态机的简单表C。一般而言Q状态图是对cL描述的设施的补充说明Q它描述了类的所有对象可能具有的状态以及引L态变化的事g? (7) 时序图:交互图描qC一个交互,它由一l对象和它们之间的关pȝ成,q且q包括在对象间传递的信息。交互图表达对象之间的交互,是描qCl对象如何协作完成某个行为的模型化工兗? 序列囑֒协作囄UCؓ交互图。其中,序列囄来描q对象之间消息发送的先后ơ序Q阐明对象之间的交互q程以及在系l执行过E中的某一具体时刻会发生什么事件。序列图是一U强调时间顺序的交互图,其中对象沿横轴方向排列,消息沿纵轴方向排列? 序列图中的对象生命线是一条垂直的虚线Q它表示一个对象在一D|间内存在。由于序列图中大多数对象都存在于整个交互q程中,因此q些对象全部排列在图的顶部,它们的生命线从图的顶部画到图的底部。每个对象的下方有一个矩形条Q它与对象的生命UK叠,它表C对象的控制焦炏V序列图中的消息可以有序P但由于这U图上的消息已经从纵轴上按时间顺序排序,因此消息序号通常予以省略? (8) 协作图:包含cd角色和关联角Ԍ而不仅仅是类元和兌。协作图参加交互的各对象的组l。协作图只对怺间有交互作用的对象和q些对象间的关系建模Q而忽略了其他对象和关联。协作图也是一U交互图Q它收发消息的对象的l织l构? 协作囑֒序列图是协作的,它们可以互相转换。在多数情况下,协作图主要对单调的、顺序的控制徏模,但它也可以用来对包括q代和分支在内的复杂控制进行徏模? 一般而言Q徏模h员可以创建多个协作图Q其中一些是主要的,另外一些是可选择的\径或者异常条件。徏模h员可以用包来l织q些协作图,q给每个图v一个合适的名字Q以便与其它囑别开? (9) zd图:用于展现参与行ؓ的类的活动或动作? zd图是状态图的一U特D情况,其中几乎所有或大多数状态都处于zd状态,而且几乎所有或者大多数变迁都是由源状态中zd的完成触发的。活动图本质上是一U流E图Q它描述了从zd到活动的控制? 可以把活动图看作是新L交互图,但交互图观察的是传递消息的对象Q而活动图观察到的是对象之间传送的消息。尽两者在语义上的区别很细微,但它们用不同的方式来看pȝ的? 如果你觉得本文不错的话,请你点击屏幕右下方的 最后,Ƣ迎大家l箋支持和关注我的博客: http://blog.csdn.net/IBM_hoojo 也欢q大家和我交、探讨IT斚w的知识?/p> 看异怿息大概知道属性wfsjq个字段Q不能完成java.util.Date ?java.sql.Timestamp 日期旉戳的转换。后面还有提C, 没有扑ֈ匚w的conversion或editor?/p>
conversion 在Spring中{换对象属性会用到Q而editor和converter 以及formatter也是在{换对象(String ?gt; Date, String ?gt; TimestampQ,从字W串到对象,从对象到字符串的时候会l常用到?/p>
解决ҎQ?/p>
为message-broker对象注入CustomAmfConversionServiceConfigProcessor对象QCustomAmfConversionServiceConfigProcessor是承AbstractAmfConversionServiceConfigProcessor对象?/p>
AbstractAmfConversionServiceConfigProcessor对象中提供了对各个类型{换serialization/deserialization的方法?/p>
如果你还需要添加更多自q转化服务Q那么你需要给CustomAmfConversionServiceConfigProcessor 注入conversionService对象?/p>
。如果你以后会用到这文章的或觉得以后要重新阅的话Q你可以点击屏幕右下角的
。如果你觉得我的博文不错或是惛_W一旉看到我的动态的话,你可以点dq右下角
。如果你惌点什么的话,你可以点dq右下方?a >
。如果你都点q了Q那真的太谢谢你了,兄弟太支持了。此Ӟ或许你可以点?a >
按钮Q然后看看博文的Dl箋览其他文章?/p>
。如果你以后会用到这文章的或觉得以后要重新阅的话Q你可以点击屏幕右下角的
。如果你觉得我的博文不错或是惛_W一旉看到我的动态的话,你可以点dq右下角
。如果你惌点什么的话,你可以点dq右下方?a >
。如果你都点q了Q那真的太谢谢你了,兄弟太支持了。此Ӟ或许你可以点?a >
按钮Q然后看看博文的Dl箋览其他文章?/p>
]]>org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.Date' to required type 'java.sql.Timestamp' for property 'wfsj'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.util.Date] to required type [java.sql.Timestamp] for property 'wfsj': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:463)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:494)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1097)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:882)
at org.springframework.flex.core.io.SpringPropertyProxy.setValue(SpringPropertyProxy.java:182)
at flex.messaging.io.amf.Amf3Input.readScriptObject(Amf3Input.java:438)
at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:152)
at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
at flex.messaging.io.amf.Amf3Input.readArray(Amf3Input.java:358)
………?/pre>
at flex.messaging.io.amf.AmfMessageDeserializer.readObject(AmfMessageDeserializer.java:227)
at flex.messaging.io.amf.AmfMessageDeserializer.readBody(AmfMessageDeserializer.java:206)
at flex.messaging.io.amf.AmfMessageDeserializer.readMessage(AmfMessageDeserializer.java:126)
at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:145)
at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:291)
at flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$6f090fa2.service(<generated>)
at org.springframework.flex.servlet.MessageBrokerHandlerAdapter.handle(MessageBrokerHandlerAdapter.java:109)
………?/pre>
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.util.Date] to required type [java.sql.Timestamp] for property 'wfsj': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
... 59 more
<bean id="customConfigProcessor" class="com.jp.tic.framework.flex.converter.CustomAmfConversionServiceConfigProcessor"/>
<flex:message-broker services-config-path="/WEB-INF/flex/services-config.xml">
<flex:exception-translator ref="flexExceptionTranslator" />
<flex:config-processor ref="configProcessor"/>
<flex:config-processor ref="customConfigProcessor"/>
<!--<flex:message-interceptor ref="flexMessageInterceptor" />
<flex:message-interceptor ref="loginMessageInterceptor" />-->
</flex:message-broker>
package com.jp.tic.framework.flex.converter;
import java.util.HashSet;
import java.util.Set;
import org.springframework.flex.core.io.AbstractAmfConversionServiceConfigProcessor;
/**
* <b>function:</b> 自定义AMF转换服务
* @author hoojo
* @createDate 2013-7-17 下午01:35:12
* @file CustomAmfConversionServiceConfigProcessor.java
* @package com.jp.tic.framework.flex.converter
* @project JTZHJK-Server
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class CustomAmfConversionServiceConfigProcessor extends AbstractAmfConversionServiceConfigProcessor {
private static Set<Class<?>> classes = new HashSet<Class<?>>();
@Override
protected Set<Class<?>> findTypesToRegister() {
return classes;
}
}
<!-- d配置cd转换器、{换服?-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.jp.tic.framework.mvc.convert.StringToTimestampConverter"/>
<bean class="com.jp.tic.framework.mvc.convert.DateToTimestampConverter"/>
</list>
</property>
<property name="formatters">
<list>
<bean class="com.jp.tic.framework.mvc.formatter.SimpleDateTimeFormatAnnotationFormatterFactory"/>
<bean class="com.jp.tic.framework.mvc.formatter.TimestampFormatterFactory"/>
</list>
</property>
</bean>
<bean id="customConfigProcessor" class="com.jp.tic.framework.flex.converter.CustomAmfConversionServiceConfigProcessor">
<property name="conversionService" ref="conversionService"/>
</bean>
]]>
]]>
]]>
]]>
]]>
]]>
我们采用的方案如下:
先看?/p>
上图的流E大致上是这LQ?
手机端向PC端发送聊天内?
1、手机端E序通过Socketq接服务器端的ServerSocket
2、然后服务器端根据手机Mobile客户端发送过来统一规范的报文或聊天内容Q进行解?
3、然后将解析的内容,再用smack框架转发到openfire服务?
4、最后由openfire服务器向客户端(BS、CS、PhoneClientQ程序发送聊天信息。这里的客户端可以是pc上的览器,pc上的桌面应用Q手机应用等
5、PC客户端BSE序Q用http bind方式监听Q的长连接监听到openfire服务器发送过来的数据Q直接在面中显C?/p>
同样QPC客户端向手机端发送聊天内?
1、PC客户端(BSQ可以直接用http bindQxmpp 提供的httph的长q接方式Q直接向openfire服务器发送聊天数据;
2、然后openfire服务器接收到聊天内容的时候,q时候socket服务器中的smack框架中有一个聊天内容的监听?
3、监听到PC端向openfire发送的内容后,会用socket的流向手机端发送我们定义好的报文或是聊天内?
4、手机端的socket会不停的轮询Q可以模拟心跛_长连接的方式Q,判断是否有消息到达,如果有则昄
而普通的聊天E序的流E则是客L发送信息到openfire服务器,openfire服务器再消息{发给其他客户端。他们省Msocket服务器这部分Q那我们Z么要加上socket服务器这部分呢?
我们q样做也是有自己的道理的Q?
首先Q如果让手机端自己实现向openfire服务器发送程序的代码Q那工作量是相当大的。因为每个手机^C用的语言都不同,每个q_都需要实现向openfire服务器发送聊天信息的报文。这其实是在做重复的工作,而且每个q_实现向手机端发送报文信息的技术会让每个手机端的开发h员都要学会一套和openfire交互的代码。这势必会重复工作、重复相同业务的代码。所以,把这些代码放在一个tcp/ip的socket中{服务器进行统一发送,q也是有好处的?
其次Q把所以发送消息在报文在socket服务器完成,可以对业务进行一个统一的处理、消息过滤?/p>
手机端被否决的解x案,供参?/font>
手机端用http长连接的方式Q这个是不行?/p>
其一、手机的Ud|络不稳定,长连接会l常断掉Q当然你可以自动q行重连
其二、长q接一直连接在服务器上Q占用服务器资源。当然你可以使用心蟩式长q接或是轮询方式
其三、手机端一直连接服务器会用手机端用户的网l带宽流量(量不是免费的,客户会怎么惻I
其四、手机端一直连着服务器,Ҏ机的电量也有消耗(现在决电量也是一个问题)
解决办法
1、在链接openfire服务器后Q线E休眠一D|_再进行登录login操作?/p>
…?/p>
connection.connect();
Thread.sleep(3000);connection.login(user, pass);
…?
2、设|setPacketReplyTimeout参数
......
SmackConfiguration.setPacketReplyTimeout(PACKET_REPLY_TIMEOUT);
config = new ConnectionConfiguration(SERVER, PORT);......
注意Q如果设|了休眠旉或setPacketReplyTimeout参数后还是出现错误,误旉讄再大些看?/p>
参考官方解{:http://community.igniterealtime.org/message/206443#206443
q篇文章介绍Jwchat的安装和配置
首先Jwchat的配|和安装需要具备的环境Q?
Tomcat 5.0.28+/Tomcat 6
JDK 1.6+
Openfire 3.7.1
1?下蝲jwchat工程文g
下蝲站点Q?a >http://blog.jwchat.org/jwchat/download/
Zip下蝲Q?a >http://downloads.sourceforge.net/jwchat/jwchat-1.0.zip?use_mirror=
2?下蝲完成后,jwchat-1.0.zip解压C的tomcat的webapps目录Q将jwchat-1.0命名为jwchatQ如果不q样的话Q可能会出现错误Q如Authorization failed。至这样会方便你访问jwchat工程?
然后index.html.zh_CN{这样带?.后缀.zh_CN的这L文g?zh_CN都删掉,q行重命名?zh_CN是表CZ文版的,当然你也可以直接?.后缀.后缀的文件进行重命名Q那样就是默认的英文版的了?
扚w命名工具c:
package com.hoo.util;
import java.io.File;
/**
* <b>function:</b> 文g命名工具c?/span>
* @author hoojo
* @createDate 2012-5-14 下午01:58:14
* @file FileRenameUtils.java
* @package com.hoo.util
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public abstract class FileRenameUtils {
private final static String FILE_PATH = "D:\\apache-tomcat-6.0.33\\webapps\\jwchat";
/**
* <b>function:</b> 指定目录下的文件的typecd的文Ӟq行重命名,命名后的文g去掉type
* <p>example: 如果type = htmlQ?index.html.html -> index.html</p>
* <p>example: 如果type = zh_CNQ?index.html.zh_CN -> index.html</p>
* @author hoojo
* @createDate 2012-5-16 下午02:16:48
* @param path
* @param type
*/
public static void rename(String path, String type) {
if (path == null || "".equals(path)) {
path = FILE_PATH;
}
File dir = new File(path);
File[] list = dir.listFiles();
for (File file : list) {
String name = file.getName();
String[] s = name.split("\\.");
if (s.length == 3 && type.equals(s[2])) {
System.out.println(s[0] + "--" + s[1] + "--" + s[2]);
file.renameTo(new File(path + "/" + s[0] + "." + s[1]));
}
}
}
public static void main(String[] args) {
FileRenameUtils.rename("D:\\apache-tomcat-6.0.33\\webapps\\jwchat", "zh_CN");
}
}
3?下蝲JabberHTTPBindq个包,因ؓ直接下蝲的jwchat没有WEB-INF、web.xml是无法运行的?
JabberHTTPBind是jwchatq行http bind通信的一U方式,它可以让jwchat和openfireq行链接通信?
站点Q?a >http://blog.jwchat.org/jhb/
下蝲地址Q?a >http://blog.jwchat.org/download/JabberHTTPBind-1.1.1.zip
JabberHTTPBind会依赖xalan的library?
下蝲站点Q?a >http://xml.apache.org/xalan-j/downloads.html
下蝲目录Q?a >http://labs.renren.com/apache-mirror/xml/xalan-j/
4?下蝲完成后,JabberHTTPBind的zip解压出来的WEB-INF、META-INF一q放到刚才的jwchat目录中,q且刚才下载的xalan的xalan.jar,serializer.jar, xercesImpl.jar, xml-apis.jar攑ֈwebapps\jwchat\WEB-INF\lib目录下即可?
5?修改jwchat目录中的相关配置
修改config.js文g
var BACKENDS =
[
{
…?/pre>},{…?/pre>},{name:"Open Relay",
description:"HTTP Binding backend that allows connecting to any jabber server",
httpbase:"/JHB/", /* 修改q里为:/jwchat/JHB/ */type:"binding",
default_server: SITENAME},{…?/pre>}];
修改WEB-INF目录下的web.xml文g
<servlet-mapping>
<servlet-name>Jabber HTTP Binding Servlet</servlet-name>
<url-pattern>/</url-pattern>
url-pattern修改为:/JHB/
<!-- q里的修改主|对应上面的config.jsQ如果config.js的httpbase配置?jwchat/Q那q里的就不用修改?-->
</servlet-mapping>
6?启动tomcat后,讉Khttp://localhost:8080/jwchat/
如果d出现Service unavailableq个问题Q那么会有以下几U情况:
A?表明服务器不可用Q可能是openfire服务器没有启动,
B?webapps\jwchat \config.js的配|有问题Q如var SITENAME = "localhost";和openfire服务器地址没有对应
C?伴随出现QException in thread "Thread-34" javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found异常Q可能是tomcat版本低于tomcat6或是jwchat~少相应的jar包,如缺xml的serializer.jar、xalan.jar、xercesImpl.jar、xml-apis.jar
D、如果在满了c步骤Q有djra包还出现Exception in thread "Thread-34" javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found异常Q徏议删除tomcat/work目录下的~存Q然后重启tomcat试试
7?如果d出现Authorization failed验证p|Q那么有以下几种可能的情况:
A?用户没有注册
B?openfire的证书(C:\Program Files\openfire\resources\securityQ没有安装到相应的jdk的C:\Program Files\Java\jre6\lib\security目录?
如果出现q种异常信息Qjavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed也表明是安全证书的问题;
关于解决ssl验证Q网上有在jsjac.js中的if(this.has_sasl) q行前面加上this.has_sasl = false;来取消ssl安全证书的验证?
C?如果你的工程名称不是jwchatQ徏议把它修Ҏjwchatq且修改config.xml的相关链接的配置QhttpbaseQ?
D?q有可能是你当前的用h有注册,q个时候你可以注册一个用h是在openfire控制台的用户l中d一个用P然后再等了看看是否存在这个问题?
8?修改服务器名U?
点击服务器à服务器理器à编辑属?修改服务器名U?
修改后的服务器名U?
出现叹号Q我们要删除安全证书Q点L务器à服务器设|à服务器安全证书删掉q里的证书?
删除后,在当前页面会出现提示Q然后按照提C点ȝ应的链接Q重启服务器Q然后登陆,再生成证?
生成证书需要点旉Q然后生成完成后Q手动重启openfire服务器,再次登陆发现警告没有了?
9?在服务器端增加配|?
xmpp.httpbind.client.requests.polling = 0
xmpp.httpbind.client.requests.wait = 10
安装指南
Openfire是一个强大的x消息QIMQ和聊天服务器,它实CXMPP协议。这份文件将引导您通过安装Openfire。对于更多的功能和信息的完整列表Q请讉KOpenfire|站Q?a >http://www.igniterealtime.org/projects/openfire/
q行Openfire 安装? 应用~省被安装于目?c:\Program Files\Openfire .
可选择RPM包或tar.gz? 如果使用RPM? 用你的包理器运行把它Openfire安装到目?/opt/openfire:
rpm -ivh openfire_3_0_0.rpm
如果使用.tar.gz? 解压到目?/opt ?/usr/bin:
tar -xzvf openfire_3_0_0.tar.gz mv openfire /opt
注意: .tar.gz包不一定包含Java虚拟?JRE). 所? 你必M前就?JDK ?JRE 1.5.0 (Java 5) 或之后安装到你的pȝ? 你可以在命o行键?"java -version" 来检查你的java版本Q然?(如果必要) 讉K http://java.sun.com 更新你的Java安装.
Z完成Openfire的安? 你需要执行以下步?
本文也包括以下信?
你的分发版里的文件应该像下面q样 (Z短一点,一些子目录被忽略了):
openfire/ |- readme.html |- license.html |- conf/ |- bin/ |- jre/ |- lib/ |- plugins/ |- admin/ |- resources/ |-database/ |-security/ |- documentation/
Openfire能把它的数据存储在一个嵌入式的数据库里,你也能选择使用一个外部数据库,例如MySQL或Oracle. 如果你喜Ƣ用外部数据库, 你必d开始安装之前准备好? 更多信息?a >数据库安?/a>.
Openfire內徏了一个基于web? "向导"驱动的安装和配置工具. 单地启动Openfire(分^台的指引如下) q用浏览器q接到管理控制台. Zweb的管理控制台的缺省端口是9090. 如果你和Openfire在同一台机? 以下URL通常会v作用: http://127.0.0.1:9090.
在完成上q步骤之? Openfire被配置Q你可以用基于web的管理控制台理服务? URL应该和你用来安装服务器用的那个一P除非你在安装期间修改了那个端?
如果你用了Openfire安装? 在你的开始菜单里会有一个快h式来启动囑Ş化启动器. 否则, 在你?Openfire 安装位置?bin/ 目录q行 openfire.exe . 在启动界面上有一个按钮,允许你自动打开你的web览器连接正的URL来完成服务器的安?
如果你正在Windows下运行Openfire, 你或许想在初始化安装之后把Openfire作ؓ一个标准的Windows来运? 如果你用Windows安装? 一?openfire-service.exe 文g会出现在安装目录下?bin 目录. 你可以用这个可执行文g来安装和控制Openfire服务.
从控制台H口, 你可以运行以下命?
你也可以在Windows控制面板使用服务工具来启动和停止服务.
注意: 那个囑Ş化的启动器目前和Windows服务q不兼容. 如果你安装了服务, 你应该用上q的服务控制台来控制服务而不是这个图形启动器.
高用户可能希望传递参数到Java虚拟?VM)来定制Openfire的运行时环境. 你可以在你的Openfire安装目录下的 bin/ 目录建立 vmoptions 文g来做到这一? 对于 Windows服务, 你要Z个新文本文gQ名?openfire-service.vmoptions. 每个lVM的参数应该独立占用文件中的一? 例如, 讄最堆栈大ؓ 512 MB 和最?VM 堆栈?1024 MB, 你可以用:
-Xms512m -Xmx1024m
要新建参数给普通的启动? 新徏一个文Ӟ名ؓ openfired.vmoptions (因ؓ openfire.exe 启动器会调用 openfired.exe 可执行文件来实际地启动服务器).
如果你正在一?Red Hat 或类 Red Hat 的系l上q行 (CentOS, Fedora, {等), 我们使用RPMQ因为它包含一些标准的cRed Hat环境的自定义处理. 假设你用了RPM, 你可以?strong>/etc/init.d/openfire 脚本启动和停止Openfire.
# /etc/init.d/openfire Usage /etc/init.d/openfire {start|stop|restart|status|condrestart|reload} # /etc/init.d/openfire start Starting openfire:
如果你正在一个不同的Linux/Unix变种下运? q且/或你使用了tar.gz '安装?, 你可以用你的Openfire安装目录下的 bin/openfire 脚本启动和停止Openfire:
# ./openfire Usage: ./openfire {start|stop} # ./openfire start Starting openfire
如果你想把Openfire安装成一个服? ?bin/extra 目录提供了两个脚?
如果你通过RPM安装Q不推荐你用这些脚? RPM已经把这些脚本照־很好?
你可以在你的Openfire安装目录下的 bin/ 目录建立 vmoptions 文g来做到这一? 对于 Windows服务, 你要Z个新文本文gQ名?openfire-service.vmoptions. 每个lVM的参数应该独立占用文件中的一? 例如, 讄最堆栈大ؓ 512 MB 和最?VM 堆栈?1024 MB, 你可以用:
高用户可能希望传递参数到Java虚拟?VM)来定制Openfire的运行时环境. 如果你是通过RPM安装? 你可以编?/etc/sysconfig/openfire 文gq找?OPENFIRE_OPTS 选项来定制它. 如果你通过.tar.gz安装? 你要调整你的启动脚本来满你的需?
插glOpenfire增加了额外的Ҏ和协议支持. 在安装完你的Openfire之后, 你可能想下蝲q安装插件以增进你的服务? 插g可从 igniterealtime.org ?plugins 面下蝲或直接从内部的管理控制台直接下蝲.
如果你从Openfire内部的管理控制台下蝲了一个插? 它将被自动安? 如果你手工下载这个插?打包成一?jar文g), 你可以通过把插件文件拷贝到Openfire安装目录下的 plugins/ 目录来布|它. 一个插件监控器自动解包这个插件到一个目录ƈ安装q个插g到Openfire. 你也可以在管理控制台使用"上传插g"功能(?插g 标签? 来从本地文gpȝ装入一个插件到服务?
插g可通过内部的Openfire理控制台来理. 你也可以在Q何时候通过删除插g的JAR文g来手工删除一个插?当你q么q了QOpenfire从内存自动U除q个插gq删除它的目?.
SystemQWindows
WebBrowserQIE6+、Firefox3+
JavaEE ServerQtomcat5.0.2.8、tomcat6
IDEQeclipse、MyEclipse 8
Flex IDEQFlash Builder 4
BlazeDSQ?.5
开发依赖库Q?
JavaEE5、blazeDS 4.5
EmailQhoojo_@126.com
BlogQ?a >http://blog.csdn.net/IBM_hoojo
1?首先要提供相关的jar?
Java服务器端需要提供BlazeDS相关的配|和jar?
下蝲地址Q?a >http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+trunk
下蝲后,解压你可以看到这L一个目?
Docs是文档
Resource是源?
SampleDB是示例用的数据库Q可以运行startdb.bat来启动数据库
Tomcat是内|的tomcatQ如果你没有tomcat的话可以使用它,在tomcat的webapps目录中有samplesCZ
blazeds.war是blazeDS的核心文件、库Q你可以把这个war攑ֈtomcat的webapps目录下,׃自动解压。当然你也可以自己手动解压?
Blazeds-spring.war是和spring整合的配|?
Ds-console.war是blazeDS的控制台E序
Samples.war是官Ҏ供的CZ
Samples-spring.war是spring和blazeDS的整合示?
1、新Z个JavaWeb Project工程Q然后在WEB-INF/lib目录中添加如下jar?
q些jar包可以在blazeds.war包中的lib目录中可以找?
2?然后你需要将blazeds.war包中的WEB-INF目录下的flex目录复制到当前工E的WEB-INF?
3?blazeds.war包中的WEB-INF目录下的web.xml的配|,d到当前工E的web.xml文g?
4?最后基本的样式如下
5?最后你发布当前工程Q如果没有错误就表明你服务器端部|成功了?
6?~写一个HelloWorld的javaE序。代码如?
package com.hoo.flex;
/**
* <b>function:</b> HelloWorld Example
* @author hoojo
* @createDate 2011-8-31 下午06:11:27
* @file HelloWorld.java
* @package com.hoo.flex
* @project BlazeDSServer
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class HelloWorld {
public HelloWorld() {
}
public String sayHello(String name) {
return "[" + name + "] say hello!";
}
}
׃个sayHelloҎQ接收一个参数?
1、创Z个Flex工程Q在选择服务器技术的时候,你需要选择J2EE。然后勾上用J2EE技术,然后选择BlazeDS。点击Next下一?
2、配|根文g夹,也就是JavaEE服务器端发布E序在tomcat中的位置。我q里是在tomcat的webapps的BlazeDSServer中,BlazeDSServer是我的服务器端程序。根URL是访问服务器端程序的urlQ上下文目录对应工程名称Q最后就是输出文件夹目录Q这个是Flex的文件最后在tomcat中保存的目录?
3、最后你需要设|服务器端的services-config.xml的\径到~译参数中,q个很重要!如果你不讄的话Q那么你在后面用RemoteObject调用BlazeDS的时候,需要设|endpoint。设|如下:
-services是参数键Q后面的字符串是倹{我q里是设|BlazeDSServer发布到tomcat目录中的services-config.xml的\径?
4、编译Flex前端代码Q代码如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" viewSourceURL="BlazeDSHelloWorld.mxml" layout="absolute" minWidth="955" minHeight="600">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.AsyncToken;
import mx.rpc.events.ResultEvent;
private function faultHandler(event: Event): void {
Alert.show(event.toString(), event.type);
}
private function resultHandler(event: ResultEvent): void {
//event.result是服务器端返回对?/pre>result.text = "MessageQ? + event.result.toString();}private function sendHandler(): void {helloRemoteObject.sayHello(userName.text);}]]>
</mx:Script><!-- 当工E没有设|编译器-service参数 或是-context-root{参敎ͼ需要手动设|endpoint参数 -->
<mx:RemoteObjectid="helloRemoteObject"destination="helloWorld"fault="faultHandler(event)"result="resultHandler(event)"showBusyCursor="true"/><mx:Panel x="10" y="10" width="272" height="148" layout="absolute" title="BlazeDS Remote HelloWorld Sample"><mx:Label x="10" y="22" text="误入名U?/><mx:TextInput x="70" y="19" id="userName"/><mx:Button x="184" y="45" label="发? click="sendHandler()"/><mx:Text x="10" y="79" id="result"/></mx:Panel></mx:Application>
首先你需要将Java服务器端的HelloWorldE序配置在flex的remoting-config.xml中,配置如下Q?
<?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="helloWorld">
<properties>
<source>com.hoo.flex.HelloWorld</source>
</properties>
</destination>
</service>
上面mxml代码中的RemoteObject的destination对应的就是remoting-config.xml配置文g中的destination的id。这个是一一对应的,然后在sendHandlerҎ中,helloRemoteObject对应的就是RemoteObject的idQ而sayHelloҎ对应的就是配|在remoting-config.xml中的destination的source的Java服务器端代码的公有方法。添加完配置后,需要重启tomcat?
q行上面的flexE序后,如果输入参数后,点击发送,可以看到服务器端q回的消息就说明BlazeDS整合Flex成功了?