spring-boot处理jackson的null值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring-boot处理jackson的null值相关的知识,希望对你有一定的参考价值。
参考技术A JacksonAllowNull<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n60" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">/**
JacksonHttpMessageConverter
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n65" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">@Component
public class JacksonHttpMessageConverter extends MappingJackson2HttpMessageConverter
/**
//解决 /instances/%5Bobject%20Object%5D/actuator/metrics
// https://github.com/codecentric/spring-boot-admin/issues/1517
objectMapper.addMixIn(InstanceId.class, InstanceIdMixin.class);
String[] pwdConstructor = new String[]".*password$";
objectMapper.registerModule(new AdminServerModule(pwdConstructor));
//解决domain.values.Registration cannot deserialize from Object
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Registration.class, ToStringSerializer.instance);
simpleModule.addDeserializer(Registration.class, new RegistrationDeserializer());
objectMapper.registerModule(simpleModule);
/**
/**
private class MyBeanSerializerModifier extends BeanSerializerModifier
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties)
for (Object beanProperty : beanProperties)
BeanPropertyWriter writer = (BeanPropertyWriter) beanProperty;
/ 过滤允许为null的注解 /
if (ObjectUtil.isNull(writer.getAnnotation(JacksonAllowNull.class)))
if (isArrayType(writer))
writer.assignNullSerializer(new NullArrayJsonSerializer());
else if (isNumberType(writer))
writer.assignNullSerializer(new NullNumberJsonSerializer());
else if (isBooleanType(writer))
writer.assignNullSerializer(new NullBooleanJsonSerializer());
else if (isStringType(writer))
writer.assignNullSerializer(new NullStringJsonSerializer());
/* 防止Long精度丢失 */
// if(isLongType(writer))
// writer.assignSerializer(new ToStringSerializer());
//
return beanProperties;
private boolean isArrayType(BeanPropertyWriter writer)
Class<?> clazz = writer.getType().getRawClass();
return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
private boolean isStringType(BeanPropertyWriter writer)
Class<?> clazz = writer.getType().getRawClass();
return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
private boolean isNumberType(BeanPropertyWriter writer)
Class<?> clazz = writer.getType().getRawClass();
return Number.class.isAssignableFrom(clazz);
private boolean isLongType(BeanPropertyWriter writer)
Class<?> clazz = writer.getType().getRawClass();
return Long.class.isAssignableFrom(clazz);
private boolean isBooleanType(BeanPropertyWriter writer)
Class<?> clazz = writer.getType().getRawClass();
return clazz.equals(Boolean.class);
private class NullArrayJsonSerializer extends JsonSerializer<Object>
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException
if (o == null)
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
private class NullStringJsonSerializer extends JsonSerializer<Object>
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
jsonGenerator.writeString(StringUtils.EMPTY);
private class NullNumberJsonSerializer extends JsonSerializer<Object>
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
jsonGenerator.writeNumber(0);
private class NullBooleanJsonSerializer extends JsonSerializer<Object>
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
jsonGenerator.writeBoolean(false);
</pre>
https://gitee.com/miaoyinjun/jjche-boot
spring-boot 使用啥版本的 Jackson?
【中文标题】spring-boot 使用啥版本的 Jackson?【英文标题】:What version of Jackson does spring-boot use?spring-boot 使用什么版本的 Jackson? 【发布时间】:2018-05-21 23:11:27 【问题描述】:我正在努力确保以安全的方式使用 spring-boot 和 Jackson。 Jackson 的某些版本中存在反序列化错误(来源:https://github.com/FasterXML/jackson-databind/issues/1599)。
默认情况下,Spring Security 不使用 Jackson 执行反序列化,因此这是用户的明确选择(来源:https://pivotal.io/security/cve-2017-4995)。
如果 Jackson 用于执行反序列化,则版本 2.7、2.8、2.8.9 和 2.7.9.1 以及 2.9.0.pr3 已修补(来源:请参阅 cowtowncoder 于 4 月 13 日评论,https://github.com/FasterXML/jackson-databind/issues/1599)而不是容易受到该错误的影响。
那么使用作为 spring、spring-boot 或 Spring Security 一部分的 Jackson 版本执行反序列化是否安全?
【问题讨论】:
这取决于您使用的这些工具的版本。例如,Spring Boot 版本 1 可能使用 Jackson 版本 1,而 Spring Boot 版本 2 使用 Jackson 版本 2。不只有 1 个“Spring Boot”仅使用一组依赖项。一个真实的例子是 Spring Boot 1.5.2 使用 Jackson 2.8.7 我的意思是包含这些信息:Spring Boot 1.59 “当前”版本。 如果您查看父 pom 文件,您将看到正在使用的 jackson 版本。 如果你使用gradle,执行gradlew依赖,你就知道了。如果你使用 Maven,使用 mvn dependency:tree,你就会知道。您也可以只查看 pom:mvnrepository.com/artifact/org.springframework.boot/…(当然,您可能有另一个依赖项导致使用另一个版本)。 【参考方案1】:每个版本的 SpringBoot 都使用易受攻击的 Jackson API 版本,因为确实没有任何版本至少部分易受攻击。如果您允许将不受信任的第三方数据反序列化为通用集合(Map、List. 等),则可能会发生这种情况。即使您在代码中向这些结构添加泛型,这些泛型也只是编译时的,不能强制在 JVM 运行时中键入。
如果您正在访问外部的 RESTful api,那么您将必须实现自己的类型。如果您使用的是 RestTemplate,则必须在它使用的对象映射器上手动设置。
仅供参考:SpringBoot 也使用易受攻击的 logback 版本。只需将其明确包含在您的构建中即可更新到最新版本。
【讨论】:
以上是关于spring-boot处理jackson的null值的主要内容,如果未能解决你的问题,请参考以下文章
Jackson 包含 non_null 不能处理来自 kotlin 扩展函数的对象
Jackson中处理map中的null key 或者null value 及实体字段中的null value
带有war文件的Maven上的Spring-boot jackson错误,但不是带有com.fasterxml.jackson.core.JsonFactory.requiresPropertyOrd