JAVA 编写 IBM MQ Client SSL双向通信

因为工作需要使用到IBM MQ ,但是大家都知道IBM MQ购买是很贵的,所以打算直接java编写一个IBM MQ Client去和对方连接。因为自己没有了解过这个,所以想先从IBM的官网下载一个IBM MQ去简单连接测试一下,有兴趣的朋友可以自己去查询一下怎么安装下载,因为已经有很多帖子说明,在此不做介绍,简单附上下载地址

https://developer.ibm.com/messaging/mq-downloads/

这里主要说明一下怎么使用java 编写IBM MQ Client SSL双向通信

准备IBM_JAVA_SDK

需要的朋友可以去下面的地址下载,解压即可用

https://download.csdn.net/download/qq_26182739/10424618

了解 MQSeries classes for Java 编程,附上中文pdf文档说明,简单易懂

https://download.csdn.net/download/qq_26182739/10424746

前面准备做好后,开始上主要代码

//初始化消息工厂,connect()方法在下方,只贴出部分方法主要代码
SSLContext ctx = connect();
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "true");
try {
    //MQ队列管理器设置
    mqConnectionFactory.setHostName("127.0.0.1");
    mqConnectionFactory.setPort(1414);
    mqConnectionFactory.setQueueManager("QM.TEST.CLIENT.FPE001");
    mqConnectionFactory.setChannel("test.01.TO.client.n");//通道名称
    mqConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
    mqConnectionFactory.setCCSID(1381);
    //SSL相关配置
    mqConnectionFactory.setSSLFipsRequired(true);
    mqConnectionFactory.setSSLSocketFactory(ctx.getSocketFactory());
    //TLS_RSA_WITH_AES_256_CBC_SHA256对应通道的 ssl Cipher Spec 的值                  
    mqConnectionFactory.setSSLCipherSuite(JmqiUtils.toCipherSuite("TLS_RSA_WITH_AES_256_CBC_SHA256"));
    //SSLPeerName请根据提供的证书信息填写,如果异常会提示正确的SSLPeerName
    mqConnectionFactory.setSSLPeerName("CN=test.mq.client.cn, OU=CLIENT, O=MQ TEST, C=CN");
    //连接方式为client
    mqConnectionFactory.setMessageSelection(WMQConstants.WMQ_MSEL_CLIENT);
    mqConnectionFactory.setMQConnectionOptions(WMQConstants.WMQ_CM_CLIENT);
    logger.info("start create connection...");
    //如果连接的时候,弹出检查是否支持该用户名、密码,请在此处设置相应的用户名,密码
    connection = mqConnectionFactory.createConnection("username","password");
    logger.info("finish create connection...");
    connection.start();
    logger.info("connection start...");
    //自动通知
    //对于同步消费者,Receive方法调用返回,且没有异常发生时,将自动对收到的消息予以确认.
    //对于异步消息,当onMessage方法返回,且没有异常发生时,即对收到的消息自动确认
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
} catch (JMSException e) {
    e.printStackTrace();
    logger.error("fail connection:"+e.getMessage(),e);
    init = false;
}

创建SSL 双向连接方法的内容

怎么创建密钥以及密钥库,请自行搜索,可以直接使用 keytool


keytool是jdk自带的一款ssl管理工具,使用方法请参考下面这篇博客,在此不做介绍

https://blog.csdn.net/fengwind1/article/details/52191520

/** 
 * @Title:MqApplication
 * @Description:创建SSL双向连接
 * @return 
 */ 
public static SSLContext connect() {
    SSLContext ctx = null;
    try {
        ctx = SSLContext.getInstance("TLSv1.2");
        SSLContext.setDefault(ctx);
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("IBMX509");
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("IBMX509");
        KeyStore ks = KeyStore.getInstance("JKS");
        KeyStore tks = KeyStore.getInstance("JKS");
        String selfPasswd = "pass";
        
        //客户端私钥文件、根证书、由CA签发的证书客户端证书
        ks.load(new FileInputStream(CommonUtils.appHome()+"keyStore"+System.getProperty("file.separator")+"keyStore.jks"), selfPasswd.toCharArray());
        //服务端公钥文件
        tks.load(new FileInputStream(CommonUtils.appHome()+"keyStore"+System.getProperty("file.separator")+"trustStore.jks"), selfPasswd.toCharArray());

        kmf.init(ks, selfPasswd.toCharArray());
        tmf.init(tks);
        TrustManager[] tm = tmf.getTrustManagers();
        final X509TrustManager[] x509tm = Arrays.asList(tm).toArray(new X509TrustManager[tm.length]);
        X509TrustManager[] x509tmArray = new X509TrustManager[] {
                new X509TrustManager() {
                    
                    /* (non Javadoc) 
                     * @Title: getAcceptedIssuers
                     * @Description:  返回受身份验证同位体信任的认证中心的数组
                     * @return 
                     * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() 
                     */ 
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return x509tm[0].getAcceptedIssuers();
                    }
                    
                    /* (non Javadoc) 
                     * @Title: checkClientTrusted
                     * @Description: 给出同位体提供的部分或完整的证书链,构建到可任的根的证书路径,并且返回是否可以确认和信任将其用于基于身份验证类型的客户端 SSL 身份验证
                     * @param chain
                     * @param authType
                     * @throws CertificateException 
                     * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String) 
                     */ 
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType){
                        for(int i=0;i<chain.length;i++) {
                            logger.info("-------------------Check client cert"+i+"/"+authType+"---------------------");
                        }
                        try {
                            x509tm[0].checkClientTrusted(chain, authType);
                        } catch (CertificateException e) {
                            logger.error("Check client Cert Exception:"+e.getMessage(),e);
                        }
                    }
                    
                    /* (non Javadoc) 
                     * @Title: checkServerTrusted
                     * @Description: 给出同位体提供的部分或完整的证书链,构建到可任的根的证书路径,并且返回是否可以确认和信任将其用于基于身份验证类型的服务器 SSL 身份验证
                     * @param chain 证书链
                     * @param authType 使用的密钥交换算法 RSAwith256
                     * @throws CertificateException 此证书链不受trustManager信任
                     * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String) 
                     */ 
                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType){
                        for(int i=0;i<chain.length;i++) {
                            logger.info("-------------------Check server cert"+i+"/"+authType+"---------------------");
                        }
                        try {
                            x509tm[0].checkServerTrusted(chain, authType);
                            logger.info("finish check server cert");
                        } catch (CertificateException e) { 
                            logger.error("Check server Cert Exception:"+e.getMessage(),e);
                            e.printStackTrace();
                        }
                    }
                }
        };            
        ctx.init(kmf.getKeyManagers(), x509tmArray, null);
        //返回支持的加密套件
//        logger.info("Support CipherSuites:"+Arrays.asList(en.getSupportedCipherSuites()));
        //返回启用的加密套件
//        logger.info("Used CipherSuites:"+Arrays.asList(en.getEnabledCipherSuites()));
    } catch (Exception e) {
        e.printStackTrace();
        logger.error("create ssl connection failer:"+e.getMessage(),e);
    }
    return ctx;
}

发送消息

public class JmsProducer {
    private Log logger = LogFactory.getLog(getClass());
    Connection connection = null;
    Destination destination = null;
    MessageProducer producer = null;
    Session session = null;
    String line = null;
    private static int status = 1;
    
    public void JmsProducer() {
        
    }

    public void sendMsg() {
        try {
            session = MqApplication.session;
            //队列名称从配置文件读取 创建队列 client.TO.server.N                        
            destination = session.createQueue(ConfigUtils.getConfig("mqManage/mq/outQueue"));//
            //在jms会话中创建一个消息的生产者
            producer = session.createProducer(destination);
            //开始连接
            logger.info("start read file msg...");
            //读取文件信息
            File file = new File(CommonUtils.appHome()+"keyStore"+System.getProperty("file.separator")+"message.xml");
            BufferedReader in = new BufferedReader(new FileReader(file));
              do {
                line = in.readLine();
                if (line!=null){
                  if(line.trim().length()==0){
                    break;
                  }
                   TextMessage message = session.createTextMessage(line);
                   //传递信息
                   producer.send(message);
                   logger.info("send msg:\n"+message);
                  }
                }
              while (line != null);
              recordSuccess();
        } catch (Exception e) {
            logger.error("send msg wrong"+e.getMessage(),e);
            status = -1;
        } finally {
            if (producer != null) {
                try {
                  producer.close();
                }
                catch (JMSException jmsex) {
                  logger.error("Producer could not be closed.");
                }
              }

              if (session != null) {
                try {
                  session.close();
                }
                catch (JMSException jmsex) {
                  logger.error("Session could not be closed.");
                }
              }

              if (connection != null) {
                try {
                  connection.close();
                }
                catch (JMSException jmsex) {
                    System.exit(status);
                    return;
                }
              }
        
        }

    }
    
    private void recordSuccess() {
        logger.info("SUCCESS");
        status = 0;
        return;
    }
}

接收消息

public class JmsConsumer {
    private Log logger = LogFactory.getLog(getClass());
    Connection connection = null;
    Destination destination = null;
    MessageConsumer consumer = null;
    Session session = null;
    String line = null;
    private static int timeout = 15000;
    private static int status = 1;
    
    public void JmsConsumer() {
        
    }

    public void receiveMsg() {
        try {
            session = MqApplication.session;
            //队列名称从配置文件读取 创建队列 server.TO.client.N
            destination = session.createQueue(ConfigUtils.getConfig("mqManage/mq/inQueue"));
            //在jms会话中创建一个消息的消费者
            consumer = session.createConsumer(destination);
            //开始连接
            logger.info("start receive msg...");
            //接收消息
            Message message;
            do {
                message = consumer.receive(timeout);
                if (message != null) {
                  logger.info("receive msg:\n"+message);
                }
            }
            while (message != null);
            recordSuccess();
        } catch (Exception e) {
            logger.error("read msg wrong"+e.getMessage());
            status = -1;
        } finally {
            if (consumer != null) {
                try {
                    consumer.close();
                }
                catch (JMSException jmsex) {
                  logger.error("consumer could not be closed.");
                }
              }

              if (session != null) {
                try {
                  session.close();
                }
                catch (JMSException jmsex) {
                  logger.error("Session could not be closed.");
                }
              }

              if (connection != null) {
                try {
                  connection.close();
                }
                catch (JMSException jmsex) {
                    System.exit(status);
                    return;
                }
              }
        
        }

    }
    
    private void recordSuccess() {
        logger.info("SUCCESS");
        status = 0;
        return;
    }
}
这里只贴出部分主要代码,有问题请私信


猜你喜欢

转载自blog.csdn.net/qq_26182739/article/details/80375190
今日推荐