杰克逊将日期从 Twitter 反序列化为“ZonedDateTime”
Jackson deserialize date from Twitter to `ZonedDateTime`
我想将日期从 Twitter 反序列化为 ZonedDateTime
。我的程序在 created_at
字段反序列化时失败。
我的领域class
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Tweet {
public final String id;
public final String idStr;
public final ZonedDateTime created_at;
public final String text;
public final long timestamp_ms;
public final User user;
@JsonCreator
public Tweet(@JsonProperty("id") String id,
@JsonProperty("id_str") String idStr,
@JsonProperty("created_at") ZonedDateTime created_at,
@JsonProperty("text") String text,
@JsonProperty("timestamp_ms") long timestamp_ms,
@JsonProperty("user") User user) {
this.id = id;
this.idStr = idStr;
this.created_at = created_at;
this.text = text;
this.timestamp_ms = timestamp_ms;
this.user = user;
}
}
我的解析方法
public class TweetTest {
private static final String TWEET = "{\"created_at\":\"Mon Aug 20 13:28:07 +0000 2018\",\"id\":1031533339793129472,\"id_str\":\"1031533339793129472\",\"text\":\"juntar dinheiro pra ir na prox tour do justin bieber que eu amo\",\"source\":\"\u003ca href=\\"http:\/\/twitter.com\/download\/iphone\\" rel=\\"nofollow\\"\u003eTwitter for iPhone\u003c\/a\u003e\",\"truncated\":false,\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":1239680360,\"id_str\":\"1239680360\",\"name\":\"ste\",\"screen_name\":\"flowxrst\",\"location\":\"Manaus, Brasil\",\"url\":null,\"description\":null,\"translator_type\":\"none\",\"protected\":false,\"verified\":false,\"followers_count\":1444,\"friends_count\":378,\"listed_count\":5,\"favourites_count\":13566,\"statuses_count\":40091,\"created_at\":\"Sun Mar 03 19:38:25 +0000 2013\",\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"lang\":\"pt\",\"contributors_enabled\":false,\"is_translator\":false,\"profile_background_color\":\"FFFFFF\",\"profile_background_image_url\":\"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png\",\"profile_background_image_url_https\":\"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png\",\"profile_background_tile\":false,\"profile_link_color\":\"000000\",\"profile_sidebar_border_color\":\"FFFFFF\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":false,\"profile_image_url\":\"http:\/\/pbs.twimg.com\/profile_images\/1030497329999237121\/MLVfvoFy_normal.jpg\",\"profile_image_url_https\":\"https:\/\/pbs.twimg.com\/profile_images\/1030497329999237121\/MLVfvoFy_normal.jpg\",\"profile_banner_url\":\"https:\/\/pbs.twimg.com\/profile_banners\/1239680360\/1533144133\",\"default_profile\":false,\"default_profile_image\":false,\"following\":null,\"follow_request_sent\":null,\"notifications\":null},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"quote_count\":0,\"reply_count\":0,\"retweet_count\":0,\"favorite_count\":0,\"entities\":{\"hashtags\":[],\"urls\":[],\"user_mentions\":[],\"symbols\":[]},\"favorited\":false,\"retweeted\":false,\"filter_level\":\"low\",\"lang\":\"pt\",\"timestamp_ms\":\"1534771687826\"}";
@Test
public void jackson_parsesDateTime() throws IOException {
DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.setDateFormat(dateFormat);
Tweet tweet = mapper.readValue(TWEET, Tweet.class);
Assert.assertNotNull(tweet);
}
@Test
public void ztd_parse() throws ParseException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy");
ZonedDateTime.parse("Mon Aug 20 13:28:07 +0000 2018", formatter);
}
}
两个测试都失败并出现 om.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type
java.time.ZonedDateTimefrom String "Mon Aug 20 13:28:07 +0000 2018": Text 'Mon Aug 20 13:28:07 +0000 2018' could not be parsed at index 0
错误。
我在 Whosebug 上查看了类似的问题,
我的 "EEE MMM dd HH:mm:ss Z yyyy"
格式看起来是正确的。
我做错了吗?
已解决
问题出在语言环境中。添加准确的语言环境测试后开始通过。
对于jackson_parsesDateTime
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "EEE MMM dd HH:mm:ss Z yyyy", locale = "en")
@JsonProperty("created_at") ZonedDateTime created_at,
用于 ztd_parse
测试
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
好像你的Locale
不匹配,试试用Locale.ENGLISH
:
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
和
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
尝试在您的 属性
上添加此注释
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
@JsonProperty("created_at")
ZonedDateTime created_at;
我想将日期从 Twitter 反序列化为 ZonedDateTime
。我的程序在 created_at
字段反序列化时失败。
我的领域class
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Tweet {
public final String id;
public final String idStr;
public final ZonedDateTime created_at;
public final String text;
public final long timestamp_ms;
public final User user;
@JsonCreator
public Tweet(@JsonProperty("id") String id,
@JsonProperty("id_str") String idStr,
@JsonProperty("created_at") ZonedDateTime created_at,
@JsonProperty("text") String text,
@JsonProperty("timestamp_ms") long timestamp_ms,
@JsonProperty("user") User user) {
this.id = id;
this.idStr = idStr;
this.created_at = created_at;
this.text = text;
this.timestamp_ms = timestamp_ms;
this.user = user;
}
}
我的解析方法
public class TweetTest {
private static final String TWEET = "{\"created_at\":\"Mon Aug 20 13:28:07 +0000 2018\",\"id\":1031533339793129472,\"id_str\":\"1031533339793129472\",\"text\":\"juntar dinheiro pra ir na prox tour do justin bieber que eu amo\",\"source\":\"\u003ca href=\\"http:\/\/twitter.com\/download\/iphone\\" rel=\\"nofollow\\"\u003eTwitter for iPhone\u003c\/a\u003e\",\"truncated\":false,\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":1239680360,\"id_str\":\"1239680360\",\"name\":\"ste\",\"screen_name\":\"flowxrst\",\"location\":\"Manaus, Brasil\",\"url\":null,\"description\":null,\"translator_type\":\"none\",\"protected\":false,\"verified\":false,\"followers_count\":1444,\"friends_count\":378,\"listed_count\":5,\"favourites_count\":13566,\"statuses_count\":40091,\"created_at\":\"Sun Mar 03 19:38:25 +0000 2013\",\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"lang\":\"pt\",\"contributors_enabled\":false,\"is_translator\":false,\"profile_background_color\":\"FFFFFF\",\"profile_background_image_url\":\"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png\",\"profile_background_image_url_https\":\"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png\",\"profile_background_tile\":false,\"profile_link_color\":\"000000\",\"profile_sidebar_border_color\":\"FFFFFF\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":false,\"profile_image_url\":\"http:\/\/pbs.twimg.com\/profile_images\/1030497329999237121\/MLVfvoFy_normal.jpg\",\"profile_image_url_https\":\"https:\/\/pbs.twimg.com\/profile_images\/1030497329999237121\/MLVfvoFy_normal.jpg\",\"profile_banner_url\":\"https:\/\/pbs.twimg.com\/profile_banners\/1239680360\/1533144133\",\"default_profile\":false,\"default_profile_image\":false,\"following\":null,\"follow_request_sent\":null,\"notifications\":null},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"quote_count\":0,\"reply_count\":0,\"retweet_count\":0,\"favorite_count\":0,\"entities\":{\"hashtags\":[],\"urls\":[],\"user_mentions\":[],\"symbols\":[]},\"favorited\":false,\"retweeted\":false,\"filter_level\":\"low\",\"lang\":\"pt\",\"timestamp_ms\":\"1534771687826\"}";
@Test
public void jackson_parsesDateTime() throws IOException {
DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.setDateFormat(dateFormat);
Tweet tweet = mapper.readValue(TWEET, Tweet.class);
Assert.assertNotNull(tweet);
}
@Test
public void ztd_parse() throws ParseException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy");
ZonedDateTime.parse("Mon Aug 20 13:28:07 +0000 2018", formatter);
}
}
两个测试都失败并出现 om.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type
java.time.ZonedDateTimefrom String "Mon Aug 20 13:28:07 +0000 2018": Text 'Mon Aug 20 13:28:07 +0000 2018' could not be parsed at index 0
错误。
我在 Whosebug 上查看了类似的问题,
我的 "EEE MMM dd HH:mm:ss Z yyyy"
格式看起来是正确的。
我做错了吗?
已解决
问题出在语言环境中。添加准确的语言环境测试后开始通过。
对于jackson_parsesDateTime
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "EEE MMM dd HH:mm:ss Z yyyy", locale = "en")
@JsonProperty("created_at") ZonedDateTime created_at,
用于 ztd_parse
测试
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
好像你的Locale
不匹配,试试用Locale.ENGLISH
:
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
和
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
尝试在您的 属性
上添加此注释@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
@JsonProperty("created_at")
ZonedDateTime created_at;