Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

`WebClient` with default codecs drops `ProblemDetail` extension members

未关闭 适合新手
#37,503 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

  • #37507 来自 @zsewasdsdsd —— 已关闭,未合并

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
70/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
java, spring
领域
backend

调研方向

问题出在 org.springframework.http.codec.json 下的 JacksonJsonDecoder:与 JacksonJsonEncoder 不同,它在默认构造函数和接收 JsonMapper.Builder 的构造函数中都没有注册 ProblemDetailJacksonMixin。先并排比较这两个类,然后查看现有的 ProblemDetail 解码编解码器测试,以确定解码器的镜像测试应放在哪里。完成标准是:使用默认编解码器构建的 WebClient 能在 getProperties() 中保留扩展成员,并用 noojung/webclient-problemdetail-mixin-repro 中的示例复现。注意,PR(#37507)已经开过但未合并即被关闭,因此在重复提交之前请先查看该讨论串。

由索引模型根据 Issue 内容生成。

描述

status: waiting-for-triage

Overview

While checking that RestClient and WebClient decode ProblemDetail responses correctly, I noticed that a WebClient created with the default codecs (WebClient.create() or WebClient.builder()) drops RFC 9457 extension members: getProperties() returns null, while the standard members are decoded correctly.

This worked with Spring Framework 6.2 (Spring Boot 3.5), so it looks like a regression introduced with the Jackson 3 codecs.

Versions tested

  • Spring Framework 7.0.9 (Spring Boot 4.1.1, Jackson 3): extension members are lost
  • Spring Framework 6.2.11 (Spring Boot 3.5.6, Jackson 2): works as expected

Reproducer

With the sample server running on port 8080, GET /orders/42 returns HTTP 404 with Content-Type: application/problem+json and the following body:

{
  "type": "https://example.com/problems/order-not-found",
  "title": "Order Not Found",
  "status": 404,
  "detail": "Order 42 does not exist",
  "instance": "/orders/42",
  "errorCode": "ORDER_NOT_FOUND",
  "orderId": 42
}

The extension members are lost when decoding the response:

WebClient webClient = WebClient.create("http://localhost:8080");
// Also reproduces with:
// WebClient.builder().baseUrl("http://localhost:8080").build();

WebClientResponseException.NotFound exception = assertThrows(
        WebClientResponseException.NotFound.class,
        () -> webClient.get()
                .uri("/orders/42")
                .retrieve()
                .bodyToMono(Order.class)
                .block());

ProblemDetail problemDetail = exception.getResponseBodyAs(ProblemDetail.class);

assertThat(problemDetail).isNotNull();
assertThat(problemDetail.getProperties())
        .containsEntry("errorCode", "ORDER_NOT_FOUND")
        .containsEntry("orderId", 42);
// 6.2.11: passes
// 7.0.9:  fails because getProperties() returns null

A complete sample (Spring MVC server + WebClient/RestClient tests) is available here: https://github.com/noojung/webclient-problemdetail-mixin-repro

Running ./gradlew test starts the server automatically and fails webClientCreateShouldPreserveProblemDetailProperties and webClientBuilderShouldPreserveProblemDetailProperties.

For comparison, RestClient.create() and the WebClient.Builder auto-configured by Spring Boot both keep the extension members, since JacksonJsonHttpMessageConverter registers the mixin and Boot configures the codecs with a JsonMapper that has it (spring-projects/spring-boot#47298).

Analysis

JacksonJsonEncoder and JacksonJsonHttpMessageConverter register ProblemDetailJacksonMixin in their default and JsonMapper.Builder-based constructors, but JacksonJsonDecoder does not. Since FAIL_ON_UNKNOWN_PROPERTIES is disabled by default in Jackson 3, the extension members are ignored without any error.

With Jackson 2, the default Jackson2JsonDecoder created its mapper through Jackson2ObjectMapperBuilder, which registers the mixin.

Workaround

WebClient webClient = WebClient.builder()
        .codecs(configurer -> configurer.defaultCodecs().jacksonJsonDecoder(new JacksonJsonDecoder(
                JsonMapper.builder().addMixIn(ProblemDetail.class, ProblemDetailJacksonMixin.class))))
        .build();

Related issues

  • #35597
  • spring-projects/spring-boot#47298

Would registering ProblemDetailJacksonMixin in the default and JsonMapper.Builder-based constructors of JacksonJsonDecoder, the same way as in JacksonJsonEncoder, be the right fix? If so, I would be happy to submit a pull request.

主要语言
Java
星标
60.3k
派生
38.7k
平均合并
1 天 9 小时
30 天内合并 PR
34

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

spring-projects/spring-framework 的其他 Issue

查看 spring-projects/spring-framework 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。