我正在尝试序列化JMS消息,以便我可以将其转换为BLOB并将其保存到SQL数据库中。
我的第一次天真尝试使用了一个Serializable类,它将其作为一个字段,如下所示:
private static class SerializableWrapper implements Serializable{
Message message;
private SerializableWrapper(Message message){
this.message = message;
}
private Message getMessage() {
return message;
}
private void setMessage(Message message) {
this.message = message;
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
out.writeObject(getMessage());
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
setMessage((Message) in.readObject());
}
}
这不起作用,并继续为NotSerializableException
抛出JMSTextMessage
。我不确定是否有其他第三方库可能有助于序列化这一点,但我的任务要求是 不 根本没有第三方依赖。
有没有好的/合理的方法可以做到这一点而不需要其他依赖?
编辑:我目前通过解压缩每个属性然后在反序列化时重新整理消息来实现此目的。在我看来,这种方法仍然不是最优的 - 有一些字段是不可序列化的,我还必须单独处理Message
的各种不同的子类,例如TextMessage
,ByteMessage
等。
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
HashMap<String, Object> properties = new HashMap <String, Object> ();
HashMap<Integer, Object> metaData = new HashMap<Integer, Object>();
try {
Enumeration srcProperties = message.getPropertyNames();
while (srcProperties.hasMoreElements()) {
String propertyName = (String) srcProperties.nextElement ();
properties.put(propertyName, message.getObjectProperty (propertyName));
}
//FIXME text/other body not preserved yet, have to preserve the message type eg Text/Byte etc continue after confirming with aditya
metaData.put(KEY_JMS_CORRELATION_ID, message.getJMSCorrelationID());
metaData.put(KEY_JMS_DELIVERY_MODE, message.getJMSDeliveryMode());
metaData.put(KEY_JMS_EXPIRATION, message.getJMSExpiration());
metaData.put(KEY_JMS_TIMESTAMP, message.getJMSTimestamp());
metaData.put(KEY_JMS_MESSAGE_ID, message.getJMSMessageID());
metaData.put(KEY_JMS_PRIORITY, message.getJMSPriority());
metaData.put(KEY_JMS_REPLY_TO, message.getJMSReplyTo());
metaData.put(KEY_JMS_TYPE, message.getJMSType());
} catch (JMSException e) {
e.printStackTrace();
}
out.writeObject(properties);
out.writeObject(metaData);
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
HashMap<String, Object> properties = (HashMap<String, Object>) in.readObject();
HashMap<Integer, Object> metaData= (HashMap<Integer, Object>) in.readObject();
System.out.println("JMSMessageUtility - Retrieving Properties: "+properties);
System.out.println("JMSMessageUtility - Retrieving Metadata: "+metaData);
Message message = null;
try {
ConnectionFactory connectionFactory = new AMQConnectionFactory(CONNECTION_BROKER);
Destination destination = new AMQAnyDestination(QUEUE_ADDRESS);
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
message = session.createMessage();
for(Map.Entry<String, Object> property: properties.entrySet()){
message.setObjectProperty(property.getKey(), property.getValue());
}
message.setJMSCorrelationID(metaData.get(KEY_JMS_CORRELATION_ID) == null? null:(String) metaData.get(KEY_JMS_CORRELATION_ID));
message.setJMSDeliveryMode((Integer) metaData.get(KEY_JMS_DELIVERY_MODE));
message.setJMSDestination(destination);
message.setJMSExpiration((Long) metaData.get(KEY_JMS_EXPIRATION));
message.setJMSTimestamp((Long) metaData.get(KEY_JMS_TIMESTAMP));
message.setJMSMessageID((String) metaData.get(KEY_JMS_MESSAGE_ID));
message.setJMSPriority((Integer) metaData.get(KEY_JMS_PRIORITY));
message.setJMSReplyTo(null); // no idea what to do with this
message.setJMSType(metaData.get(KEY_JMS_TYPE) == null? null:(String) metaData.get(KEY_JMS_TYPE));
} catch (URLSyntaxException e) {
e.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
setMessage(message);
}