Enable body filter codec encoding customization via CodecCustomizer#4151
Conversation
|
Can you help me understand why you would want to switch the gateway from using Jackson 3 to Jackson 2? |
|
Gateway requires Jackson 3 |
|
@ryanjbaxter @spencergibb Thank you for your feedback. I apologize that the PR described a very specific scenario, which may have made the issue seem narrower than it actually is. The underlying problem is likely more general — specifically, that the codec encoder cannot be configured consistently. Our switch from Jackson3 back to Jackson2 is currently a transitional state during our upgrade process. While upgrading Gateway, we want to avoid any unexpected changes in the response body received by downstream callers (and similarly, avoid changes in the forwarded request body received by backend services). Since Jackson3 and Jackson2 have some differences in encoding behavior, these differences can be mitigated by enabling: spring.jackson.use-jackson2-defaults=true This allows us to use Jackson3 while still preserving Jackson2's default behavior. So our actual goal is not necessarily to keep using Jackson2 itself, but rather to preserve the default serialization behavior that Jackson2 previously provided. |
So really this PR is enabling configuring the codec encoder vie Just to be clear setting |
|
@ryanjbaxter Thanks for the clarification. Yes, the core purpose of this PR is to make body filter encoding follow the codec configuration provided through I've updated the PR title and description to better reflect that focus. |
|
Thanks. We will need to add tests to the PR. Also we cannot change public methods/constructors. We need to keep the existing ones in place, mark them as deprecated, and add new ones. |
|
@ryanjbaxter I added some unit tests and found two behaviors that need clarification.
|
May I ask why Both to switch from Jackson 3 back to Jackson 2 directly. Even when continuing to use Jackson 3, after this fix, configuring: would also take effect and preserve Jackson 2-style defaults during encoding, since it is also applied through |
|
We built and tested spring cloud gateway against the defaults of spring boot 4 which uses Jackson 3. We never guaranteed or test spring cloud gateway 5.0.x to be compatible with Jackson 2. So if you try it we cannot guarantee it will work, nor are we guaranteeing we will support any problems it may cause |
Oh, Thanks for the clarification — I can see the concern more clearly now. My understanding is that as long as Spring Cloud Gateway follows Spring Boot’s codec integration model consistently, the behavior itself should generally be guaranteed by Spring Boot. At the moment, the issue seems to be that SCG follows the codec customization path during decode, but not consistently during encode. So from my perspective, this may be less about officially supporting Jackson 2, and more about keeping codec customization behavior consistent across decode and encode paths. |
|
We are fine supporting the customizations but again I am not sure we are going to say we support Jackson 2 at this point |
There was a problem hiding this comment.
Pull request overview
This PR updates WebFlux body filter encoding paths to use codec customizations, aligning modified request/response/function routing body serialization with configured Spring Boot codec behavior.
Changes:
- Adds
CodecCustomizer-aware constructors andExchangeStrategiesusage for body inserter encoding. - Wires codec customizers through Gateway auto-configuration.
- Adds integration tests covering codec customization for function routing, modify request body, and modify response body.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/support/BodyInserterContext.java |
Removes obsolete TODO now that custom strategies are supported. |
spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/filter/FunctionRoutingFilter.java |
Applies customized exchange strategies when writing function responses. |
spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactory.java |
Applies customized exchange strategies when rewriting request bodies. |
spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java |
Applies customized exchange strategies when rewriting response bodies. |
spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java |
Passes ordered codec customizers into body filter factories. |
spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/config/GatewayFunctionAutoConfiguration.java |
Passes ordered codec customizers into function routing filter. |
spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/test/TestCodecCustomizerConfiguration.java |
Adds shared test configuration for verifying custom JSON encoding. |
spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/filter/FunctionRoutingFilterTests.java |
Adds coverage for customized encoding in function routing. |
spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyRequestBodyGatewayFilterFactoryTests.java |
Adds coverage for customized encoding in request body rewriting. |
spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactoryTests.java |
Adds coverage for customized encoding in response body rewriting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Got it, we understand that Jackson 2 is already in a deprecated state, and in our case this is only a temporary transition scenario. We’ll gradually migrate fully to Jackson 3 as well. |
| * @author Junghoon Song | ||
| */ | ||
| @SpringBootTest(webEnvironment = RANDOM_PORT, properties = "spring.http.codecs.max-in-memory-size=13") | ||
| @SpringBootTest(webEnvironment = RANDOM_PORT, properties = "spring.http.codecs.max-in-memory-size=40") |
There was a problem hiding this comment.
Why is this such a big increase?
There was a problem hiding this comment.
I've updated the changes mentioned above based on the feedback. Please take a look.
Regarding the question in this comment:
The previous limit was too small, and the new tests I added also hit this limit.
My understanding is that the size restriction only needs to be low enough to trigger the test_modify_request_body_to_large test case. I also noticed that ModifyResponseBodyGatewayFilterFactoryTests uses 40, so I aligned the value here for consistency.
There was a problem hiding this comment.
I think you might be able to set it to 15 and the tests will work, can you try that?
There was a problem hiding this comment.
Yes, it worked. Thanks!
…coder. Signed-off-by: qnnn <qiunan@cmbchina.com>
Signed-off-by: qnnn <qiunan@cmbchina.com>
Signed-off-by: qnnn <qiunan@cmbchina.com>
Signed-off-by: qnnn <qiunan@cmbchina.com>
Signed-off-by: qnnn <qiunan@cmbchina.com>
…ing' Signed-off-by: qnnn <qiunan@cmbchina.com>
|
LGTM @spencergibb mind taking another quick look? |
This PR enables body filters to use codec encoders customized via
CodecCustomizer.Previously, body filters did not consistently apply configured codec customizations during encoding. As a result, encoding in some body filters could still fall back to default codec behavior instead of using the configured codec encoder customization.
This change ensures that body filter encoding also follows the configured codec customization, making codec behavior consistent between decoding and encoding.