Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở Phù hợp với người mới
#37,503 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

  • #37507 của @zsewasdsdsd — đã đóng, không merge

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
70/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java, spring
Lĩnh vực
backend

Hướng nghiên cứu

Lỗ hổng nằm ở JacksonJsonDecoder trong org.springframework.http.codec.json; khác với JacksonJsonEncoder, lớp này không bao giờ đăng ký ProblemDetailJacksonMixin trong cả constructor mặc định lẫn constructor nhận JsonMapper.Builder. Trước tiên hãy so sánh hai lớp này cạnh nhau, sau đó xem các test codec hiện có cho việc giải mã ProblemDetail để xác định nơi đặt một test tương tự cho decoder. Hoàn thành khi một WebClient được xây dựng với codec mặc định giữ nguyên các thành viên mở rộng trong getProperties(), được tái hiện bằng mẫu noojung/webclient-problemdetail-mixin-repro. Lưu ý rằng một PR (#37507) đã được mở và đóng mà không được hợp nhất, vì vậy hãy kiểm tra luồng thảo luận trước khi tạo PR trùng lặp.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Java
Star
60.3k
Fork
38.7k
Merge trung bình
1 ngày 9 giờ
Pull request đã merge (30 ngày)
34

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của spring-projects/spring-framework

Tất cả issue của spring-projects/spring-framework

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.