我要求将加密文件(文件大小可达100 M.B)发布到jms队列。与文件一起,我必须将解密密钥发送到jms侦听器用于解密文件的相同消息。
我已经附加了applicationContext.xml和jms发布者。目前我尝试使用MapMessage发布文件和密钥,但收到以下错误。
2015-12-09 19:31:12,709 INFO [simBatchQueueListener-1] - Received a message for updating organization
2015-12-09 19:31:12,719 DEBUG [simBatchQueueListener-1] - Received a JMS message: Key ->null
2015-12-09 19:31:12,729 DEBUG [simBatchQueueListener-1] - Received a JMS message: File ->null
2015-12-09 19:31:12,729 DEBUG [simBatchQueueListener-1] - Received a JMS message: bytesMessage ->null
weblogic.jms.common.MessageFormatException: [JMSClientExceptions:055130]Invalid data type: java.io.BufferedWriter
at weblogic.jms.common.MapMessageImpl.setObject(MapMessageImpl.java:234)
at com.vodafone.m2m.kssv.jms.JMSNotifier$1.createMessage(JMSNotifier.java:113)
at com.vodafone.m2m.kssv.jms.JMSNotifier$1.createMessage(JMSNotifier.java:106)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:602)
at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:583)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:493)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:579)
at com.vodafone.m2m.kssv.jms.JMSNotifier.publishMessage(JMSNotifier.java:106)
at com.vodafone.m2m.kssv.directoryscanner.file.SIMBatchReturnFileProcessor.run(SIMBatchReturnFileProcessor.java:88)
at java.lang.Thread.run(Thread.java:744)
jms发布应该是同步的。从队列中读取消息后,将创建一个ID,并且需要向发布者确认ID。
由于我是编码jms的新手,任何人都可以帮助我如何实现这一目标。
public class JMSNotifier {
private final Logger LOG = LoggerFactory.getLogger(JMSNotifier.class);
private static final String myName = JMSNotifier.class.getSimpleName();
private String filename = null;
private FileInputStream inStream = null;
private BytesMessage bytesMessage = null;
private int bytes_read = 0;
private int BUFLEN = 64;
private byte[] buf1 = new byte[BUFLEN];
private byte[] buf2 = new byte[BUFLEN];
private int length = 0;
private int exitResult = 0;
@Autowired
private JmsTemplate jmsTemplate;
private String simBatchQueue;
private MapMessage m = null;
@Required
public void setSimBatchQueue(String simBatchQueue) {
this.simBatchQueue = simBatchQueue;
}
public synchronized void publishMessage(String destinationName, String msg) throws JMSException {
LOG.debug("Sending message {} on {} queue...", msg.toString(), destinationName);
try {
filename = new String("C:\\Vijay\\cleartext.txt");
inStream = new FileInputStream(filename);
} catch (IOException e) {
System.out.println("Problem getting file: " + e.toString());
System.exit(1);
}
if (Constants.SIM_BATCH_QUEUE.equals(destinationName)) {
destinationName = simBatchQueue;
LOG.trace("{}: Attempting messgage for D_N_SIM_BATCH_QUEUE {} ", myName, simBatchQueue);
} else {
LOG.trace("{}: Unknow JMS destinaion name {} ", myName, destinationName);
throw new JMSException("Unknow JMS destinaion name {}" + destinationName);
}
jmsTemplate.send(destinationName, new MessageCreator() {
@Override
public MapMessage createMessage(Session session) throws JMSException {
try {
m = session.createMapMessage();
m.setObject("file", writeToFile(inStream));
m.setObject("key","123");
return m;
} catch (Exception ex) {
ex.printStackTrace();
return m;
}
}
});
}
public static String prepareNormalDateString() {
Calendar tzCal = Calendar.getInstance();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-ddhhmmss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
StringBuffer date = new StringBuffer(dateFormat.format(tzCal.getTime()));
date.append("UTC");
return (date.toString());
}
private BufferedWriter writeToFile(InputStream is) {
BufferedReader br = null;
String time = prepareNormalDateString();
String filepath = "C:\\vijay\\File" + time + ".csv";
String line;
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new FileWriter(filepath));
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
bufferedWriter.write(line);
}
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bufferedWriter;
}
}
公共类SimBatchQueueMessageHandler实现MessageListener {
private static org.slf4j.Logger myLogger = LoggerFactory.getLogger(SimBatchQueueMessageHandler.class);
private String myName = SimBatchQueueMessageHandler.class.getSimpleName();
int bytes_read = 0;
final int BUFLEN = 64;
byte[] buf1 = new byte[BUFLEN];
byte[] buf2 = new byte[BUFLEN];
int length = 0;
int exitResult = 0;
FileOutputStream fos = null;
File newFile = null;
private static int count = 1;
@Override
public synchronized void onMessage(Message message) {
try {
myLogger.info("Received a message for updating organization");
Source source;
count = count + 1;
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
source = new StringSource(textMessage.getText());
myLogger.debug("Text Message received {}", textMessage.getText());
} else if (message instanceof MapMessage) {
MapMessage msg = (MapMessage) message;
myLogger.debug("Received a JMS message: Key ->" + msg.getObject("key"));
myLogger.debug("Received a JMS message: File ->" + msg.getObject("file"));
Object bytesMessage = msg.getObject("file");
myLogger.debug("Received a JMS message: bytesMessage ->" + bytesMessage);
} else if (message instanceof BytesMessage) {
else {
throw new MessageConversionException("Unsupported JMS Message type " + message.getClass() + ", expected instance of TextMessage or BytesMessage for " + message);
}
Object[] params = new Object[]{myName};
} catch (JMSException jmsEx) {
myLogger.error("Error occured while publishing" + jmsEx);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://jax-ws.dev.java.net/spring/core
http://jax-ws.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.java.net/spring/servlet.xsd">
<!--
Activates various annotations to be detected in bean classes:
Spring's @Required and @Autowired, as well as JSR 250's @Resource.
-->
<context:annotation-config/>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>file:///${MYCOMPONENT_CONFIG_PATH}/log4j.properties</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="searchSystemEnvironment" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>file:///${MYCOMPONENT_CONFIG_PATH}/jdbc.properties</value>
<!--<value>file:///${MYCOMPONENT_CONFIG_PATH}/MYCOMPONENTConfig.xml</value>-->
<value>file:///${MYCOMPONENT_CONFIG_PATH}/MYCOMPONENT.properties</value>
</list>
</property>
</bean>
<!--
Uses Apache Commons DBCP for connection pooling. See Commons DBCP documentation
for the required JAR files. Alternatively you can use another connection pool
such as C3P0, similarly configured using Spring.
-->
<!-- USE FOR GLASSFISH DATABASE POOLING
<bean id="dataSourceMYCOMPONENT" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${MYCOMPONENT.jdbc.dataSource}"/>
</bean>-->
<!-- USE FOR SPRING DATABASE POOLING -->
<bean id="dataSourceMYCOMPONENT" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}"
p:password="${jdbc.password}" >
<property name="defaultAutoCommit" value="false"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
<property name="minIdle" value="2"/>
<property name="initialSize" value="1"/>
<property name="maxWait" value="500"/>
<property name="testOnBorrow" value ="true"/>
<property name="timeBetweenEvictionRunsMillis" value ="1800000"/>
<property name="minEvictableIdleTimeMillis" value ="300000"/>
</bean>
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
<property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
</bean>
<bean id="dao" class="com.mycompany.m2m.MYCOMPONENT.support.dataaccess.jdbc.JdbcDataAccessObject">
<!-- Must set schemaName before dataSource! -->
<property name="schemaName" value="${jdbc.schema}"/>
<property name="dbUser" value="${jdbc.username}"/>
<property name="dataSource" ref="dataSourceMYCOMPONENT"/>
</bean>
<!-- Ends -->
<!-- USE FOR JMS CONFIGURATION ************************* -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="jndiName" value="${MYCOMPONENT.jms.connectionFactory}" />
</bean>
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">${MYCOMPONENT.jndi.initialFactory}</prop>
<prop key="java.naming.provider.url">${MYCOMPONENT.jndi.providerUrl}</prop>
</props>
</property>
</bean>
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="cache" value="true" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestination" ref="simBatchQueue" />
<property name="destinationResolver" ref="jmsDestinationResolver" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="sessionAcknowledgeModeName" value="AUTO_ACKNOWLEDGE" />
<property name="sessionTransacted" value="false" />
</bean>
<bean id="jmsNotifier" class="com.mycompany.m2m.MYCOMPONENT.jms.JMSNotifier">
<property name="simBatchQueue" value="${MYCOMPONENT.jms.simBatchQueue}" />
</bean>
<!-- JMS Message Listener to handle messages from MYCOMPONENT-->
<bean id="simBatchQueueMessageListener" class="com.mycompany.m2m.MYCOMPONENT.jms.listener.SimBatchQueueMessageHandler"/>
<bean id="simBatchQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="jndiName" value="${MYCOMPONENT.jms.simBatchQueue}" />
</bean>
<bean id="simBatchQueueListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="simBatchQueue" />
<property name="messageListener" ref="simBatchQueueMessageListener" />
<property name="pubSubDomain" value="true"/>
<property name="subscriptionDurable" value="false"/>
<!--<property name="durableSubscriptionName" value="${sasm.jms.orgDurableSubName}"/>-->
</bean>
</beans>