杰克逊禁用@JsonFormat 注释
jackson disable @JsonFormat annotation
我正在使用 jackson 库,我遇到了一种情况,我想在 serialization/deserialization.
时使用 objectmapper 禁用 @JsonFormat 注释
我的 Api 代码在第 3 方库中,所以我不能 remove/add 任何注释,所以 objectMapper 是唯一的选择。
Api class:
public class ApiClass {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private DateTime time;
}
我的代码:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(Include.NON_ABSENT);
objectMapper.registerModule(new JodaModule());
objectMapper.registerModule(new JavaTimeModule());
String str = " {\"time\": \"2012-05-01\"}";
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
我希望这次转换成功。
目前我得到:com.fasterxml.jackson.databind.JsonMappingException:格式无效:“2012-05-01”太短
请帮帮我。
提前致谢
在使用 readValue
方法之前尝试下面的代码
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
尝试使用自定义解串器:
public class MyTest {
@Test
public void myTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
objectMapper.registerModule(new JavaTimeModule());
String str = " {\"time\": \"2012-05-01\"}";
SimpleModule module = new SimpleModule();
module.addDeserializer(DateTime.class, new DateTimeDeserializer());
objectMapper.registerModule(module);
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
System.out.println(msg.getTime());
}
}
class ApiClass {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private DateTime time;
public DateTime getTime() {
return time;
}
public void setTime(DateTime time) {
this.time = time;
}
}
class DateTimeDeserializer extends StdDeserializer<DateTime> {
public DateTimeDeserializer() {
this(null);
}
public DateTimeDeserializer(Class<?> vc) {
super(vc);
}
@Override
public DateTime deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
String time = node.asText();
return new DateTime(time);
}
}
您可以使用 SimpleDateFormat 将字符串类型日期转换为如下所示的日期类型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
try {
Date parse = simpleDateFormat.parse(String date);
return parse;
} catch (ParseException e) {
e.printStackTrace();
}
问题只有一种解决方案。
请检查:https://www.baeldung.com/jackson-annotations点号。 9 禁用 Jackson 注释
objectMapper.disable(MapperFeature.USE_ANNOTATIONS);
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
sout(msg.getTime()) //2012-05-01T00:00:00.000Z
但这会禁用所有注释。我只想禁用 @JsonFormat 注释。请提出建议。
下面是专门禁用 JsonFormat 的代码:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(Include.NON_ABSENT);
objectMapper.registerModule(new JodaModule());
objectMapper.registerModule(new JavaTimeModule());
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
protected <A extends Annotation> A _findAnnotation(final Annotated annotated,
final Class<A> annoClass) {
if (!annotated.hasAnnotation(JsonFormat.class)) { //since we need to disable JsonFormat annotation.
return super._findAnnotation(annotated, annoClass);
}
return null;
}
});
String str = " {\"time\": \"2012-05-01\"}";
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
System.out.println(objectMapper.writeValueAsString(msg ));
如果我们需要禁用多个注释(JsonFormat、JsonUnWrapped),那么:
替换:
if (!annotated.hasAnnotation(JsonFormat.class)) {
与:
if (!annotated.hasOneOf(new Class[] {JsonFormat.class, JsonUnwrapped.class})) {
谢谢大家
我正在使用 jackson 库,我遇到了一种情况,我想在 serialization/deserialization.
时使用 objectmapper 禁用 @JsonFormat 注释我的 Api 代码在第 3 方库中,所以我不能 remove/add 任何注释,所以 objectMapper 是唯一的选择。
Api class:
public class ApiClass {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private DateTime time;
}
我的代码:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(Include.NON_ABSENT);
objectMapper.registerModule(new JodaModule());
objectMapper.registerModule(new JavaTimeModule());
String str = " {\"time\": \"2012-05-01\"}";
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
我希望这次转换成功。
目前我得到:com.fasterxml.jackson.databind.JsonMappingException:格式无效:“2012-05-01”太短
请帮帮我。
提前致谢
在使用 readValue
方法之前尝试下面的代码
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
尝试使用自定义解串器:
public class MyTest {
@Test
public void myTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
objectMapper.registerModule(new JavaTimeModule());
String str = " {\"time\": \"2012-05-01\"}";
SimpleModule module = new SimpleModule();
module.addDeserializer(DateTime.class, new DateTimeDeserializer());
objectMapper.registerModule(module);
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
System.out.println(msg.getTime());
}
}
class ApiClass {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private DateTime time;
public DateTime getTime() {
return time;
}
public void setTime(DateTime time) {
this.time = time;
}
}
class DateTimeDeserializer extends StdDeserializer<DateTime> {
public DateTimeDeserializer() {
this(null);
}
public DateTimeDeserializer(Class<?> vc) {
super(vc);
}
@Override
public DateTime deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
String time = node.asText();
return new DateTime(time);
}
}
您可以使用 SimpleDateFormat 将字符串类型日期转换为如下所示的日期类型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
try {
Date parse = simpleDateFormat.parse(String date);
return parse;
} catch (ParseException e) {
e.printStackTrace();
}
问题只有一种解决方案。
请检查:https://www.baeldung.com/jackson-annotations点号。 9 禁用 Jackson 注释
objectMapper.disable(MapperFeature.USE_ANNOTATIONS);
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
sout(msg.getTime()) //2012-05-01T00:00:00.000Z
但这会禁用所有注释。我只想禁用 @JsonFormat 注释。请提出建议。
下面是专门禁用 JsonFormat 的代码:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(Include.NON_ABSENT);
objectMapper.registerModule(new JodaModule());
objectMapper.registerModule(new JavaTimeModule());
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
protected <A extends Annotation> A _findAnnotation(final Annotated annotated,
final Class<A> annoClass) {
if (!annotated.hasAnnotation(JsonFormat.class)) { //since we need to disable JsonFormat annotation.
return super._findAnnotation(annotated, annoClass);
}
return null;
}
});
String str = " {\"time\": \"2012-05-01\"}";
ApiClass msg = objectMapper.readValue(str, ApiClass.class);
System.out.println(objectMapper.writeValueAsString(msg ));
如果我们需要禁用多个注释(JsonFormat、JsonUnWrapped),那么:
替换:
if (!annotated.hasAnnotation(JsonFormat.class)) {
与:
if (!annotated.hasOneOf(new Class[] {JsonFormat.class, JsonUnwrapped.class})) {
谢谢大家