loveqq 作为网关框架时如何修改请求体 / 响应体,和 spring 又有什么区别?

前言

loveqq-framework 作为网关框架使用时,修改响应体是一个十分常见的需求。

而作为一个使用过 spring gateway 的作者,我觉得 spring gateway 中修改响应体实在是复杂,因此 loveqq 框架在实现修改响应体时,则力求简洁易用。

如何实现?

loveqq 框架修改响应体是基于网关过滤器(GatewayFilter)实现的,因此要实现修改响应体只需两步:

1、自定义网关过滤器

2、给指定的路由配置这个过滤器

下面给出相应的示例:

网关过滤器:

java 复制代码
    /**
     * 这里手动设置 bean name 为:FormatResponseBody
     * 后面配置时会用到,当然自动生成的也可以,只是名称比较长而已
     * <p>
     * 注意:这里设置过滤器优先级为最低级别,因为需要转发请求之后才能获取下游响应体,而转发过滤器默认的级别比较低
     */
    @Order(Integer.MAX_VALUE)
    @Component("FormatResponseBody")
    public static class FormatResponseBodyGatewayFilter implements GatewayFilter {

        @Override
        public Mono<Void> doFilter(ServerRequest request, ServerResponse response, GatewayFilterChain chain) {
            return chain.doFilter(request, response)
                    .then(Mono.defer(response::getAggregateBody))               // 可以直接获取聚合后的响应体,避免 Flux 分段处理数据
                    .map(e -> {
                        byte[] bytes = NIOUtil.read(e);
                        JSON json = new JSON();
                        json.put("data", new String(bytes));
                        json.put("code", 0);
                        return NIOUtil.from(json.toString());                   // 修改响应体
                    })
                    .flatMap(json -> response.writeBody(Flux.just(json)))       // 响应体写入响应
                    .then();
        }
    }

应用过滤器:

yaml 复制代码
k:
  server:
    gateway:
      routes:
        - uri: lb://demo
          predicates: Path=/api/demo/**
          filters:
            - id: StripPrefix               # 去除 /api
              args:
                stripPrefix: 1
            - id: FormatResponseBody        # 修改响应体

这样就可以了。

响应体校验不通过想抛出异常?

很简单,直接抛出异常就可以了,例如:

java 复制代码
        @Override
        public Mono<Void> doFilter(ServerRequest request, ServerResponse response, GatewayFilterChain chain) {
            return chain.doFilter(request, response)
                    .then(Mono.defer(response::getAggregateBody))               // 可以直接获取聚合后的响应体,避免 Flux 分段处理数据
                    .map(e -> {
                        String body = new String(NIOUtil.read(e));
                        if (body.charAt(0) != '{' || body.charAt(0) != '[') {
                            throw new ResolvableException("not json");
                        }
                        JSON json = new JSON();
                        json.put("data", body);
                        json.put("code", 0);
                        return NIOUtil.from(json.toString());                   // 修改响应体
                    })
                    .flatMap(json -> response.writeBody(Flux.just(json)))       // 响应体写入响应
                    .then();
        }

这样的话,网关会输出正常的错误信息吗?

当然可以,因为网关异常同样可以走 mvc 模式的全局异常处理器进行处理!

java 复制代码
@RestControllerAdvice(supportAny = true)
public class GlobalExceptionHandler {
    /**
     * 异常处理
     *
     * @param request 抽象的统一的请求对象
     * @param e       异常
     * @return 返回错误信息
     */
    @ExceptionHandler
    public String onException(ServerRequest request, Exception e) {
        return e.getClass().getName() + ":" + e.getMessage();
    }
}

看起来相当简洁,几乎和修改请求体没什么区别,但是 spring gateway 修改请求体 / 响应体想必做过的各位懂的都懂。

感兴趣的同学可以尝试一下~

相关推荐
adinnet20264 分钟前
深度拆解企业级 Agent 架构:LangGraph + 知识图谱 + 向量检索的协同设计
人工智能·架构·知识图谱
listening77734 分钟前
HarmonyOS 6.1 混沌工程实战:从“故障免疫”到“韧性架构”
华为·架构·harmonyos
晚风吹长发40 分钟前
Docker使用——Docker容器及相关命令
linux·运维·服务器·docker·容器·架构
郝学胜-神的一滴1 小时前
[简化版 GAMES 104] 现代游戏引擎 02:拆解现代游戏引擎5+1层级架构,吃透引擎底层核心逻辑
c++·unity·架构·游戏引擎·图形渲染·unreal engine·系统设计
电子科技圈1 小时前
先进封装、芯粒架构和3D集成——先进异构集成亟需兼具标准化与定制化能力的互联及总线IP解决方案
tcp/ip·设计模式·架构·软件构建·代码规范·设计规范
止语Lab2 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活2 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困2 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn2 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
AI小白Lin2 小时前
33 个 AI 专家全票通过?那问题才刚开始
人工智能·架构