JMS的Spring配置(WebSphereMQ-SSL、Tomcat、JNDI、非IBMJRE)
背景: 我有一个相对较旧的应用程序,它使用WebSphereMQ进行消息传递。它运行在WAS(WebSphereApplicationServer)上,并使用MDB(消息驱动bean)。我成功地使用替换了所有MDB。我的下一步是尝试看看是否可以将它从WAS中移植出来,以便它可以在任何其他具有非IBMJRE的servlet容器上运行(我正在尝试:ApacheTomcat)。请注意,使用SSL保护通道是一项要求。我更喜欢使用JNDI 最终目标: 将我的应用程序与应用程序服务器(WAS)和其他基础结构(如消息传递(MQ))分离。但是把这个从WAS中带到tomcat上是第一步。接下来的任务是用更具可伸缩性的东西更新我的消息传递基础结构。这使我能够一次更新应用程序所依赖的基础设施的各个组件(应用程序服务器、消息传递层、数据存储),而不会在运行过程中过度中断应用程序 问题: 现在,我的挑战是在tomcat上定义可以访问WebSphereMQ的JNDI资源。我使用在context.xml文件中定义的非SSL通道在这方面取得了一些进展,如下所示:JMS的Spring配置(WebSphereMQ-SSL、Tomcat、JNDI、非IBMJRE),spring,tomcat,jms,jndi,ibm-mq,Spring,Tomcat,Jms,Jndi,Ibm Mq,背景: 我有一个相对较旧的应用程序,它使用WebSphereMQ进行消息传递。它运行在WAS(WebSphereApplicationServer)上,并使用MDB(消息驱动bean)。我成功地使用替换了所有MDB。我的下一步是尝试看看是否可以将它从WAS中移植出来,以便它可以在任何其他具有非IBMJRE的servlet容器上运行(我正在尝试:ApacheTomcat)。请注意,使用SSL保护通道是一项要求。我更喜欢使用JNDI 最终目标: 将我的应用程序与应用程序服务器(WAS)和其他基础结构
我的下一步是让它与SSL通道一起工作。我理解涉及设置密钥库(kdb文件和证书生成和交换)、配置QM上的SSL通道等的部分。我已经完成了所有这些工作。如何让tomcat使用我的密钥库、密码套件等?指针或工作示例将是伟大的
注意:我目前正在使用SpringIntegration4.2、WebSphereMQV8和TomcatV9
我必须补充一点,没有JNDI我什么都试过了。下面是我的spring jms非ssl配置,没有JNDI,它可以工作:
QM_沙箱
沙箱
我想我终于找到了解决办法。。。以下是这些步骤的简要说明。如果你需要更多的细节,请告诉我
预需求:
已安装Websphere MQ服务器(至少版本8.0.0.2)
配置QM、SSL和非SSL通道,创建Qs和所有您需要的好东西。
不用说,您需要WebSphereMQJAR。请注意任何许可限制
步骤1:让直接连接在没有SSL、没有JNDI的情况下工作。您将需要使用这些bean来配置基于spring的JMS侦听器和JMS模板等
<bean id="mq-jms-cf-sandbox"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref bean="mqQueueConnectionFactory" />
</property>
</bean>
<bean id="mqQueueConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName" value="localhost" />
<property name="port" value="1414" />
<property name="queueManager" value="QM_SANDBOX" />
<property name="transportType" value="1" />
<property name="channel" value="NON_SSL_CHANNEL" />
</bean>
<bean id="jms-destination-sandbox" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="SANDBOX_Q" />
<property name="baseQueueManagerName">
<value>QM_SANDBOX</value>
</property>
<property name="baseQueueName">
<value>SANDBOX_Q</value>
</property>
</bean>
2d。使用以下命令启动tomcat:
catalina.bat run > ..\logs\tomcat.log 2>&1
要停止,只需按ctrl+c(在windows上)。无论采用哪种方式,请确保在启动期间使用setenv.bat。或者使用JAVA_选项设置密钥库属性
2e。验证使用SSL通道的方法是否有效
步骤3:获取一个使用非SSL、JNDI的JNDI连接
在tomcat上设置JNDI的方法有很多。我是这样做的:在web应用程序中创建一个包含以下内容的META-INF/Context.xml文件:
<Resource
name="jms/qcf_sandbox"
auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory"
factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description="JMS Queue Connection Factory for sending messages"
HOST="localhost"
PORT="1414"
CHAN="NON_SSL_CHANNEL"
TRAN="1"
QMGR="QM_SANDBOX"/>
<Resource
name="jms/SandboxQ"
auth="Container"
type="com.ibm.mq.jms.MQQueue"
factory="com.ibm.mq.jms.MQQueueFactory"
description="JMS Queue"
QU="SANDBOX_Q"/>
<Resource
name="jms/qcf_sandbox"
auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory"
factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description="JMS Queue Connection Factory for sending messages"
HOST="localhost"
PORT="1414"
CHAN="SSL_CHANNEL"
TRAN="1"
QMGR="QM_SANDBOX"
SCPHS="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"/>
<Resource
name="jms/SandboxQ"
auth="Container"
type="com.ibm.mq.jms.MQQueue"
factory="com.ibm.mq.jms.MQQueueFactory"
description="JMS Queue"
QU="SANDBOX_Q"/>
或者,如果您使用的是spring集成,则可以执行如下操作,而不是步骤3:
<int:channel id="jms-inbound"/>
<int-jms:message-driven-channel-adapter
id="jms-inbound-adapter" container="jmsContainer" channel="jms-inbound"
extract-payload="true" acknowledge="transacted"
message-converter="messagingMessageConverter" />
<beans:bean id="messagingMessageConverter" class="org.springframework.jms.support.converter.MessagingMessageConverter">
</beans:bean>
详细说明+1.您在哪里配置步骤1?文件名,在spring-beans.xml或其他文件中,以及如何读取它。它是配置spring-beans的xml文件(也可以分解为多个文件)。只需确保在web.xml中提到@code4kix(如果根据命名约定,默认情况下无法获取它),就可以获取它。我只是尝试从WAS7迁移到WAS8.5,并删除所有EJB和MDB。我已经成功地完成了EJB到Spring4的注入和ComponentContext,现在我只能在代码中使用一个MDB。我使用ActiveSpec阅读was。你能帮助我如何在was 8.5中迁移它吗?我的建议是完全删除MDB和active spec。在服务器上,你所需要的只是qm连接工厂和q连接工厂。在应用程序上,只使用消息驱动的POJO(而不是MDB)。我相信如果你搜索,肯定会有一些例子。如果你真的找不到,可以在stackoverflow中再问一个问题。如果没有其他人能做到的话,我会尽力做到的。
<jee:jndi-lookup id="mq-jms-cf-sandbox" jndi-name="java:/comp/env/jms/qcf_sandbox" resource-ref="false" />
<jee:jndi-lookup id="jms-destination-sandbox" jndi-name="java:/comp/env/jms/SandboxQ" resource-ref="false" />
<Resource
name="jms/qcf_sandbox"
auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory"
factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description="JMS Queue Connection Factory for sending messages"
HOST="localhost"
PORT="1414"
CHAN="SSL_CHANNEL"
TRAN="1"
QMGR="QM_SANDBOX"
SCPHS="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"/>
<Resource
name="jms/SandboxQ"
auth="Container"
type="com.ibm.mq.jms.MQQueue"
factory="com.ibm.mq.jms.MQQueueFactory"
description="JMS Queue"
QU="SANDBOX_Q"/>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<!-- this is the Message Driven POJO (MDP) -->
<bean id="messageListener" class="jmsexample.ExampleListener" />
<!-- and this is the message listener container -->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="mq-jms-cf-sandbox"/>
<property name="destination" ref="jms-destination-sandbox"/>
<property name="messageListener" ref="messageListener" />
</bean>
</beans>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context/spring-beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class ExampleListener implements MessageListener {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
System.out.println(((TextMessage) message).getText());
}
catch (JMSException ex) {
throw new RuntimeException(ex);
}
}
else {
throw new IllegalArgumentException("Message must be of type TextMessage");
}
}
}
<int:channel id="jms-inbound"/>
<int-jms:message-driven-channel-adapter
id="jms-inbound-adapter" container="jmsContainer" channel="jms-inbound"
extract-payload="true" acknowledge="transacted"
message-converter="messagingMessageConverter" />
<beans:bean id="messagingMessageConverter" class="org.springframework.jms.support.converter.MessagingMessageConverter">
</beans:bean>