I am using the below mentioned code to publish into a topic. It is of the format convertAndSend(Destination destination, Object message)
Event event;
jmsTemplate.convertAndSend(topic, event);
My current Event interface is something like this,
public interface Event {
public boolean isEmpty();
public AcEventDatafileTransaction getDatafileTransaction();
public AcEventObjectTransaction getObjectTransaction();
boolean isDatafileTransaction();
boolean isObjectTransaction();
boolean isRdbmsTransaction();
String getTransactionId();
}
Its implementation is something like this,
public class EventPublisherImpl implements Event {
private final AcTransactionRecord transactionRecord;
private final Ac ac;
private final String[] actualTemplates;
private final String[] curveTemplates;
public AcEventPublisherImpl(final Ac ac,
final String[] actualTemplates,
final String[] curveTemplates,
final AcTransactionRecord acTransactionRecord) {
this.ac = ac;
this.transactionRecord = acTransactionRecord;
this.actualTemplates = actualTemplates;
this.curveTemplates = curveTemplates;
}
@Override
public boolean isEmpty() {
return transactionRecord.isEmpty();
}
@Override
public AcEventDatafileTransaction getDatafileTransaction() {
if (isDatafileTransaction()) {
return new AcEventDatafileTransactionPublisherImpl(transactionRecord.getDatafileTransaction());
}
return null;
}
@Override
public AcEventObjectTransaction getObjectTransaction() {
if (isObjectTransaction()) {
return new AcEventObjectTransactionPublisherImpl(ac, actualTemplates, curveTemplates, transactionRecord.getObjectOperations());
}
return null;
}
@Override
public boolean isDatafileTransaction() {
return transactionRecord.getType() == AcTransactionRecord.DATAFILE_TRANS;
}
@Override
public boolean isObjectTransaction() {
return transactionRecord.getType() == AcTransactionRecord.OBJECT_TRANS;
}
@Override
public boolean isRdbmsTransaction() {
return transactionRecord.getType() == AcTransactionRecord.RDBMS_TRANS;
}
@Override
public String getTransactionId() {
if (transactionRecord != null) {
return Integer.toString(transactionRecord.getNumber());
}
return "";
}
}
How do I convert it into a serializable form?
My whole objective is to publish Event object into topic. For that I am using convertAndSend method. That method requires an object of a serialized class, which I currently dont have. It is what I am trying to achieve. I have looked at examples where a class with few attributes is serialized using message converter https://examples.javacodegeeks.com/enterprise-java/spring/spring-framework-jmstemplate-example/
Please suggest a method through code or point to the appropriate example and how that helps me.
The overloaded methods
convertAndSend()
andreceiveAndConvert()
in JmsTemplate delegate the conversion process to an instance of theMessageConverter
interface. This interface defines a simple contract to convert between Java objects and JMS messages. The default implementationSimpleMessageConverter
supports conversion betweenString
andTextMessage
,byte[]
andBytesMesssage
, andjava.util.Map
andMapMessage
.
So, to support custom type we have to create custom converter which implements MessageConverter
to convert Event
object to one of supported message type. The simplest solution is to register MappingJackson2MessageConverter
provided by spring which support converting object to TextMessage
in form of json.
@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
You can take a look how the serialization process is done on the source code in case you want to create your own converter.
To receive the message, the easiest way is to use @JmsListener
annotation, spring will implicitly convert the message to its java type using the registered converter
@Component
public class Receiver {
@JmsListener(destination = "dest")
public void receiveMessage(Event event) {
// do whatever you need with the event
}
}
another way is to use javax.jms.MessageListener
but you need to manually convert the message yourself.
@Component
public class ExampleListener implements MessageListener {
@Autowired
private ObjectMapper objectMapper;
public void onMessage(Message message) {
if (message instanceof TextMessage) {// we set the converter targetType to text
try {
String json = ((TextMessage) message).getText(); // here you have your event object as json string
Event event = objectMapper.readValue(json, Event.class); // convert back to event object
}
catch (JMSException ex) {
throw new RuntimeException(ex);
}
}
else {
throw new IllegalArgumentException("Message must be of type TextMessage");
}
}
Ref:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With