??xml version="1.0" encoding="utf-8" standalone="yes"?>
JRE: WebSphere 6.1 JRE
目需求:(x)用SUN JDK6自带的JAX-WS创徏Web Service?其中Server端的Web Service接口已发布,我这边的目直接Ҏ(gu)Ҏ(gu)提供的WSDL创徏Client?br />
到的问题:(x)
当调用javax.xml.ws.Service的构造方?Service(URL url, QName qName)的时候,报错如下Q?br />
[3/14/09 14:51:53:750 CST] 0000002c SystemErr R Caused by: java.lang.Throwable: java.lang.LinkageError: You are loading old SAAJ from jar:file:/C:/Program%20Files/IBM/SDP70/runtimes/base_v61/lib/j2ee.jar!/javax/xml/soap/MessageFactory.class
at com.sun.xml.ws.api.SOAPVersion.<init>(SOAPVersion.java:184)
at com.sun.xml.ws.api.SOAPVersion.<clinit>(SOAPVersion.java:83)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:177)
at com.sun.xml.ws.api.BindingID.<clinit>(BindingID.java:318)
...(以下省略300?
Caused by: java.lang.Throwable: java.lang.NoSuchMethodError: javax/xml/soap/MessageFactory.newInstance(Ljava/lang/String;)Ljavax/xml/soap/MessageFactory;
at com.sun.xml.ws.api.SOAPVersion.<init>(SOAPVersion.java:178)
... 21 more
主要是把Classloader mode从默认的Parent_FirstҎ(gu)Parent_LastQ让E序先读自己的class文g以及(qing)jar包?br /> 我就照样画葫芦设|了。顺便说一下,兌׃n库到应用E序Q我无论如何都做不成功。关闭Application,q入ApplicationQ关联共享库Q关联好了,保存成功Q退到外面,再进去,׃n库又没关联上。设|Classloader mode的时候也遇到了这L(fng)问题Q但最l还是迫使其让我保存了。共享库׃理Q反正无所谓,只要加蝲序变了成?br /> 但事实上Q我的担心成Z事实Q程序启动失败,虽然h了,但只跑了一部分代码,后面的服务都没v来。想想也是,E序那么大,用到的jar包那么多Q改了Classloader modeQ一切全都ؕ套了...
之后Q查看Console-->TroubleShooting-->Class Loader ViewQ发现系l最开始加载的是WebSphere下的ext目录下的jar?/p>
所以就投机取yQ把我要用的两个saaj包放Cext目录下,重启Q程序运行成?br /> 当然Q这不是一个好的解军_法,阿三那里能不能通得q还是个问题
JMS 支持两种消息cdPTP QPoint-to-PointQ和Pub/SubQPublish-SubscribeQ,分别UCQPTP Domain 和Pub/Sub
Domain?br />
PTP的主要特Ҏ(gu)Q?br />
1Q一条消息只有一个用?br />
2Q不存在旉限制
Pub/Sub主要特点有:(x)
1Q一条消息可以有多个使用?br />
2Q存在时间限制。订阅者可以用持久方式来订阅消息Q但是也?x)过期或者取消订?br />
q两U接口都l承l一的JMS Parent 接口QJMS 主要接口如下所C:(x)
JMS Parent | PTPDomain | Pub/Sub Domain |
ConnectionFactory | QueueConnectionFactory | TopicConnectionFactory |
Connection | QueueConnection | TopicConnection |
Destination | Queue | Topic |
Session | QueueSession | TopicSession |
MessageProducer | QueueSender | TopicPublisher |
MessageConsumer | QueueReceiver,QueueBrowser | TopicSubscriber |
以下是对q些接口的简单描qͼ(x)
ConnectionFactory Q连接工厂,JMS 用它创徏q接
Connection QJMS 客户端到JMS Provider 的连?/p>
Destination Q消息的目的?/p>
SessionQ?一个发送或接收消息的线E?/p>
MessageProducerQ?由Session 对象创徏的用来发送消息的对象
MessageConsumerQ?由Session 对象创徏的用来接收消息的对象
JMS 消息׃下几部分l成Q消息头Q属性,消息体?/p>
消息?Header) -消息头包含消息的识别信息和\׃息,消息头包含一些标准的属性如QJMSDestination,JMSMessageID{?/p>
消息?/strong> | p讄 |
JMSDestination | send ?publish Ҏ(gu) |
JMSDeliveryMode | send ?publish Ҏ(gu) |
JMSExpiration | send ?publish Ҏ(gu) |
JMSPriority | send ?publish Ҏ(gu) |
JMSMessageID | send ?publish Ҏ(gu) |
JMSTimestamp | send ?publish Ҏ(gu) |
JMSCorrelationID | 客户 |
JMSReplyTo | 客户 |
JMSType | 客户 |
JMSRedelivered | JMS Provider |
属?Properties) -除了消息头中定义好的标准属性外QJMS提供一U机制增加新属性到消息头中Q这U新属性包含以下几U:(x)
应用需要用到的属?
消息头中原有的一些可选属?
JMS Provider 需要用到的属性?/p>
标准的JMS 消息头包含以下属性:(x)
JMSDestination --消息发送的目的地?/p>
JMSDeliveryMode --传递模式, 有两U模式:(x)PERSISTENT和NON_PERSISTENTQPERSISTENT表示该消息一定要被送到目的圎ͼ否则?x)导致应用错误? NON_PERSISTENT表示偶然丢失该消息是被允许的Q这两种模式使开发者可以在消息传递的可靠性和吞吐量之间找到^衡点?/p>
JMSMessageID 唯一识别每个消息的标识,由JMS Provider 产生?/p>
JMSTimestamp 一个消息被提交lJMS Provider 到消息被发出的时间?/p>
JMSCorrelationID 用来q接到另外一个消息,典型的应用是在回复消息中q接到原消息?/p>
JMSReplyTo 提供本消息回复消息的目的地址?/p>
JMSRedelivered如果一个客L(fng)收到一个设|了JMSRedelivered属性的消息Q则表示可能该客L(fng)曄在早些时候收到过该消息,但ƈ没有{收(acknowledged)?/p>
JMSType 消息cd的识别符?/p>
JMSExpiration 消息q期旉Q等于QueueSender 的sendҎ(gu)中的timeToLive值或TopicPublisher 的publish Ҏ(gu)中的timeToLive值加上发送时ȝGMT旉倹{如果timeToLive值等于零Q则JMSExpiration被设为零Q表C消息怸q期。如果发送后Q在消息q期旉之后消息q没有被发送到目的圎ͼ则该消息被清除?/p>
JMSPriority 消息优先U,?-9 十个U别Q?-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider严格按照q十个优先发送消息,但必M证加急消息要先于普通消息到达?/p>
消息?Body) - JMS API定义?U消息体格式Q也叫消息类型,你可以用不同Ş式发送接收数据ƈ可以兼容现有的消息格式,下面描述q?U类型:(x)
消息cd | 消息?/strong> |
TextMessage | java.lang.String对象Q如xml文g内容 |
MapMessage | ?值对的集合,名是String对象Q值类型可以是JavaM基本cd |
BytesMessage | 字节?/td> |
StreamMessage | Java中的输入输出?/td> |
ObjectMessage | Java中的可序列化对象 |
Message | 没有消息体,只有消息头和属?/td> |
Message是以?cȝ基础。最常用的是ObjectMessage和TextMessage
消息的同步接?/strong>
同步接收是指客户端主动去接收消息QJMS 客户端可以采用MessageConsumer的receiveҎ(gu)L收下一个消息?/p>
消息的异步接?/strong>
异步接收是指当消息到达时Q主动通知客户端。JMS客户端可以通过注册一个实现MessageListener接口的对象到MessageConsumerQ这P每当消息到达ӞJMS Provider ?x)调用MessageListener中的onMessage Ҏ(gu)?/p>
PTP(Point-to-Point)模型是基于队列的Q发送方发消息到队列Q接收方从队列接收消息,队列的存在得消息的异步传输成ؓ(f)可能。和邮gpȝ中的邮箱一P队列可以包含各种消息QJMS Provider 提供工具理队列的创建、删除。JMS PTP模型定义了客L(fng)如何向队列发送消息,从队列接收消息,览队列中的消息?/p>
下面描述JMS PTP 模型中的主要概念和对象:(x)
名称 | 描述 |
Queue | 由JMS Provider 理Q队列由队列名识别,客户端可以通过JNDI接口用队列名得到一个队列对象?/td> |
TemporaryQueue | 由QueueConnection 创徏Q而且只能由创建它的QueueConnection 使用?/td> |
QueueConnectionFactory | 客户端用QueueConnectionFactory 创徏QueueConnection 对象?/td> |
QueueConnection | 一个到JMS PTP provider 的连接,客户端可以用QueueConnection创徏QueueSession来发送和接收消息?/td> |
QueueSession | ? 供一些方法创建QueueReceiver、QueueSender、QueueBrowser和TemporaryQueue。如果在 QueueSession关闭Ӟ有一些消息已l被收到Q但q没有被{收(acknowledged)Q那么,当接收者下ơ连接到相同的队列时Q这些消? q会(x)被再ơ接收?/td> |
QueueReceiver | 客户端用QueueReceiver接收队列中的消息Q如果用户在QueueReceiver中设定了消息选择条gQ那么不W合条g的消息会(x)留在队列中,不会(x)被接收到?/td> |
QueueSender | 客户端用QueueSender 发送消息到队列?/td> |
QueueBrowser | 客户端可以QueueBrowser 览队列中的消息Q但不会(x)收走消息?/td> |
QueueRequestor | JMS 提供QueueRequestorcȝ化消息的收发q程。QueueRequestor的构造函数有两个参数QQueueSession和queueQQueueRequestor 通过创徏一个(f)旉列来完成最l的收发消息h?/td> |
可靠?Reliability) | 队列可以长久C存消息直到接收者收到消息。接收者不需要因为担心消息会(x)丢失而时d队列保持Ȁzȝq接状态,充分体现了异步传输模式的优势?/td> |
JMS Pub/Sub 模型定义了如何向一个内容节点发布和订阅消息Q这些节点被UC主题(topic)?/p>
主题可以被认为是消息的传输中介,发布?publisher)发布消息C题,订阅?subscribe)从主题订阅消息。主题得消息订阅者和消息发布者保持互相独立,不需要接触即可保证消息的传送?/p>
下面描述JMS Pub/Sub 模型中的主要概念和对象:(x)
名称 | 描述 |
订阅(subscription) | 消息订阅分ؓ(f)非持久订?non-durable subscription)和持久订?durablesubscrip-tion)Q非持久订阅只有当客L(fng)处于Ȁzȝ态,也就是和JMS Provider保持q接状态才能收到发送到某个主题的消息,而当客户端处于离U状态,q个旉D发C题的消息会(x)丢失Q永q不?x)收到。持久订阅时Q客L(fng)向JMS注册一个识别自pn份的IDQ当q个客户端处于离U时QJMS Provider ?x)?f)q个ID 保存所有发送到主题的消息,当客户再ơ连接到JMS ProviderӞ?x)根据自qID得到所有当自己处于ȝ时发送到主题的消息?/td> |
Topic | 主题由JMS Provider 理Q主题由主题名识别,客户端可以通过JNDI接口用主题名得到一个主题对象。JMS没有l出主题的组l和层次l构的定义,由JMS Provider 自己定义?/td> |
TemporaryTopic | 临时主题由TopicConnection创徏Q而且只能由创建它的TopicConnection使用。(f)时主题不能提供持久订阅功能?/td> |
TopicConnectionFactory | 客户端用TopicConnectionFactory 创徏TopicConnection 对象?/td> |
TopicConnection | TopicConnection 是一个到JMS Pub/Sub provider的连接,客户端可以用TopicConnection创徏TopicSession来发布和订阅消息?/td> |
TopicSession | TopicSession提供一些方法创建TopicPublisher、TopicSubscriber、TemporaryTopic。它q提供unsubscribeҎ(gu)取消消息的持久订阅?/td> |
TopicPublisher | 客户端用TopicPublisher 发布消息C题?/td> |
TopicSubscriber | 客户端用TopicSubscriber接收发布C题上的消息。可以在TopicSubscriber中设|消息过滤功能,q样Q不W合要求的消息不?x)被接收?/td> |
Durable TopicSubscriber | 如果一个客L(fng)需要持久订阅消息,可以使用Durable TopicSubscriberQTopSession提供一个方法createDurableSubscriber创徏Durable TopicSubscriber 对象?/td> |
恢复和重新派?Recovery and Redelivery) | 非持久订阅状态下Q不能恢复或重新zN一个未{收的消息。只有持久订阅才能恢复或重新zN一个未{收的消息?/td> |
TopicRequestor | JMS 提供TopicRequestorcȝ化消息的收发q程。TopicRequestor的构造函数有两个参数QTopicSession和topic。TopicRequestor 通过创徏一个(f)时主题来完成最l的发布和接收消息请求?/td> |
可靠?Reliability) | 当所有的消息必须被接Ӟ则用持久订阅模式。当丢失消息能够被容忍,则用非持久订阅模 |