Fra*_*ans 2 jackson spring-boot
将其从GitHub移至此处,因为 Spring 团队仅使用 GitHub 问题来处理错误和功能请求。
根据 Spring Boot文档,只要您没有定义自己的bean ,就应该可以ObjectMapper使用环境属性(例如在 中application.properties)来自定义 Jackson 。spring.jackson.parser.<feature_name>ObjectMapper
我需要激活ALLOW_NON_NUMERIC_NUMBERS解析器功能,因为我正在获取(严格来说无效)JSON NaN,其中包含我希望 Jackson 在 Java 中映射到的浮点字段的值java.lang.Double.NaN。
所以在我的application.properties添加中spring.jackson.parser.ALLOW_NON_NUMERIC_NUMBERS=true,我可以看到它正在被拾取:
JacksonAutoConfiguration正在创建一个Jackson2ObjectMapperBuilderJackson2ObjectMapperBuilder正在 StandardJackson2ObjectMapperBuilderCustomizer拾取我的spring.jackson.parser.ALLOW_NON_NUMERIC_NUMBERS=true财产并将其添加到其features地图中Jackson2ObjectMapperBuilder的build()方法最终会被调用configureFeature,这会导致特征 (512) 的掩码值ALLOW_NON_NUMERIC_NUMBERS被添加_parserFeatures到JsonFactoryObjectMapperObjectMapper在我的 bean 中注入的使用也@Autowired启用了该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.
我现在正在调试,所以我可能最终会回答我自己的问题。上述细节可能是为了帮助来自GitHub 问题的人们找到一个线程,以防他们的功能标志没有被应用。
“问题”是我试图将浮点值映射到BigDecimalJava中,但BigDecimal没有表示NaN(或(-)Inf就此而言)。问题的根源com.fasterxml.jackson.databind.util.TokenBuffer.Parser在于public BigDecimal getDecimalValue():
return BigDecimal.valueOf(n.doubleValue());
Run Code Online (Sandbox Code Playgroud)
最终(在java.match.BigDecimal)将双精度值转换为字符串"NaN",然后将其传递给构造函数,构造函数用 a和我在问题中提到的错误消息BigDecimal拒绝它:NumberFormatException
throw new NumberFormatException("Character " + c
+ " is neither a decimal digit number, decimal point, nor"
+ " \"e\" notation exponential mark.");
Run Code Online (Sandbox Code Playgroud)
就我而言,我很高兴被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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以用 来注释我的BigDecimal字段@JsonDeserialize(using = NaNSafeBigDecimalDeserializer.class)。
| 归档时间: |
|
| 查看次数: |
3134 次 |
| 最近记录: |