Jackson 2.15(v2.15.0-rc1 已发布)具有一组应用于输入的默认限制。违反这些限制的输入文件将导致解析异常。
spring-boot 将需要考虑这些限制是否可以,或者您是否需要提供一种配置 Jackson StreamReadConstraints 的方法。
Jackson 2.15(v2.15.0-rc1 已发布)具有一组应用于输入的默认限制。违反这些限制的输入文件将导致解析异常。
spring-boot 将需要考虑这些限制是否可以,或者您是否需要提供一种配置 Jackson StreamReadConstraints 的方法。
感谢您提出这个问题,@pjfanning。
在ObjectMapper
Spring Boot 运行的层面上,我不太明白如何配置约束。据我所知,它们必须配置在JsonFactoryBuilder
用于创建 的 上,而JsonFactory
该 又用于创建ObjectMapper
.理想情况下,这JsonFactory
应该是一个由.我不知道如何创建一个具有本身已使用相同创建的自定义。MappingJsonFactory
ObjectMapper
ObjectMapper
JsonFactory
ObjectMapper
@cowtowncoder 如果您有时间的话,能否请您为我们指出正确的方向?
MappingJsonFactory
从现有的构造一个ObjectMapper
,然后尝试覆盖StreamReadConstraints
-MappingJsonFactory
目前不允许。
我不确定这是否是 jackson-databind 应该有的东西,但 @cowtowncoder 可能会有不同的看法。
如果您无法重构代码,您可以子类化 jackson-databindMappingJsonFactory
并添加一个方法来覆盖StreamReadConstraints
.
@wilkinsona 你能强调一些你担心的代码吗?我查看了 spring-boot,我所能找到的只是大量使用new ObjectMapper()
.
相反new ObjectMapper()
,您可能会发现拥有一个通用的好主意ObjectMapperFactory
,这样可以更轻松地new ObjectMapper()
用类似的东西替换所有调用ObjectMapperFactory.createObjectMapper()
。
private static JsonFactory JSON_FACTORY;
// add some code to create JSON_FACTORY with your preferred StreamReadConstraints settings
public static createObjectMapper() {
return JsonMapper.builder(JSON_FACTORY).build();
}
我的担忧是一般性的,并没有真正关注 Spring Boot 代码的任何特定区域。如果 Jackson 中有一种用于配置约束的机制,那么根据我们过去配置 Jackson 的经验,我希望我们能够毫无困难地使用它。这是一种配置机制,与 Jackson 在我正在寻找的其他各个领域提供的配置机制类似。
如果说有一个区域可能值得特别关注,那就是 及其周边地区org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
。此自动配置应用用户的spring.jackson.*
应用程序属性并广泛使用 Spring 框架Jackson2ObjectMapperBuilder
来实现此目的。如果约束需要可配置,那么一些新spring.jackson.*
属性将是用户这样做的明显方法。我还不知道如何将这些属性应用到新ObjectMapper
实例或现有实例。
Jackson 正在努力使对象映射器变得不可变。您可能需要重新考虑在该级别重新配置的想法。工厂和建筑商是 Jackson 配置发生的地方,或者是事情发生的地方。
好的,虽然 @pjfanning 是正确的,因为我们正在转向基于构建器的配置,但出于兼容性原因,确实需要对旧式直接配置提供一些支持。对于新功能,这可能不需要,但StreamReadConstraints
我认为我们确实需要一些东西。 Jackson 3.x(仅)将提供/要求完全不变性;在此之前,只能使用具有部分优势的构建器。
我将提出一个jackson-core
问题,以确保实际上有一种方法可以通过直接设置配置JsonFactory
——我确实相信期望框架切换到构建器风格的构造(更重要的是,将其暴露给用户)是不切实际的杰克逊2.x
编辑:创建https://github.com/FasterXML/jackson-core/issues/962
感谢 @pjfanning 的尽职尽责:我认为这是 2.15.0 Final 必须解决的问题,并且现在是一个很好的解决方案(而不是发布后)。
@wilkinsona 我确实添加了明显的 2.x 非构建器机制(请参阅https://github.com/FasterXML/jackson-core/issues/962),即JsonFactory.setStreamReadConstraints()
.它将在 2.15.0-rc2 中。感谢您概述了这个明显的差距(事后看来,尽管我真的应该提前看到它)。
与往常一样,我们非常感谢 Spring Boot 团队的帮助:尽管我希望 2.15.0 尽快完成,但我也希望避免匆忙和破坏有价值的用户社区的现有使用情况。
非常感谢,@cowtowncoder。
使用新的 setter,人们可以在 Spring Boot 应用程序中配置约束,而无需在 Boot 中进行任何更改:
@Bean
Jackson2ObjectMapperBuilderCustomizer customStreamReadConstraints() {
return (builder) -> builder.postConfigurer((objectMapper) -> objectMapper.getFactory()
.setStreamReadConstraints(StreamReadConstraints.builder().maxNestingDepth(2000).build()));
}
这将确保ObjectMapper
通过自动配置创建的任何Jackson2ObjectMapperBuilder
内容的最大嵌套深度为 2000。如果调整它们是常见要求,我们仍然可以考虑为这三个约束添加一些配置属性。
正确的@wilkinsona,这就是想法。
我们添加了一个Jackson2ObjectMapperBuilderCustomizer
来修改最大字符串长度,就像 @wilkinsona提到的那样,但我们在使用注入的 ObjectMapper 的测试中没有看到这一点。我们还尝试过StreamReadConstraints.overrideDefaultStreamReadConstraints
在应用程序启动时强制覆盖,但同样没有成功。仍触及 20,000,000 的上限。
@Configuration
public class JacksonConfig {
@Bean
Jackson2ObjectMapperBuilderCustomizer customStreamReadConstraints() {
return (builder) -> builder.postConfigurer((objectMapper) -> objectMapper.getFactory()
.setStreamReadConstraints(StreamReadConstraints.builder().maxStringLength(100000000).build()));
}
}
public static void main(String[] args) {
StreamReadConstraints.overrideDefaultStreamReadConstraints(
StreamReadConstraints.builder().maxStringLength(100000000).build()
);
SpringApplication.run(ApiApplication.class, args);
}
我可以让它工作的唯一方法是覆盖静态上下文中的默认值,例如
@Configuration
public class JacksonConfig {
static {
StreamReadConstraints.overrideDefaultStreamReadConstraints(
StreamReadConstraints.builder().maxStringLength(100000000).build()
);
}
}
@jamesdh 我无法重现您在这两种情况下描述的行为。如果overrideDefaultStreamReadConstraints
不起作用,听起来好像有其他东西正在配置约束并阻止覆盖的默认值生效。请跟进 Stack Overflow 上的问题,其中包括重现该问题的最小示例。
@wilkinsona我开始overrideDefaultStreamReadConstraints
工作,但必须从静态上下文中调用它。我猜这意味着第 3 方依赖项中的其他一些 bean/config 可能是原因?我们的代码中没有任何其他内容涉及 ObjectMapper 配置。
这确实是杰克逊的问题,但据我所知,对默认值的更改应该会影响com.fasterxml.jackson.core.JsonFactory
此后创建的所有内容。正如我上面所说,请关注 Stack Overflow,因为这个问题不适合这个问题。
我认为这个问题应该在最初的更改完成后关闭。
如果有后续问题,请将问题提交到适当的位置。
我想保持这个问题的开放,看看是否有足够的兴趣来spring.jackson.*
配置约束的某些配置属性。与此同时,使用定制器或提前调用StreamReadConstraints.overrideDefaultStreamReadConstraints
仍然是推荐的方法。
我们刚刚遇到了这种情况。收到已达到的约束限制。能够通过属性来设置它会很好,因为我们所做的大多数配置都是通过这些属性进行的。
根据设计,Jackson 并没有提供太多全局配置——它通常作为组件嵌入,因此全局配置往往会破坏非预期位置的使用。
因此 Jackson 端不会添加对属性配置的支持。
编辑:请忽略,根据 @wilkinsona 评论,我对问题感到困惑;与杰克逊一方无关。 Spring 确实有很多相关的可配置性。
@cowtowncoder,我假设 @jjstreet 指的是 Spring Boot 属性。我们已经提供了几个用于配置ObjectMapper
实例的方法,并且可以添加它们以为其流读取约束提供基于属性的配置。
@wilkinsona 感谢您指出这一点 - 是的,我应该注意问题存在的地方,而不仅仅是查看标题和更新:)
@cowtowncoder,我假设 @jjstreet 指的是 Spring Boot 属性。我们已经提供了几个用于配置
ObjectMapper
实例的方法,并且可以添加它们以为其流读取约束提供基于属性的配置。
这将是非常有用的。我时不时地会达到某些极限。将相同的配置类复制到每个微服务并不是最理想的。发布一个能够通过属性启用配置的 jar 并将其作为依赖项包含在每个应用程序中的问题甚至更大。
我想说的是,我们能够通过使用建议的定制器类来绕过流限制约束。
这样的财产会存在于哪里?spring.jackson.deserialization.*
?
我不确定,但它不可能是spring.jackson.deserialization
财产,因为它们是Map<DeserializationFeature, Boolean>
.我们得考虑一下。