json 为日期反序列化设置杰克逊时区
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7556851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set Hymanson Timezone for Date deserialization
提问by Mike G
I'm using Hymanson (via Spring MVC Annotations) to deserialize a field into a java.util.Datefrom JSON. The POST looks like - {"enrollDate":"2011-09-28T00:00:00.000Z"}, but when the Object is created by Spring & Hymanson it sets the date as "2011-09-27 20:00:00".
我正在使用 Hymanson(通过 Spring MVC Annotations)将字段java.util.Date从 JSON反序列化为 a 。POST 看起来像 - {"enrollDate":"2011-09-28T00:00:00.000Z"},但是当对象由 Spring & Hymanson 创建时,它会将日期设置为"2011-09-27 20:00:00".
How can I set the proper timezone in Hymanson?Or if that is not the problem, how do I send EST from the JSON message?
如何在Hyman逊设置正确的时区?或者,如果这不是问题,我如何从 JSON 消息发送 EST?
Javascript/jQuery:
Javascript/jQuery:
var personDataView = { enrollDate : new Date($("#enrollDate").val()),
//...other members
};
$.postJSON('/some/path/', personDataView, function(data){
//... handle the response here
});
JSON Message:
JSON 消息:
{"enrollDate":"2011-09-28T00:00:00.000Z"}
{"enrollDate":"2011-09-28T00:00:00.000Z"}
Spring Controller:
弹簧控制器:
@RequestMapping(value="/", method=RequestMethod.POST)
public @ResponseBody String saveProfile(@RequestBody personDataView persondataView, HttpServletRequest request)
{
//...dataView has a java.util.Date enrollDate field
//...other code
}
回答by Olivier Lecrivain
In Hymanson 2+, you can also use the @JsonFormat annotation :
在 Hymanson 2+ 中,您还可以使用 @JsonFormat 注释:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone="America/Phoenix")
private Date date;
回答by SiCN
If you really want Hymanson to return a date with another time zone than UTC (and I myself have several good arguments for that, especially when some clients just don't get the timezone part) then I usually do:
如果你真的希望Hyman逊返回一个时区而不是 UTC 的日期(我自己有几个很好的论据,特别是当一些客户没有得到时区部分时),那么我通常会这样做:
ObjectMapper mapper = new ObjectMapper();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
dateFormat.setTimeZone(TimeZone.getTimeZone("CET"));
mapper.getSerializationConfig().setDateFormat(dateFormat);
// ... etc
It has no adverse effects on those that understand the timezone-p
它对那些了解 timezone-p 的人没有不利影响
回答by SiCN
Have you tried this in your application.properties?
你在 application.properties 中试过这个吗?
spring.Hymanson.time-zone= # Time zone used when formatting dates. For instance `America/Los_Angeles`
回答by whitestryder
I am using Hymanson 1.9.7 and I found that doing the following does not solve my serialization/deserialization timezone issue:
我正在使用 Hymanson 1.9.7,我发现执行以下操作并不能解决我的序列化/反序列化时区问题:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
objectMapper.setDateFormat(dateFormat);
Instead of "2014-02-13T20:09:09.859Z" I get "2014-02-13T08:09:09.859+0000" in the JSON message which is obviously incorrect. I don't have time to step through the Hymanson library source code to figure out why this occurs, however I found that if I just specify the Hymanson provided ISO8601DateFormatclass to the ObjectMapper.setDateFormatmethod the date is correct.
我在 JSON 消息中得到的不是“2014-02-13T20:09:09.859Z”,而是“2014-02-13T08:09:09.859+0000”,这显然是不正确的。我没有时间单步执行 Hymanson 库源代码来弄清楚为什么会发生这种情况,但是我发现如果我只是将 Hymanson 提供的ISO8601DateFormat类指定给ObjectMapper.setDateFormat方法,则日期是正确的。
Except this doesn't put the milliseconds in the format which is what I want so I sub-classed the ISO8601DateFormatclass and overrode the format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition)method.
除了这不会以我想要的格式放置毫秒,所以我对ISO8601DateFormat类进行了子类化并覆盖了format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition)方法。
/**
* Provides a ISO8601 date format implementation that includes milliseconds
*
*/
public class ISO8601DateFormatWithMillis extends ISO8601DateFormat {
/**
* For serialization
*/
private static final long serialVersionUID = 2672976499021731672L;
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition)
{
String value = ISO8601Utils.format(date, true);
toAppendTo.append(value);
return toAppendTo;
}
}
回答by Lichader
回答by fl4l
I had same problem with Calendar deserialization, solved extending CalendarDeserializer.
It forces UTC Timezone
I paste the code if someone need it:
我在 Calendar 反序列化方面遇到了同样的问题,解决了扩展 CalendarDeserializer 的问题。
如果有人需要,
它会强制 UTC 时区
我粘贴代码:
@HymansonStdImpl
public class UtcCalendarDeserializer extends CalendarDeserializer {
TimeZone TZ_UTC = TimeZone.getTimeZone("UTC");
@Override
public Calendar deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT) {
Calendar cal = Calendar.getInstance(TZ_UTC);
cal.clear();
cal.setTimeInMillis(jp.getLongValue());
return cal;
}
return super.deserialize(jp, ctxt);
}
}
in JSON model class just annotate the field with:
在 JSON 模型类中,只需使用以下内容注释该字段:
@JsonDeserialize(using = UtcCalendarDeserializer.class)
private Calendar myCalendar;
回答by jjmontes
Your date object is probably ok, since you sent your date encoded in ISO format with GMT timezone and you are in EST when you print your date.
您的日期对象可能没问题,因为您使用 GMT 时区发送了以 ISO 格式编码的日期,并且您在打印日期时处于 EST。
Note that Date objects perform timezone translation at the moment they are printed. You can check if your dateobject is correct with:
请注意,Date 对象在打印时执行时区转换。您可以通过以下方式检查您的date对象是否正确:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.setTime(date);
System.out.println (cal);
回答by robrides
For anyone struggling with this problem in the now (Feb 2020), the following Medium post was crucial to overcoming it for us.
对于现在(2020 年 2 月)遇到这个问题的任何人来说,以下 Medium 帖子对于我们克服它至关重要。
https://medium.com/@ttulka/spring-http-message-converters-customizing-770814eb2b55
https://medium.com/@ttulka/spring-http-message-converters-customizing-770814eb2b55
In our case, the app uses @EnableWebMvc and would break if removed so, the section on 'The Life without Spring Boot' was critical. Here's what ended up solving this for us. It allows us to still consume and produce JSON and XML as well as format our datetime during serialization to suit the app's needs.
在我们的例子中,应用程序使用 @EnableWebMvc 并且如果删除它就会中断,关于“没有 Spring Boot 的生活”的部分至关重要。这就是最终为我们解决这个问题的原因。它允许我们在序列化期间仍然使用和生成 JSON 和 XML 以及格式化我们的日期时间以满足应用程序的需求。
@Configuration
@ComponentScan("com.company.branch")
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, new MappingHymanson2XmlHttpMessageConverter(
new Hymanson2ObjectMapperBuilder()
.defaultUseWrapper(false)
.createXmlMapper(true)
.simpleDateFormat("yyyy-mm-dd'T'HH:mm:ss'Z'")
.build()
));
converters.add(1, new MappingHymanson2HttpMessageConverter(
new Hymanson2ObjectMapperBuilder()
.build()
));
}
}

