JavaEE知识整理系列(六)JMS

1.         网上典型例子

例1:http://www.verydemo.com/demo_c202_i2146.html 这个例子相对比较详细完整,也是JMS入门级的资料,例子中的JMS消息没有进行持久化。下面的DIY也是在这个基础上进行。

本DIY的例子的JBOSS安装程序是jboss-4.0.4.GA-Patch1-installer.jar,JBoss环境就是http://blog.csdn.net/ictcamera/article/details/13997997 ,整个例子是在该环境基础上进行的。因为这个JBOSS版本例1的版本有差异,所有在DIY过程会出现一些问题,按照例子1进行的过程出现很多问题(当然不是完全按照例1进行,本例子中全程使用了IDE-myeclipse作为编译、打包工具,jar包和配置文件完全是手工进行的),主要问题和解决办法如下:

1、“如何来管理目的”部分,安装文档介绍,调用一个通过调用service=DestinationManager 登记的JMX Bean 来实现目的地的动态操作(增加、删除)。如果代码调用部分和JMXBean服务器在一个JVM(注意:(1)这个版本的JBOSSJBOSS、内置tomcat都在一个容器;(2)、JBOSS的服务都是以JMXMBean服务形式提供),那么可以如下方式管理目的地

MBeanServer server = (MBeanServer)

MBeanServerFactory.findMBeanServer(null).iterator().next();

server.invoke(new ObjectName("JBossMQ", "service", "DestinationManager"),

method,

new Object[] {myTopic },

new String[] { "java.lang.String" });

而可能因为版本的不同,默认的DestinationManager服务域名有差异,应该改为boss.mq否则一直抛出DestinationManager服务未注册的异常。这时候可以通过登入URLhttp://localhost:8080/jmx-console/HtmlAdaptor来查看DestinationManager服务的基本属性来了解具体的域名(可以查看JBOSS的所有服务及相关信息)

2、同样在“如何来管理目的”部分,果代码调用部分和JMXBean服务器在不再一个JVM,那么可以通过一个JMX adapter。一个JMX adapter是一个HTML GUI。用程序通过URL来调用Mbean。但是由于代码中的直接发http请求通过来进行操作,而JBOSS提供的web形式管理方式默认有口令(admin/admin),因此执行这段代码的时候一直异常“java.io.IOException: Server returned HTTP response code:……”这时候将异常中的url直接在已经登入过的浏览器中输入执行,目的却能成功创建。

3、果代码调用部分和JMXBean服务器在不再一个JVM可以如下方式操作JMS的目的地

private static void invokeViaMBeanInDiffJVM(String method, String destName){
        try {
            Context context;
            Hashtable <String, String> jndi = new Hashtable <String, String>();
            jndi.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            jndi.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            jndi.put(Context.PROVIDER_URL, "localhost:1099");

            context = new InitialContext(jndi);
            MBeanServerConnection server = (MBeanServerConnection) context.lookup("jmx/invoker/RMIAdaptor");
            server.invoke(new ObjectName("jboss.mq:service=DestinationManager"),
                            method,
                          new Object[] {destName, "topic/" + destName},
                          new String[] {"java.lang.String", "java.lang.String"});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


2.        DIY例子

使用JMS不仅能发送(send)/发布(publish)消息,也能获得(receive)/订阅(subscribe)的消息,消息的发送(send)/发布(publish)和(receive)/订阅(subscribe)和JBOSS的相对位置是无关的,这个在实际应用中非常有用。在C/S架构的软件中,一般S端部署了JBOSS,作为JMS的publisher,而C端一般是Java程序,作为JMS的subscriber。这里以topic的形式举例说明,注:下面以可序列化的Map作为消息传输载体。

 

import org.martin.common.communication.jms.JmsService;
import org.martin.common.communication.jms.JmsServiceImpl;

public class ServiceAccess
{
    public static JmsService  getJMSService(){
        return new JmsServiceImpl();
    }
}
package org.martin.common.communication.jms;
public class Constants
{
    public static final int DEST_TYPE_TOPIC=1;
    public static final int DEST_TYPE_QUEUE=2;
    public static final int DEST_OPER_ADD=1;
    public static final int DEST_OPER_DELETE=2;
}
public class JmsAsyncReceiver
{

    private TopicConnection topicConnection;
    private TopicSession    topicSession;
    private TopicSubscriber topicSubscriber;
    private Topic           topic;
    
    @SuppressWarnings("unchecked")
    public JmsAsyncReceiver(String factoryJNDI, String topicJNDI,
         MessageListener messagelistener) throws JMSException,NamingException
    {
        Hashtable props = new Hashtable();
        props.put(Context.INITIAL_CONTEXT_FACTORY,
                        "org.jnp.interfaces.NamingContextFactory");
        props.put(Context.PROVIDER_URL, "localhost:1099");
        props.put("java.naming.rmi.security.manager", "yes");
        props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");
        Context context = new InitialContext(props);
        TopicConnectionFactory topicFactory = (TopicConnectionFactory)
                                          context.lookup(factoryJNDI);
        topicConnection = topicFactory.createTopicConnection();
        topicSession = topicConnection.createTopicSession(false,
                                             Session.AUTO_ACKNOWLEDGE);
        topic = (Topic) context.lookup(topicJNDI);
        topicSubscriber = topicSession.createSubscriber(topic);
        topicSubscriber.setMessageListener(messagelistener);
        System.out.println("AsyncReceiver subscribed to topic: " + topicJNDI);
        topicConnection.start();
    }
    
    public void close() throws JMSException
    {
        topicSession.close();
        topicConnection.close();
    }
}
public class JmsHelper
{
    public static void addDestination(String destName){
        try{
            invokeViaMBean("createTopic", destName);
        }catch(Exception e){
            //e.printStackTrace();
            try{
                invokeViaMBeanInDiffJVM("createTopic",  destName);
            }catch(Exception e1){
                //e1.printStackTrace();
            }
        }
    }
    
    private static void invokeViaMBean(String method, String destName) throws Exception
    {
        MBeanServer server = (MBeanServer) MBeanServerFactory.findMBeanServer(null)
                        .iterator().next();
        server.invoke(new ObjectName("jboss.mq", "service", "DestinationManager"), method,
                        new Object[] { destName }, new String[] { "java.lang.String" });
    }
    
    private static void invokeViaMBeanInDiffJVM(String method, String destName)throws Exception{
        Context context;
        Hashtable <String, String> jndi = new Hashtable <String, String>();
        jndi.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        jndi.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
        jndi.put(Context.PROVIDER_URL, "localhost:1099");

        context = new InitialContext(jndi);
        MBeanServerConnection server = (MBeanServerConnection) context.lookup("jmx/invoker/RMIAdaptor");
        server.invoke(new ObjectName("jboss.mq:service=DestinationManager"),
                        method,
                      new Object[] {destName, "topic/" + destName},
                      new String[] {"java.lang.String", "java.lang.String"});
    }
}
public interface JmsReceiveListener
{
    void onMessage(Object msg);
}
public class JmsReceiveScheduler implements MessageListener
{
    private JmsAsyncReceiver regInfo;
    private ConcurrentHashMap<String, JmsReceiveListener> listenerMap 
                = new ConcurrentHashMap<String, JmsReceiveListener>();
    private String destination=null;
    
    public JmsReceiveScheduler(String destination) 
    throws JMSException, NamingException
    {
        this.destination=destination;
        JmsService service=ServiceAccess.getJMSService();
        regInfo = service.registAsyncReceive(Constants.DEST_TYPE_TOPIC, 
                        this.destination, this);
    }
    
    public  void registerListener(String clientID, JmsReceiveListener listener)
    {
        listenerMap.put(clientID, listener);
    }
    
    public  void unregisterListener(String id)
    {
        listenerMap.remove(id);
    }
    
    public  void close() throws JMSException
    {
        regInfo.close();
    }

    @SuppressWarnings("unchecked")
    public void onMessage(Message msgIn)
    {
        ObjectMessage objMsg = (ObjectMessage) msgIn;
        Map map=null;
        try{
            map = (HashMap) objMsg.getObject();
        }catch(JMSException e){
            e.printStackTrace();
        }
        String clientID = (String) map.get("CLIENT_ID");
        JmsReceiveListener listener = listenerMap.get(clientID);
        if(listener != null)
        {
            listener.onMessage(map.get("DATA"));
        }
    }
}
public class JmsSender
{
    private TopicConnection topicConnection;
    private TopicSession    topicSession;
    private TopicPublisher  topicPublisher;
    private Topic           topic;
    
    @SuppressWarnings("unchecked")
    public JmsSender(String factoryJNDI, String topicJNDI) 
           throws JMSException,NamingException
    {
        Hashtable props = new Hashtable();
        props.put(Context.INITIAL_CONTEXT_FACTORY,
                        "org.jnp.interfaces.NamingContextFactory");
        props.put(Context.PROVIDER_URL, "localhost:1099");
        props.put("java.naming.rmi.security.manager", "yes");
        props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");
        Context context = new InitialContext(props);
        TopicConnectionFactory topicFactory = (TopicConnectionFactory) context
                        .lookup(factoryJNDI);
        topicConnection = topicFactory.createTopicConnection();
        topicSession = topicConnection
                        .createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        
        topic = (Topic) context.lookup(topicJNDI);
        topicPublisher = topicSession.createPublisher(topic);
        
    }
    
    @SuppressWarnings("unchecked")
    public void publish(Map msg) throws JMSException
    {
        ObjectMessage  message = topicSession.createObjectMessage();
        message.setObject((Serializable) msg);
        topicPublisher.publish(topic, message); 
    }
    
    public void close() throws JMSException
    {
        topicSession.close();
        topicConnection.close();
    }

}
public class JmsSenderWrapped
{

    private static JmsSender sender;

    public JmsSenderWrapped(String destination) 
    throws JMSException, NamingException{
        JmsService  jmsService = ServiceAccess.getJMSService();
        sender = jmsService.getSender(Constants.DEST_TYPE_TOPIC, destination);
    }

    @SuppressWarnings("unchecked")
    public  void sendJMSMessage(String clientID, Serializable dataIn) 
    throws JMSException
    {
        Map map = new HashMap();
        map.put("CLIENT_ID", clientID);
        map.put("DATA", dataIn);
        sender.publish( map);
    }
    
    public void close() throws JMSException{
        sender.close();
    }
}
public interface JmsService
{
    JmsAsyncReceiver registAsyncReceive(int destType,String destination,
       MessageListener listener) throws JMSException, NamingException;

    JmsSender getSender(int destType, String destination) throws JMSException, 
    NamingException;
    
    public void operDestination(int operType,int destType, String destination);
}
public class JmsServiceImpl implements JmsService
{
    public JmsAsyncReceiver registAsyncReceive(int destType, String destination,
    MessageListener listener) throws JMSException, NamingException
    {
        if(destType==Constants.DEST_TYPE_TOPIC){
            JmsAsyncReceiver receivere = new JmsAsyncReceiver
            ("TopicConnectionFactory","topic/"+destination, listener);
            return receivere;
        }else if(destType==Constants.DEST_TYPE_QUEUE){
            
        }
        return null;
    }

    public JmsSender getSender(int destType, String destination) 
    throws JMSException, NamingException
    {
        if(destType==Constants.DEST_TYPE_TOPIC){
            JmsSender sender=new JmsSender
            ( "ConnectionFactory",  "topic/"+destination);
            return sender;
        }
        return null;
    }

    public void operDestination(int operType,int destType, String destination)
    {
        if(destType==Constants.DEST_TYPE_TOPIC){
            if(operType==Constants.DEST_OPER_ADD){
                JmsHelper.addDestination(destination);
            }
        }
        
    }  
    
}
public class ReceiveTest
{
    public static void main(String[]args){
        String destName="MyTestDestination";
        String clientName="MyTClientName";
        JmsService service=ServiceAccess.getJMSService();
        service.operDestination(Constants.DEST_OPER_ADD,
                        Constants.DEST_TYPE_TOPIC, destName);
        
        JmsReceiveScheduler schedul=null;
        try{
            schedul=new JmsReceiveScheduler(destName);
        }catch(JMSException e){
            e.printStackTrace();
        }catch(NamingException e){
            e.printStackTrace();
        }
        schedul.registerListener(clientName, new JmsReceiveListener(){

            public void onMessage(Object msg)
            {
                System.out.println(msg);
            } 
        });
    }
}
public class SendTest
{
    public static void main(String[]args){
        String destName="MyTestDestination";
        String clientName="MyTClientName";
        JmsService service=ServiceAccess.getJMSService();
        service.operDestination(Constants.DEST_OPER_ADD,
                        Constants.DEST_TYPE_TOPIC, destName);
        
        JmsSenderWrapped send=null;
        try{
            send=new JmsSenderWrapped(destName);
        }catch(JMSException e){
            e.printStackTrace();
        }catch(NamingException e){
            e.printStackTrace();
        }
        for(int i=0;i<10;i++){
            try{
                send.sendJMSMessage(clientName, "count:"+i);
            }catch(JMSException e){
                e.printStackTrace();
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值