跳到导航
BEA Dev2Dev Oracle and BEA
首页 资源中心 dev2dev学堂 在线技术论坛 User Group CodeShare
dev2dev 首页 > 资源中心 > 技术文章
Beehive JMS Control轻松访问Weblogic Server 9.2 JMS

时间:2006-09-14
作者:陈逸鹤
浏览次数:
本文关键字:Weblogic Server 9.2JMS的基本配置Beehive JMS ControlJMS资源
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章

  最近看到一篇关于如何使用Spring的JMS,提供方便的JMS开发的文章,便有了写这篇文章的想法,希望通过对Beehive JMS Control的介绍和使用,给读者一些比较。

  众所周知Java 消息服务 (JMS) 是用于与消息传递系统进行通信的 Java API。消息传递系统通常在企业应用程序中用来与旧版系统进行通信,或者在运行于不同环境或不同主机上的业务组件之间提供通信通道。而借助 Beehive JMS 控件,就可轻松与提供 JMS 实现的消息传递系统(如 WebLogic Server 或面向消息的中间件系统 (MOM) 轻松进行交互。

Beehive及Java Control

   Beehive是Apahce的开放源代码项目。自2004年5月份,BEA系统公司宣布将WebLogic Platform中一系列居于核心地位的运行时框架(Runtime Framework)开放源代码并贡献给Apache项目后,这个Beehive的框架就一直成为开源社区关注的焦点之一。

  Beehive的目标是使J2EE开发更加简单,它是一个可扩展的Java应用程序框架,该框架具有针对Web服务,Web应用程序和资源访问的集成元 数据驱动的编程模型。该框架利用了JDK1.5的最新创新,特别是JSR175元数据注解,可以减少开发人员的编码,从而提高开发效率。目前, Beehive项目包括Java控件,NetUI,Java Web服务元数据,能够帮助Java开发人员开发出基于组件和标准的JAVA应用。

  Java控件(Control)架构是一个基于JavaBeans的轻量级组件架构,它公开了用于访问各种J2EE资源类型简单而一致的客户机模型。该框 架提供了大量的函数,其中包括:基于JSR-175元数据和外部配置数据的配置,自动资源管理,上下文服务和用于创建新控件类型的可扩展设计模型。在Beehive1.0版本中还提供了三种系统控件EJB Control, JDBC Control,JMS Control,分别用于ejb使用,数据库访问操作,以及JMS操作。详细文档可以在Beehive主目录下的docs/system-controls中找到。在这里我们将主要结合WebLogic Server 9.2 提供的消息服务来介绍JMS Control的使用及特性。

在Weblogic Server9.2中配置消息传递系统

   让我们先回顾一下消息传递系统的一些基本概念。

  消息传递系统可在软件组件之间提供通信。消息传递系统的客户端可以与任何其他客户端相互收发消息。每个客户端都连接到可提供消息收发功能的消息传递服务器。WebLogic JMS 是 WebLogic Server 的组件,它是消息传递服务器的示例。WebLogic Server 还支持第三方消息传递系统。

  消息传递系统提供了异步的分布式通信。这意味着,组件可以将消息发送到目标,而消息接收方可以从目标检索消息,但发送方和接收方不能直接进行通信。发送方只知道存在可向其发送消息的目标,而接收方也知道存在可从中接收消息的目标。只要他们要使用的消息格式和目标一致,消息传递系统就会管理实际的消息传递。

  消息传递系统还能提供消息传递的可靠性。具体的可靠性级别通常可按目标或客户端进行配置,但消息传递系统有能力保证消息一定被传递,并可一次性精确传递至每一个接收方。

   JMS 支持两种基本形式的基于消息的通信:“点对点”和“发布和订阅”。

  1. 创建WLS9.2服务器
  2.   首先创建一个应用服务器,使用Configuration Wizard创建新的服务器,这里我们全部使用默认配置。在要求输入服务器域所在的目录时,输入test_domain。新创建的服务器名称默认为AdminServer。

       Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图1

  3. 使用管理控制台
  4.    与WLS8.1中一样,启动应用服务器后,在浏览器中输入http://localhost:7001/console打开控制台。与WLS8.1不同,WLS9中管理控制台的新架构基于WebLogic Portal Framework,而且管理控制台使用构建在Struts之上的模型-视图-控制器方法,这使得控制台更加开放,更加易于扩展。现在,可以以常用于扩展门户应用程序的方式来扩展管理控制台。控制台扩展可以包括现有页面、新页面和小节,以及JSR 168或WSRP portlet的简单改写。如图所示:

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图2

      为了保护修改并防止其他人进行修改,管理控制台中引入了一个新的区域(如图红色部分),称为Change Center,在开始修改域配置之前,首先锁定管理控制台(Lock & Edit)。当完成修改时,保存这些修改(Active Changes)并将它们发布到域中的所有实例,也可以回滚修改并释放锁定。每台服务器自行决定它是否接收修改。如果所有的服务器都接受修改,它们将更新它们的工作配置树,修改完成。如果有一台或多台服务器不接受修改,那么所有的服务器都不会使修改生效,因此避免了出现未完成的中间状态。这种功能有助于确定WebLogic Server配置信息总是正确和一致的。

      这里我们点击Lock & Edit开始配置消息传递系统。

  5. 配置JMS服务器
  6.    首先,我们需要配置一个JMS Server,对于定位到 JMS 服务器的 JMS 模块中的队列和主题,JMS 服务器可作为管理容器。

      在Domain Structure中定位到JMS Servers,点击New创建一个新的JMS Server:

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图3

      我们给这个JMS服务器命名:TestJMSServer

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图4

      点击Next将其绑定到AdminServer(管理服务器)上,如图

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图5

  7. 创建 JMS 系统模块
  8.    JMS系统模块是Weblogic Server 9中的新特性,用于将 JMS 系统资源配置并存储为与标准 J2EE 模块相似的模块。这样的资源包括队列、主题、连接工厂、模板、目标关键字、配额、分布式队列、分布式主题、外部服务器和 JMS 存储转发 (SAF) 参数。管理员可以将JMS 系统模块作为全局系统资源进行配置和管理。

      此处我们创建一个名为 TestSystemModule的JMS系统模块。同样绑定到AdminServer

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图6

  9. 新建 JMS 队列
  10.    点对点消息传递通过 JMS 队列完成,这些队列是 JMS 服务器中配置的特定命名资源。JMS 客户端(如 JMS 控件)可将消息发送到队列或从队列接收消息。

      创建JMS 系统模块后,我们便可以在为该模块添加系统模块实体,这些实体包括主题、队列、连接工厂、分布式主题、分布式队列和外部服务器。首先选择新增队列类型的资源:

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图7

      系统根据选择的资源类型,提示需要输入的基本信息。我们命名该队列为TestQueue.JNDI名称设置为queue.TestQueue

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图8

      点击下一步,首先创建一个子部署对应刚才创建的TestQueue,使用它的默认名称

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图9

      接着为子部署TestQueue选择一个JMS Server,我们选择最初定义的TestJMSServer作为管理容器。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图10

  11. 新建JMS连接工厂
  12.    JMS 客户端必须先通过连接工厂获取与消息传递系统的连接,然后才可以向队列或主题发送消息,或从队列或主题接收消息。连接工厂是由消息服务器管理员配置的资源。连接工厂的名称存储在 JNDI 目录中,希望创建连接的客户端可以在该目录中查找它们。

      与创建JMS队列类似,我们创建另一个JMS系统模块实体。选择实体类型为Connection Factory(连接工厂),并命名为TestConnectionFactory。JNDI名称设为connectionFactory.TestConnectionFactory,并同样绑定到TestJMSServer,同时您还可以配置包括各种客户端连接、默认传递、负载平衡和安全性等参数。这里我们使用默认参数。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图11

  13. 激活更改

   我们已经在Weblogic Server 9中完成了一个最基本的消息传递系统的设置,最后,我们需要在更改中心中点击激活更改(Activate Changes)来使配置生效。

Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图12

  如果一切正常将出现修改生效的提示信息。接着我们便可以使用Beehive JMS Control来传递消息了。

Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图13

创建Beehive JMS Control应用

   我们使用BEA Workshop for Weblogic Platform Version9.2来开发这个JMS Control应用,它被认为是目前最好的Beehive应用开发工具。

  1. 创建新项目
  2.   新建工程,选择Dynamic Web Project 类型

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图14

      输入工程的名称,ControlTest, Target runtime 选择BEA Weblogic v9.2

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图15

       点击下一步,我们选择缺省的配置,注意,由于要使用JMS Control和页面流,因此这里必须选中Beehive Controls和Beehive NetUI。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图16

  3. 新建服务器
  4.    在开发之前,我们先配置当前的开发环境使其绑定到之前创建的应用服务器上。这有利于之后的开发和测试。选择new->Server,创建一个BEA Weblogic V9.2 Server服务器,如下图所示:

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图17

      点击Next,在Domain home中选择开始创建的服务器域所在目录,完成创建。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图18

  5. 创建JMS Control
  6.   首先创建一个包(test.jms.control)来存放我们的控件,右键点击该包,选择new->JMS Control,来创建我们的JMS Control。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图19

      输入控件的名称:TestQueueSender,点击下一步,在控件创建向导中配置JMS Control的必要参数。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图20

      其中队列以及Connection Factory 的JNDI name都可以通过Browse在绑定应用服务器中找到。点击Finish完成,让我们看一下生成的控件代码:

    package test.jms.control;
    
    import org.apache.beehive.controls.system.jms.JMSControl;
    
    import org.apache.beehive.controls.api.bean.ControlExtension;
    
    @ControlExtension
    
    @JMSControl.Destination(sendType = JMSControl.DestinationType.Queue, sendJndiName = "queue.TestQueue", jndiConnectionFactory = "connectionFactory.TestConnectionFactory", transacted = false)
    
    public interface TestQueueSender extends JMSControl {
    
    /**
    
    * Send a JMSControl.MessageType.Text message to the queue or topic;
    
    */
    
    @Message(JMSControl.MessageType.Text)
    
    public void sendMessage(String body);
    
    }
    

      JMS Control是一种扩展控件,它需要继承org.apache.beehive.controls.system.jms.JMSControl接口,并用@ControlExtention作为注释说明:

       @ControlExtension

       public interface TestQueueSender extends JMSControl {

       }

      为了让这个JMS Control能够正常工作,它必须知道要发送消息的目的地(destination of messages)。在JMS Control中,这将通过JNDI context来实现。我们同样通过JDK1.5的元数据注释功能来定义这个控件的消息目的地。

       @JMSControl.Destination(sendJndiName="queue.TestQueue",

       jndiConnectionFactory="connectionFactory.TestConnectionFactory")

      这样这个控件将通过刚才在Weblogic Server9中定义的TestConnectionFactory向TestQueue发送消息。其他属性参考下表:

    属性 类型 必填项 描述
    sendJndiName String JMS对列或主题的JNDI名称
    SnedCorrelationProperty String 这是一个消息传递的属性,标示了JMS消息头部,缺省空
    jndiConnectionFactory String 连接工厂的JNDI名称
    transacted boolean True 表示对列在容器中的事务控制下 缺省值为True.
    acknowledgeMode enum AcknowledgeMode 标示了消息确认策略, 它的值是Auto,Client或 DupsOk. 缺省为 Auto.
    sendType JMSControl.Destination 发送消息的类型,它的值是 Auto,Queue 或 Topic. 如果是 Auto, 则发送消息的类型将由sendJndiName 属性指定的目标决定. 缺省值是 Auto.
    jndiContextFactory String jndi-context-factory的类名.缺省为空值.
    jndiProviderURL String 访问 JNDI提供的URL. 缺省为空值

    一个JMS Control接口可以包含一个或多个消息发送方法,这些方法必须包含至少一个非注释参数,来表示消息体。其他注释参数可以用来提供其他属性值或运行时信息。方法本身也能被注释描述。

    JMS Control可以发送文本消息(包括XML消息),byte array消息,object消息,和javax.jms.Message(JMS 消息)。这些类型是在JMS messaging service中定义的。当我们定义一个发送方法时,我们使用JMSControl.Message.messageType()注释来说明发送的是哪种类型的消息。

       @Message(JMSControl.MessageType.Text)

       public void sendMessage(String body);

      可以看到在生成的JMS Control中定义了一个sendMessage方法,发送Text类型的消息。

  7. 创建页面流
  8.    右键点击希望创建页面流的所在目录,选择New->Page Flow,打开页面流创建向导,如图所示,我们简单的命名这个页面流为flow。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图21

      由于篇幅所限,这里我们不详细介绍页面流,直接点击Finish完成创建,可以看到页面流的视图,由一个begin Action和一个index.jsp页面构成,右键点击页面流视图中的index.jsp,选择rename,将该文件重命名为sendMsg.jsp。

      接着我们需要创建一个表单form来发送JMS消息,双击sendMsg文件,在JSP Desgin Palette中拖拽Create Form到sendMsg.jsp中。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图22

      弹出form创建向导,由于我们还未创建处理消息发送的Action,这里我们选择New来新建一个Action。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图23

      向导提供了多种快速创建Action的模版,由于之前我们已完成了JMS Control的开发,为了简单起见,我们选择Add Item Via Control,workshop会根据控件提供的sendMessage(String)方法创建Action。

      在Control中,选择testQueueSender, 为了能反复发送消息,我们在Forward To中设置转向发送页面sendMsg.jsp。其他参数如下图所示设置。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图24

      点击Finish, workshop帮助我们完成了一切, sendMsg.jsp如下图

     <%@ page language="java" contentType="text/html;charset=UTF-8"%>
      
      <%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0"  prefix="netui"%>
      
      <%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0"  prefix="netui-data"%>
      
      <%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0"  prefix="netui-template"%>
      <netui:html>
      
      <head>
      
      <netui:base/>
      
      </head>
      
      <netui:body>
      
      <p>Beehive  NetUI JavaServer Page - ${pageContext.request.requestURI}</p>
      
      <netui:form  action="sendMessage">
      
      <div>
      
      <table>
      
      <tr valign="top">
      
      <td><label for="field1"> Body: </label></td>
      
      <td><netui:textArea  dataSource="actionForm.body"  tagId="field1"></netui:textArea></td>
      
      </tr>
      
      </table>
      
      </div>
      
      <netui:button  value="sendMessage"  type="submit"  />
      
      </netui:form>
      
      </netui:body>
      
      </netui:html>
    

      最终的pageFlow如下图所示:

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图25

    package test.jms.flow;
    
    import javax.servlet.http.HttpSession;
    
    import org.apache.beehive.netui.pageflow.PageFlowController;
    
    import org.apache.beehive.netui.pageflow.annotations.Jpf;
    
    import org.apache.beehive.controls.api.bean.Control;
    
    import test.jms.control.TestQueueSender;
    
    import org.apache.beehive.netui.pageflow.Forward;
    
    @Jpf.Controller(simpleActions = { @Jpf.SimpleAction(name = "begin", path = "sendMsg.jsp") })
    
    public class FlowController extends PageFlowController {
    
    private static final long serialVersionUID = -1949810128L;
    
    @Control
    
    private TestQueueSender testQueueSender;
    
    @Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "sendMsg.jsp") })
    
    public Forward sendMessage(SendMessageFormBean form) {
    
    Forward forward = new Forward("success");
    
    java.lang.String body = form.getBody();
    
    testQueueSender.sendMessage(body);
    
    return forward;
    
    }
    
    /**
    
    * Callback that is invoked when this controller instance is created.
    
    */
    
    @Override
    
    protected void onCreate() {
    
    }
    
    /**
    
    * Callback that is invoked when this controller instance is destroyed.
    
    */
    
    @Override
    
    protected void onDestroy(HttpSession session) {
    
    }
    
    @Jpf.FormBean
    
    public static class SendMessageFormBean implements java.io.Serializable {
    
    private static final long serialVersionUID = -1735661371L;
    
    
    
    private java.lang.String body;
    
    
    
    public SendMessageFormBean() {
    
    }
    
    
    
    public java.lang.String getBody() {
    
    return body;
    
    }
    
    
    
    public void setBody(java.lang.String body) {
    
    this.body = body;
    
    }
    
    }
    
    }
    

       Workshop为我们生成了Action ,FormBean。我们可以看一下它是如何使用我们创建的JMS Control的。

       @Control

       private TestQueueSender testQueueSender;

      通过@Control将JMS Control引入到页面流中,

      java.lang.String body = form.getBody();

       testQueueSender.sendMessage(body);

      在action中,先得到FormBean中的消息体,然后,用JMS Control发送消息。

       是不是很简单呢?

  9. 调试运行
  10.    为了测试应用,我们打开刚刚创建的页面流,然后点击运行按钮。在弹出的向导中,依次选择服务器,并将ControlTest 绑定到该服务器上。如下图所示。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图26

      Workshop提供了一个集成的浏览器,在服务器启动完毕之后,在浏览器中显示了SendMsg页面。如下图所示。我们在输入框种输入要发送的JMS消息内容,并点击sendMessage发送。由于每次发送之后都会重定向到sendMsg页面,这里我们依次发送三条消息:

      
    This is 1st  message  
    This is 2nd  message  
    This is 3rd  message

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图27

  11. 监控消息
  12.    Weblogic 控制台提供了详细的消息传递信息,我们选择TestQueue队列,点击上方的monitor选项卡,查看它的消息传递和消费情况。如下图所示,其中cosumers表示消息的消费者,由于我们没有创建消息消费者,因此此处各参数均为0。Messages High 为一次发送的峰值,Messages Total表示总的消息数量,Bytes Total表示消息的总Byte数。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图28

      选中TestQueue,点击ShowMessages按钮查看发送到该队列的消息。此处可以看到三条消息。ID唯一标识了每一条消息。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图29

      为了验证发送是否成功,我们点击第一条消息,查看它详细信息,如下图所示。详细信息列出了该消息的参数值。其中在Text中显示的是消息的内容,此处为我们第一次发送的消息体“this is 1st message”,查看另两条消息,分别是第二三次发送的消息内容,证明我们通过Beehive JMS Control成功发送了三条消息到指定队列TestQueue。

    Beehive JMS Control轻松访问Weblogic Server 9.2 JMS-图30

  13. 消息接受客户端

   如果希望通过消息接受客户端验证,可以使用以下参考代码:

package org.test.control.jms;

import java.util.Hashtable;

import javax.jms.*;

import javax.naming.Context;

import weblogic.jndi.*;

public class TestQueueReceiver implements MessageListener{



WLInitialContextFactory contextFactory = new WLInitialContextFactory();



private boolean done = false;

private Context ctx = null;

private QueueConnectionFactory connectionFactory = null;

private QueueConnection connection = null;

private QueueSession session = null;

private QueueReceiver receiver = null;

private Queue queue = null;

private Hashtable ht = null;



public void init(){

try{

ht = new Hashtable();



ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");

ht.put(Context.PROVIDER_URL,"t3://localhost:7001");

ht.put(Context.SECURITY_PRINCIPAL, "weblogic");

ht.put(Context.SECURITY_CREDENTIALS, "weblogic");



ctx = contextFactory.getInitialContext(ht);

connectionFactory = (QueueConnectionFactory)ctx.lookup("connectionFactory.TestConnectionFactory");

connection = connectionFactory.createQueueConnection();

session = connection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);

queue = (Queue)ctx.lookup("queue.TestQueue");

receiver = session.createReceiver(queue);

receiver.setMessageListener(this);

connection.start();

System.out.println("end init");

}catch(Exception e){

e.printStackTrace();

}

}



public void close()throws JMSException{

try{

receiver.close();

session.close();

connection.close();

System.out.println("closed");

}catch(Exception e){

System.out.println(e);

}

}



/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

TestQueueReceiver sqr = new TestQueueReceiver();

try{

sqr.init();

System.out.println("waiting for messsages ....");

synchronized(sqr){

while(!sqr.done){

try{

sqr.wait();

}catch(InterruptedException ie){



}

}

}

sqr.close();

}catch(Exception e){

e.printStackTrace();

}finally{



}

}

public void onMessage(Message message) {

System.out.println("Receive message: "+message);

// TODO Auto-generated method stub

if(message instanceof TextMessage){

try{

TextMessage textMessage = (TextMessage)message;

String msg = textMessage.getText();

System.out.println("Receive message: "+msg);

if(msg.equals("exit")){

synchronized(this){

done=true;

this.notifyAll();

}

}

}catch(Exception e){

System.out.println(e);

}

}

}

}

小结

   通过这个例子,相信大家可以在Weblogic Server 9.2中配置基础的消息传递系统,并能了解到Weblogic Server 9.2 在JMS方面的一些新特性。

  我们还使用Beehive 的JMS Control轻松的发送数据到JMS队列。通过JDK 1.5的Annotation,以声明的方式将控件绑定到特定的资源,从而省略了使用JMS处理消息所必需的样本代码(如,先从上下文中得到一个队列连接工厂,从而创建队列和会话对象等等)。这确实使得开发更加方便清晰,也能帮助初学者快速上手。

  BEA Workshop for WebLogic Platform 9.2的出现,让我们真正体验到了Beehive给开发者带来的乐趣,回顾一下示例程序的开发,我们竟然惊讶地发现,我们甚至没有手工添加过一行代码,所有的一切都通过简单的拖拽和属性配置来完成。在赞叹其强大功能的同时,我们也相信Beehive的发展和使用将会进入一个新的高峰。

  本文示例下载

 作者简介
陈逸鹤 是eBaoTech R&D事业部软件工程师,擅长使用BEA WorkShop开发基于 WebLogic Server的J2EE应用,熟悉流行的开源项目Spring,Beehive,XML Beans等。
dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分

   
相关技术