支持多种日期格式的Kafka JsonDeserializer



我正在学习kafka,我正在努力为消费者定制一个JsonDeserializer,其中我的对象有一个日期字段,应该接受多种格式。

例如,我希望它可以解析来自生产者的消息与日期= "2021/09/12"或"mm/dd/yyyy HH: mm "或者更长的时间戳1231231321

如果它只有一个字段,我可以只是写我的自定义反序列化类,但因为我有一个对象与多个类型字段,我怎么能包括我的自定义日期反序列化?我只是有一个通用的json反序列化和我的对象注释?

@JsonFormat(using = CustomDateDeserializer.class)

您可以创建这样的自定义反序列化器,

public class CustomDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
String dateString = jsonparser.getText();
return parse(dateString);
}
private Date parse(String dateString) {
final String[] formats = {
"M/d/y H:m",
"y/M/d"};

// Used to check the epoch timestamp
Pattern pattern = Pattern.compile("\d{10}");
Matcher matcher = pattern.matcher(dateString);
if (matcher.matches()) {
return new Date(Long.parseLong(dateString) * 1000); // here assumed `dateString` in seconds.
}
for (String format : formats) {
try { return new SimpleDateFormat(format).parse(dateString); }
catch (ParseException e) {/* do nothing */}
}
return null;
}
}

或者你也可以这样做。

注:唯一不同的是parse方法

public class CustomDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
String dateString = jsonparser.getText();
return parse(dateString);
}
private Date parse(String dateString) {
final Map<String, String> patterns  = new HashMap<String, String>() {{
put("M/d/y H:m", "^\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}$");
put("y/M/d", "^\d{4}\/\d{2}\/\d{2}$");
}};
// Used to check the epoch timestamp
Pattern p = Pattern.compile("\d{10}");
Matcher matcher = p.matcher(dateString);
if (matcher.matches()) {
return new Date(Long.parseLong(dateString) * 1000); // here assumed `dateString` in seconds.
}
for (Map.Entry<String, String> pattern : patterns.entrySet()) {
if (matcher.usePattern(Pattern.compile(pattern.getValue())).matches()) {
try { return new SimpleDateFormat(pattern.getKey()).parse(dateString); }
catch (ParseException e) {/* do nothing */} }
}
return null;
}
}

注意:我建议使用第二种方法

那么你需要告诉Jackson在反序列化到Date类时使用这个反序列化器。您可以通过两种方式完成此操作。

你像这样注释类中的每个Date参数,

@JsonDeserialize(using = CustomDateDeserializer.class)
private Date dateParam;

或者您可以像这样在Date类中注册这个反序列化器,

@Configuration
public class JacksonConfig implements Jackson2ObjectMapperBuilderCustomizer {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.failOnEmptyBeans(false)
.deserializerByType(Date.class, new CustomDateDeserializer());
}
}

最新更新