如何启用"ALLOW_NUMERIC_LEADING_ZEROS"功能以允许在 JSON 请求正文中使用前导零?



根据JSON规范,我知道JSON中的整数中不允许使用前导零。但根据杰克逊的文档,杰克逊图书馆中有一个属性,即ALLOW_NUMERIC_LEADING_ZEROS启用后,在找到前导零时不会引发异常。

我通过设置以下属性ALLOW_NUMERIC_LEADING_ZEROS启用了该属性,但仍然收到错误:Leading zeroes not allowed

spring.jackson.parser.ALLOW_NUMERIC_LEADING_ZEROS=true

相关日志:

Caused by: com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed
at [Source: (PushbackInputStream); line: 8, column: 17]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804) ~[jackson-core-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:663) ~[jackson-core-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.core.base.ParserMinimalBase.reportInvalidNumber(ParserMinimalBase.java:539) ~[jackson-core-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._verifyNoLeadingZeroes(UTF8StreamJsonParser.java:1489) ~[jackson-core-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._parsePosNumber(UTF8StreamJsonParser.java:1341) ~[jackson-core-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextFieldName(UTF8StreamJsonParser.java:1025) ~[jackson-core-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:376) ~[jackson-databind-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127) ~[jackson-databind-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369) ~[jackson-databind-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001) ~[jackson-databind-2.9.4.jar:2.9.4]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072) ~[jackson-databind-2.9.4.jar:2.9.4]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 63 more

我通过执行以下代码验证了属性ALLOW_NUMERIC_LEADING_ZEROS是否已启用:

@Autowired
private ObjectMapper objectMapper;
@PostMapping(path = "random_path", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> fun123( @RequestBody RandomClass obj) throws Exception {
log.info(" isEnabled = " + objectMapper.getFactory().isEnabled(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS));
log.info(" isEnabled = " + objectMapper.isEnabled(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS));
/*
When correct request is given i.e. no leading zeroes in json body , then this function is successfully executed and
output is true for above two statements  => i.e. feature 'ALLOW_NUMERIC_LEADING_ZEROS' is enabled.
When leading zeroes are present in json request body, this function is not executed as an exception 'HttpMessageNotReadableException'
is generated with error message 'Invalid numeric value: Leading zeroes not allowed'
*/
....
}

根据UTF8StreamJsonParser.java的代码,启用此属性时,应该不会发生异常,但我不确定为什么会发生这种情况!知道这背后的原因是什么吗?

来自UTF8StreamJsonParser.java的相关代码:

/**
* Method called when we have seen one zero, and want to ensure
* it is not followed by another
*/
private final int _verifyNoLeadingZeroes() throws IOException
{
// Ok to have plain "0"
if (_inputPtr >= _inputEnd && !_loadMore()) {
return INT_0;
}
int ch = _inputBuffer[_inputPtr] & 0xFF;
// if not followed by a number (probably '.'); return zero as is, to be included
if (ch < INT_0 || ch > INT_9) {
return INT_0;
}
// [JACKSON-358]: we may want to allow them, after all...
if (!isEnabled(Feature.ALLOW_NUMERIC_LEADING_ZEROS)) {
reportInvalidNumber("Leading zeroes not allowed");
}
...
}

杰克逊图书馆 使用的版本 : 2.9.4

只需将以下属性放在您的application.properties文件中

即可
spring.jackson.parser.allow-numeric-leading-zeros=true

如果未设置默认值,您可以通过以下属性将杰克逊设置为默认转换器

spring.http.converters.preferred-json-mapper=jackson

这很可能是由于Spring端点使用的ObjectMapper配置与注入字段的映射器不同。 为什么会这样我不能说 - 也许Spring用户列表可以提供帮助。

MappingJackson2HttpMessageConverter默认情况下使用Jackson2ObjectMapperBuilder类来构建ObjectMapper类的新实例。要覆盖和使用容器中的ObjectMapper,我们需要覆盖JSON转换器:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Configuration
public class JacksonMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired
private ObjectMapper objectMapper;
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper);
return converter;
}
@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
}

请参阅使用 Spring Boot 和 Spring MVC 自定义 HttpMessageConverters。从现在开始,您应该能够解析带有前导零的数字。

对于遇到该问题并正在寻找更新的工作解决方案的人来说,这只是一个说明:

  1. 在 maven 中导入最新版本的 fasterxml jackson(截至今天的 2.11.0):

    <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.11.0</version> </dependency>

  2. 创建映射器对象:

    ObjectMapper objectMapper = new ObjectMapper();

  3. 允许数字使用前导零(未弃用的版本):

    objectMapper.enable(JsonReadFeature.ALLOW_LEADING_ZEROS_FOR_NUMBERS.mappedFeature());

二手进口:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.json.JsonReadFeature;

请记住,这将修剪前导 0。如果要保留它们,则 json 值不应为数字。

相关内容

  • 没有找到相关文章

最新更新