java - 使用 Gson 反序列化 LocalDate 的问题
问题描述
我正在使用 Apache Camel 将我的 CSV 数据转换为 JSON 格式。然后我将它一个一个地流式传输到 ActiveMQ 主题,我的消费者(用 Spring Boot 编写)监听主题解析 JSON 并将其转换为相应的 POJO。
代码(生产者):
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");
}
});
我的 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.
}
我的数据(JSON 输出)像这样进入 ActiveMQ 主题:
{"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}
现在,当我对数据进行脱轨时,我希望 transactionDate 采用以下格式:YYYY-MM-DD
在我的消费者方面(在 Spring Boot 中编写的侦听器)我将 JSON 脱轨,如下所示:
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);
当我有 LocalDate 时,我无法正确反序列化我的 JSON 数据。
我得到以下异常:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 118 path $.transactionDate
然后我对代码进行了一些更改:
@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(代码):
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));
}
}
我的 JSON 现在是:
{"externalTransactionId":"SAPEXTXN6","clientId":"AP","securityId":"ICICI","transactionType":"SELL","transactionDate":"2013-11-25","marketValue":100.0,"sourceSystem":"BLO","priorityFlag":"Y","processingFee":0}
我在消费者端对其进行了反序列化:
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate transactionDate;
LocalDateDeserailizer 代码:
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));
}
}
但同样的错误:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 118 path $.transactionDate
我该如何解决这个问题?我需要帮助。我需要使用 LocalDate 并能够使用 Gson 在消费者端反序列化。另请注意,在发布者端,我使用的是 Apache Camel,而在订阅者端,我使用 Gson 进行反序列化。我需要日期格式为:YYYY-MM-DD。
解决方案
推荐阅读
- android - Android Gradle 3.0.0 - 添加特定风格的库依赖项
- c# - 如何在人脸检测过程中暂停秒表?
- c# - C# LibCurlNet 图像上传
- python - 在python中识别列表中的常见元素
- java - JasperException 使用 www.springframework.org/tags/form
- c++ - 在 OpenMP C++ 中使用并行块时没有看到任何显着的改进
- python-2.7 - 我的图像完全是黑色的,它没有显示 50% 黑色和 50% 白色
- elasticsearch - Elasticsearch 启动失败:需要 CONFIG_SECCOMP 和 CONFIG_SECCOMP_FILTER
- android - 在高于 6.0 的操作系统版本中隐藏 Actionbar 时的空白?
- javascript - 减少变化的价值