I am using Apache Camel to convert my CSV data to JSON format. I then stream it to ActiveMQ Topic one by one and my Consumer - which is written in Spring Boot listens to the Topic parses the JSON and converts its to corresponding POJO.
Code (Producer):
final BindyCsvDataFormat bindy = new BindyCsvDataFormat(camelproject.EquityFeeds.class);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
CamelContext _ctx = new DefaultCamelContext();
_ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
_ctx.addRoutes(new RouteBuilder() {
public void configure() throws Exception {
from("file:src/main/resources?fileName=sampledata.csv")
.unmarshal(bindy)
.split(body())
.marshal()
.json(JsonLibrary.Jackson)
.to("file:src/main/resources/?fileName=emp.txt")
.split().tokenize("},").streaming().to("jms:queue:json.upstream.queue");
}
});
Relevant Section of My POJO:
@CsvRecord(separator = ",",skipFirstLine = true)
public class EquityFeeds implements Serializable {
@DataField(pos = 1)
private String externalTransactionId;
@DataField(pos = 2, pattern = "dd/MM/yy")
private LocalDate transactionDate;
// other fields and getters setters.
}
My data (JSON Output) goes into ActiveMQ Topic like this:
{"externalTransactionId":"SAPEXTXN6","clientId":"AP","securityId":"ICICI","transactionType":"SELL","transactionDate":{"year":2013,"month":"NOVEMBER","dayOfMonth":25,"monthValue":11,"dayOfYear":329,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"},"dayOfWeek":"MONDAY","era":"CE"},"marketValue":100.0,"sourceSystem":"BLO","priorityFlag":"Y","processingFee":0}
Now when I deserailize data I want the transactionDate to be in the format: YYYY-MM-DD
On My Consumer side (Listener writting in Spring Boot) I deserailize the JSON as below:
if(jsonMessage instanceof TextMessage) {
TextMessage textMessage = (TextMessage) jsonMessage;
try {
jsMessage = textMessage.getText();
} catch (JMSException e) {
e.printStackTrace();
}
Gson gson = new Gson();
EquityFeeds equityFeeds = gson.fromJson(jsMessage, EquityFeeds.class);
When I have LocalDate then I am NOT able to deserialize my JSON data correctly.
I get the below Exception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 118 path $.transactionDate
I then made some changes to the code:
@CsvRecord(separator = ",",skipFirstLine = true)
public class EquityFeedsJson implements Serializable {
@DataField(pos = 1)
private String externalTransactionId;
@DataField(pos = 2, pattern = "dd/MM/yy")
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate transactionDate;
// other getters and setters and fields.
}
LocalDateSerializer (Code):
public class LocalDateSerializer extends StdSerializer<LocalDate> {
public LocalDateSerializer() {
super(LocalDate.class);
}
@Override
public void serialize(LocalDate value, JsonGenerator generator, SerializerProvider provider) throws IOException {
generator.writeString(value.format(DateTimeFormatter.ISO_LOCAL_DATE));
}
}
My JSON now comes as :
{"externalTransactionId":"SAPEXTXN6","clientId":"AP","securityId":"ICICI","transactionType":"SELL","transactionDate":"2013-11-25","marketValue":100.0,"sourceSystem":"BLO","priorityFlag":"Y","processingFee":0}
I de serialized it on the Consumer side:
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate transactionDate;
LocalDateDeserailizer Code:
public class LocalDateDeserializer extends StdDeserializer<LocalDate> {
protected LocalDateDeserializer() {
super(LocalDate.class);
}
@Override
public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return LocalDate.parse(parser.readValueAs(String.class));
}
}
But again the same error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 118 path $.transactionDate
How do I solve this? I need help. I need to use LocalDate and able to deserialize on the Consumer side using Gson. Please also note that on the Publisher side I am using Apache Camel and on the Subscriber side I am using Gson to de serialize. I need the date to be in the format: YYYY-MM-DD.