项目中有大量的MQ接口,尤其是进入结合测试以后,有大量的MQ的投入和取出需求。用Webshpere的MQ资源管理器实现太慢,而且手动作业太多了。手动写了两个工具,一个是VBA对固定格式的接口文件,生成MQ接口测试用的XML文件。一个是java写的,针对MQ的批量XML投入和取出生成XML文件的工具。这里介绍第二个,第一个VBA工具有需要的可以留言。
思路:因为只是单纯文件读写,不涉及到XML解析,使用apache的 commons.io进行文件读取和写入;MQ的读写使用javax.jms和ibm.mq.allclient。所以除了jdk1.8的库以外,还需要三个jar包。 com.ibm.mq.allclient.jar,commons-io-2.6.jar,javax.jms-api-2.0.1.jar。
代码实现:MQCommon.java
public static ResourceBundle createResourceBundle() {
// JMS setting file (mq.properties)
ResourceBundle bundle = ResourceBundle.getBundle(JMS_PROPERTIES);
return bundle;
}
public static MQQueueConnectionFactory createMQQueueConnectionFactory(ResourceBundle bundle) throws JMSException {
// Configure QueueConnectionFactory.
MQQueueConnectionFactory factory = new MQQueueConnectionFactory();
factory.setTransportType(com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
factory.setHostName(bundle.getString(JMS_HOST));
factory.setPort(Integer.valueOf(bundle.getString(JMS_PORT)));
factory.setChannel(bundle.getString(JMS_CHANNEL));
return factory;
}
public static QueueConnection createQueueConnection(MQQueueConnectionFactory factory) throws JMSException {
String password = System.getProperty(MQ_Password_KEY, "");
String userId = System.getProperty(MQ_UserID_KEY, MQ_UserID);
System.out.println("user[" + userId + "],password[" + password + "] for connection");
QueueConnection conn = factory.createQueueConnection(userId, password);
return conn;
}
public static QueueSession createQueueSession(QueueConnection conn) throws JMSException {
QueueSession session = conn.createQueueSession(true, QueueSession.AUTO_ACKNOWLEDGE);
return session;
}
public static MQQueue createMQQueue( String queueName) throws JMSException {
MQQueue mqQueue = new MQQueue(queueName);
return mqQueue;
}
MQPut.java
/**
* @param args
* 1st:QueueName(ex.inq001,outq001,errq001..)
* 2nd:MessageFile's Path(Relative path)
*/
public static void main(String[] args) {
int paramLength = args.length;
String queueName = null;
String fileName = null;
String[] paramCheckResult = null;
paramCheckResult = paramCheck(paramLength, args);
queueName = paramCheckResult[0];
fileName = paramCheckResult[1];
MQPut.put( queueName, fileName);
}
public static void put(String queueName, String fileName) {
File file = new File(fileName);
ResourceBundle bundle = null;
MQQueueConnectionFactory factory = null;
MQQueue mqQueue = null;
//clear object
QueueSender sender = null;
QueueSession session = null;
QueueConnection conn = null;
try {
bundle = MQCommon.createResourceBundle();
factory = MQCommon.createMQQueueConnectionFactory(bundle);
conn = MQCommon.createQueueConnection(factory);
session = MQCommon.createQueueSession(conn);
mqQueue = MQCommon.createMQQueue(queueName);
MQCommon.info(factory, mqQueue);
sender = createQueueSender(session, mqQueue);
if (file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
// Read & Send Message.
sendMessage(files[i], session, sender);
}
} else {
// Read & Send Message.
sendMessage(file, session, sender);
}
// mq commit.
session.commit();
System.out.println("Put completed.");
} catch (JMSException | RuntimeException e) {
// mq rollback
} finally {
// close sender session conn
}
}
private static String[] paramCheck(int paramLength, String[] args) {
String[] paramCheckResult = new String[2];
switch (paramLength) {
case 0:
System.out.println("Please Data Input.");
paramCheckResult[0] = ReadInputUtils.readInput("target queueName(ex.inq001,outq001,errq001..): ");
paramCheckResult[1] = ReadInputUtils.readInput("target filepath(Relative path): ");
break;
case 1:
System.out.println("Please Data Input.");
paramCheckResult[0] = args[0];
paramCheckResult[2] = ReadInputUtils.readInput("target filepath(Relative path): ");
break;
default:
paramCheckResult[0] = args[0];
paramCheckResult[1] = args[1];
break;
}
return paramCheckResult;
}
private static QueueSender createQueueSender(QueueSession session, MQQueue mqQueue) throws JMSException {
QueueSender sender = session.createSender(mqQueue);
return sender;
}
private static void sendMessage(File file, QueueSession session, QueueSender sender) {
InputStream inFile = null;
InputStreamReader innerReader = null;
try {
inFile = new FileInputStream(file);
//String message = IOUtils.toString(inFile,"utf-8");
String message = IOUtils.toString(inFile,"utf-8");
// Send Message information.
System.out.println("Put file :" + file.getName() );
System.out.println("Message :");
System.out.println(message);
// Send Message.
TextMessage tm;
tm = session.createTextMessage(message);
sender.send(tm);
} catch (JMSException | IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(innerReader);
IOUtils.closeQuietly(inFile);
}
}
MQView.java
/** @param args
* 1st:QueueName(ex.inq001,outq001,errq001..)
* 2nd:MessageDirectory Path(Relativepath)
* 3rd:Extension(ex.txt,xml..),
* 4th:DeleteOption(defalt false without input)
*/
public static void main(String[] args) {
int paramLength = args.length;
String queueName = null;
String dirPath = null;
String extension = null;
boolean deleteOption = false;
Object[] paramCheckResult = new Object[4];
paramCheckResult = paramCheck(paramLength, args);
queueName = (String) paramCheckResult[0];
dirPath = (String) paramCheckResult[1];
extension = (String) paramCheckResult[2];
deleteOption = (boolean) paramCheckResult[3];
MQView.view(queueName, dirPath, extension, deleteOption);
}
public static String view(String queueName, String dirPath, String extension, boolean deleteOption) {
ResourceBundle bundle = null;
MQQueueConnectionFactory factory = null;
MQQueue mqQueue = null;
String mkDirPath = null;
int i = 0;
// clear object
QueueReceiver receiver = null;
QueueSession session = null;
QueueConnection conn = null;
try {
bundle = MQCommon.createResourceBundle();
factory = MQCommon.createMQQueueConnectionFactory(bundle);
conn = MQCommon.createQueueConnection(factory);
session = MQCommon.createQueueSession(conn);
mqQueue = MQCommon.createMQQueue(queueName);
MQCommon.info(factory, mqQueue);
receiver = createQueueReceiver(session, mqQueue);
conn.start();
// loop for message in queue
mkDirPath = createDirectory(dirPath);
while (true) {
TextMessage textMessage = (TextMessage) receiver.receiveNoWait();
if (textMessage == null) {
System.out.println("All message output completed");
break;
}
writeFile(i, queueName, extension, mkDirPath, textMessage);
i++;
}
System.out.println( "Wrote " + i + "files in :" + mkDirPath);
// delete object
if (deleteOption) {
// mq commit.
} else {
// mq rollback
}
} catch (JMSException | IOException | RuntimeException e) {
// mq rollback
} finally {
// close receiver session conn
}
return mkDirPath;
}
private static void writeFile(int i, String queueName, String extension, String dirName, TextMessage textMessage) throws JMSException,
IOException {
String fileName = queueName + "_" + (i + 1) + "." + extension;
String filePath = dirName + "/" + fileName;
File mkFile = new File(filePath);
mkFile.createNewFile();
BufferedWriter fileWriter = new BufferedWriter(new OutputStreamWriter (new FileOutputStream(filePath,true),"UTF-8"));
String message = textMessage.getText();
try {
fileWriter.write(message);
System.out.println(fileName + " wrote.");
} catch (IOException e1) {
throw new IOException();
} finally {
fileWriter.close();
}
}
遇到的坑:
1,用commons.io读取和写入utf8编码问题,都需要特殊指定,否则会按照默认编码去读。
//读utf8文件
inFile = new FileInputStream(file);
String message = IOUtils.toString(inFile,"utf-8");
//写utf8文件
BufferedWriter fileWriter = new BufferedWriter(new OutputStreamWriter (new FileOutputStream(filePath,true),"utf-8"));
fileWriter.write(message);
2,MQ的取出的话,commit也要明确的写,不然读完之后会依然存在。