Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决

简介: 本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。

本文主要介绍在Spring Cloud Gateway Server Web MVC中报错“Unsupported transfer encoding: chunked”问题的原因,及解决方案。

org.apache.hc.core5.http.NotImplementedException: Unsupported Unsupported transfer encoding: chunked 错误通常是由于 Feign 依赖的 HTTP 客户端与服务端使用的 chunked 传输编码不兼容 导致的。具体原因和解决方案如下:

原因分析

基于Spring Cloud Gateway Server Web MVC的API网关问题控制台输出报错信息如下:

org.apache.hc.core5.http.NotImplementedException: Unsupported transfer encoding: chunked
    at org.apache.hc.core5.http.impl.DefaultContentLengthStrategy.determineLength(DefaultContentLengthStrategy.java:90) ~[httpcore5-5.3.4.jar:5.3.4]
    at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.receiveResponseEntity(DefaultBHttpClientConnection.java:355) ~[httpcore5-5.3.4.jar:5.3.4]
    at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:213) ~[httpcore5-5.3.4.jar:5.3.4]
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.lambda$execute$0(InternalExecRuntime.java:236) ~[httpclient5-5.4.4.jar:5.4.4]
    at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:791) ~[httpclient5-5.4.4.jar:5.4.4]
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:233) ~[httpclient5-5.4.4.jar:5.4.4]

虽然错误是报在API网关,但实际是需要在微服务中去解决。问题原因如下:

HTTP 中的 chunked 传输编码用于动态分块传输数据(适用于数据大小不确定的场景)。该错误表明:

  • 服务端返回的响应使用了 Transfer-Encoding: chunked 编码。
  • Feign 客户端使用的 HTTP 客户端(如 Apache HttpClient 5.x)不支持或未正确配置 chunked 编码处理。

解决方案

REST接口类型尽量采用具体类型,避免 Feign 客户端调用过程中导致推导类型失真。

例如:

@FeignClient(
        name = "rednote-content-microservice",
        fallback = ContentServiceClientFallback.class // 指定降级实现类
)
public interface ContentServiceClient {
   
    @GetMapping("/note/user/{userId}")
    ResponseEntity<?> getNotesWithUser(
            @PathVariable Long userId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "12") int size);
}

改为:

@FeignClient(
        name = "rednote-content-microservice",
        fallback = ContentServiceClientFallback.class // 指定降级实现类
)
public interface ContentServiceClient {
   
    @GetMapping("/note/user/{userId}")
    ResponseEntity<NotesWithUserDto> getNotesWithUser(
            @PathVariable Long userId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "12") int size);
}
@GetMapping("/user/{userId}")
public ResponseEntity<?> getNotesWithUser(
        @PathVariable Long userId,
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "12") int size) {
   
    ResponseEntity<UserDto> response = userServiceClient.findByUserId(userId);
    UserDto user = response.getBody();

    // 获取用户笔记列表(分页)
    Page<Note> notePage = noteService.getNotesByUser(userId, page - 1, size);

    // 转换为 DTO
    List<NoteExploreDto> noteExploreDtoList = notePage.map(note -> noteService.toExploreDto(note, user)).getContent();

    Map<String, Object> map = new HashMap<>();
    map.put("user", user);
    map.put("noteList", noteExploreDtoList);
    map.put("currentPage", page);
    map.put("totalPages", notePage.getTotalPages());

    return ResponseEntity.ok()
            .body(map);
}

改为:

@GetMapping("/user/{userId}")
public ResponseEntity<?> getNotesWithUser(
        @PathVariable Long userId,
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "12") int size) {
   
    ResponseEntity<UserDto> response = userServiceClient.findByUserId(userId);
    UserDto user = response.getBody();

    // 获取用户笔记列表(分页)
    Page<Note> notePage = noteService.getNotesByUser(userId, page - 1, size);

    // 转换为 DTO
    List<NoteExploreDto> noteExploreDtoList = notePage.map(note -> noteService.toExploreDto(note, user)).getContent();

    NotesWithUserDto dto = new NotesWithUserDto(user, noteExploreDtoList, page, notePage.getTotalPages());
    ResponseEntity<NotesWithUserDto> responseEntity = ResponseEntity.ok()
            .body(dto);
    return responseEntity;
}

参考引用

目录
相关文章
|
安全 Java API
深入解析 Spring Security 配置中的 CSRF 启用与 requestMatchers 报错问题
本文深入解析了Spring Security配置中CSRF启用与`requestMatchers`报错的常见问题。针对CSRF,指出默认已启用,无需调用`enable()`,只需移除`disable()`即可恢复。对于`requestMatchers`多路径匹配报错,分析了Spring Security 6.x中方法签名的变化,并提供了三种解决方案:分次调用、自定义匹配器及降级使用`antMatchers()`。最后提醒开发者关注版本兼容性,确保升级平稳过渡。
1738 2
|
11月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。
|
11月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
存储 安全 Java
如何在 Spring Web 应用程序中使用 @SessionScope 和 @RequestScope
Spring框架中的`@SessionScope`和`@RequestScope`注解用于管理Web应用中的状态。`@SessionScope`绑定HTTP会话生命周期,适用于用户特定数据,如购物车;`@RequestScope`限定于单个请求,适合无状态、线程安全的操作,如日志记录。合理选择作用域能提升应用性能与可维护性。
478 1
|
存储 NoSQL Java
探索Spring Boot的函数式Web应用开发
通过这种方式,开发者能以声明式和函数式的编程习惯,构建高效、易测试、并发友好的Web应用,同时也能以较小的学习曲线迅速上手,因为这些概念与Spring Framework其他部分保持一致性。在设计和编码过程中,保持代码的简洁性和高内聚性,有助于维持项目的可管理性,也便于其他开发者阅读和理解。
321 0
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
416 0
|
JSON 前端开发 Java
第05课:Spring Boot中的MVC支持
第05课:Spring Boot中的MVC支持
494 0
|
前端开发 IDE Java
Spring MVC 中因导入错误的 Model 类报错问题解析
在 Spring MVC 或 Spring Boot 开发中,若导入错误的 `Model` 类(如 `ch.qos.logback.core.model.Model`),会导致无法解析 `addAttribute` 方法的错误。正确类应为 `org.springframework.ui.Model`。此问题通常因 IDE 自动导入错误类引起。解决方法包括:删除错误导入、添加正确包路径、验证依赖及清理缓存。确保代码中正确使用 Spring 提供的 `Model` 接口以实现前后端数据传递。
611 0
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
11月前
|
缓存 JSON NoSQL
别再手写过滤器!SpringCloud Gateway 内置30 个,少写 80% 重复代码
小富分享Spring Cloud Gateway内置30+过滤器,涵盖请求、响应、路径、安全等场景,无需重复造轮子。通过配置实现Header处理、限流、重试、熔断等功能,提升网关开发效率,避免代码冗余。
841 1