0

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.

sidd
  • 195
  • 3
  • 20
  • The annotations on date field seems to be from jackson, but you are using gson to parse, isn't it better to use any one? – Nithin Apr 12 '20 at 19:06
  • @areus: Thanks a lot. Yes the given link answers my questions. My query got resolved. Thanks again. – sidd Apr 13 '20 at 05:26

0 Answers0