@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public Module customModule() {
SimpleModule module = new SimpleModule();
module.addSerializer(Date.class, new DateConverter.Serialize());
module.addDeserializer(Date.class, new Dateconverter.Deserialize());
return module;
}
}
86
只是 spring boot 应用程序的完整示例,其中包含 RFC3339 datetime格式
package bj.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import java.text.SimpleDateFormat;
/**
* Created by BaiJiFeiLong@gmail.com at 2018/5/4 10:22
*/
@SpringBootApplication
public class BarApp implements ApplicationListener<ApplicationReadyEvent> {
public static void main(String[] args) {
SpringApplication.run(BarApp.class, args);
}
@Autowired
private ObjectMapper objectMapper;
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));
}
}
You need to use custom serializer and custom deserializer instead of the @JsonFormat annotation if you want predicted result. 我在这里找到了真正的好教程和解决方案http://www.baeldung.com/jackson-serialize-dates
有 Date 字段的示例,但我需要 Calendar 字段,所以 here is my implementation :
serializer 类:
public class CustomCalendarSerializer extends JsonSerializer<Calendar> {
public static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
public static final Locale LOCALE_HUNGARIAN = new Locale("hu", "HU");
public static final TimeZone LOCAL_TIME_ZONE = TimeZone.getTimeZone("Europe/Budapest");
@Override
public void serialize(Calendar value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
if (value == null) {
gen.writeNull();
} else {
gen.writeString(FORMATTER.format(value.getTime()));
}
}
}
deserializer 班:
public class CustomCalendarDeserializer extends JsonDeserializer<Calendar> {
@Override
public Calendar deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException {
String dateAsString = jsonparser.getText();
try {
Date date = CustomCalendarSerializer.FORMATTER.parse(dateAsString);
Calendar calendar = Calendar.getInstance(
CustomCalendarSerializer.LOCAL_TIME_ZONE,
CustomCalendarSerializer.LOCALE_HUNGARIAN
);
calendar.setTime(date);
return calendar;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
and the usage 以上课程:
public class CalendarEntry {
@JsonSerialize(using = CustomCalendarSerializer.class)
@JsonDeserialize(using = CustomCalendarDeserializer.class)
private Calendar calendar;
// ... additional things ...
}
Using this implementation the execution of the serialization and deserialization process consecutively results the origin value.
Only using the @JsonFormat annotation the deserialization gives different result 我认为由于库内部时区默认设置你不能用注释参数改变(这是我对Jackson库2.5.3和2.6.3版本的经验) .
1
如果有人在使用java.sql.Date的自定义日期格式时遇到问题,这是最简单的解决方案:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(java.sql.Date.class, new DateSerializer());
mapper.registerModule(module);
7 回答
从Jackson v2.0开始,你可以直接在Object成员上使用@JsonFormat注释;
在@ miklov-kriven的非常有用的答案的基础上,我希望这两个额外的考虑点对某人有用:
(1)我发现在同一个类中包含序列化器和反序列化器作为静态内部类是个不错的主意 . 注意,使用ThreadLocal来实现SimpleDateFormat的线程安全性 .
(2)作为在每个单独的类成员上使用@JsonSerialize和@JsonDeserialize注释的替代方法,您还可以考虑通过在应用程序级别应用自定义序列化来覆盖Jackson的默认序列化,即所有类型为Date的类成员将由Jackson序列化使用此自定义序列化而不在每个字段上显式注释 . 例如,如果您使用Spring Boot,则执行此操作的方法如下:
只是 spring boot 应用程序的完整示例,其中包含
RFC3339
datetime格式我想指出,设置
SimpleDateFormat
就像在另一个答案中描述的那样只适用于java.util.Date
,我认为这是在问题中的意思 . 但是对于java.sql.Date
格式化程序不起作用 . 在我的情况下,为什么格式化程序不起作用并不是很明显,因为在应该序列化的模型中,字段实际上是java.utl.Date
但实际对象最终变成了java.sql.Date
. 这是可能的,因为所以这实际上是有效的
因此,如果您想知道为什么您的日期字段格式不正确,请确保该对象确实是
java.util.Date
.Here也提到了为什么不添加处理
java.sql.Date
.当然 there is an automated way 称为序列化和反序列化,您可以使用pb2q提到的特定注释( @JsonSerialize , @JsonDeserialize )来定义它 .
您可以同时使用java.util.Date和java.util.Calendar ...以及JodaTime .
The @JsonFormat annotations not worked for me as I wanted (它有 adjusted the timezone 到不同的值) during deserialization (序列化工作完美):
You need to use custom serializer and custom deserializer instead of the @JsonFormat annotation if you want predicted result. 我在这里找到了真正的好教程和解决方案http://www.baeldung.com/jackson-serialize-dates
有 Date 字段的示例,但我需要 Calendar 字段,所以 here is my implementation :
serializer 类:
deserializer 班:
and the usage 以上课程:
Using this implementation the execution of the serialization and deserialization process consecutively results the origin value.
Only using the @JsonFormat annotation the deserialization gives different result 我认为由于库内部时区默认设置你不能用注释参数改变(这是我对Jackson库2.5.3和2.6.3版本的经验) .
如果有人在使用java.sql.Date的自定义日期格式时遇到问题,这是最简单的解决方案:
(这个答案给我带来了很多麻烦:https://stackoverflow.com/a/35212795/3149048)
Jackson默认使用SqlDateSerializer作为java.sql.Date,但是目前,此序列化程序不考虑dateformat,请参阅此问题:https://github.com/FasterXML/jackson-databind/issues/1407 . 解决方法是为java.sql.Date注册不同的序列化程序,如代码示例所示 .
Date
是一个很好的字段类型 . 您可以使用ObjectMapper.setDateFormat
轻松地使JSON解析:是 . 您有几个选项,包括实现自定义
JsonDeserializer
,例如延伸JsonDeserializer<Date>
. This是一个好的开始 .