将其从 GitHub 移至此处因为 Spring 团队仅使用 GitHub 问题来处理错误和功能请求。
根据 Spring Boot documentation ,应该可以定制Jackson ObjectMapper
使用环境属性(例如在 application.properties
中),例如 spring.jackson.parser.<feature_name>
只要您没有定义自己的 ObjectMapper
bean 。
我需要激活ALLOW_NON_NUMERIC_NUMBERS
解析器功能,因为我使用 NaN
获取(严格来说无效)JSON我希望 Jackson 映射到的浮点字段的值 java.lang.Double.NaN
在Java中。
所以在我的 application.properties
中我添加了spring.jackson.parser.ALLOW_NON_NUMERIC_NUMBERS=true
我可以看到这个正在被接收:
- Spring Boot 的
JacksonAutoConfiguration
正在创建Jackson2ObjectMapperBuilder
-
Jackson2ObjectMapperBuilder
的StandardJackson2ObjectMapperBuilderCustomizer
正在接我的spring.jackson.parser.ALLOW_NON_NUMERIC_NUMBERS=true
属性并将其添加到其features
map -
Jackson2ObjectMapperBuilder
的build()
方法最终调用configureFeature
其结果是ALLOW_NON_NUMERIC_NUMBERS
的掩码值功能 (512) 被添加到_parserFeatures
JsonFactory
中的值ObjectMapper
的 ObjectMapper
使用@Autowired
注入(inject)我的bean中还有ALLOW_NON_NUMERIC_NUMBERS
功能已启用
不清楚的是为什么我在解析具有 NaN
的 JSON 时仍然收到以下 Jackson 错误浮点字段的值:
JSON decoding error: Character N is neither a decimal digit number, decimal point, nor "e" notation exponential mark.
我现在正在调试,所以我可能最终会回答我自己的问题。以上细节可能会对来自the GitHub issue的人有所帮助。找到一个线程来拉动,以防它们的功能标志没有被应用。
最佳答案
“问题”是我试图将浮点值映射到Java中的BigDecimal
,但是BigDecimal
没有表示NaN
(或 (-)Inf
)。问题源于 com.fasterxml.jackson.databind.util.TokenBuffer.Parser ,它在 public BigDecimal getDecimalValue() 中执行以下操作:
return BigDecimal.valueOf(n.doubleValue());
最终(在java.match.BigDecimal
中)将 double 值转换为字符串"NaN"
,然后将其传递到BigDecimal
构造函数,它用 NumberFormatException
拒绝它以及我在问题中提到的错误消息:
throw new NumberFormatException("Character " + c
+ " is neither a decimal digit number, decimal point, nor"
+ " \"e\" notation exponential mark.");
就我而言,我很高兴将 NaN
映射到 null
,但我知道这对于每个使用 Jackson 的人来说并不是正确的行为,所以我写了一个自定义解串器来做到这一点:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers;
import java.io.IOException;
import java.math.BigDecimal;
public class NaNSafeBigDecimalDeserializer extends JsonDeserializer<BigDecimal> {
private BigDecimal nanValue = null;
@Override
public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (p.isNaN()) {
return nanValue;
} else {
return NumberDeserializers.BigDecimalDeserializer.instance.deserialize(p, ctxt);
}
}
}
现在我可以使用 @JsonDeserialize(using = NaNSafeBigDecimalDeserializer.class) 注释我的
。BigDecimal
字段
关于spring-boot - 如何自定义 Jackson ObjectMapper 以在 Spring Boot 2.0 中允许 NaN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63899402/