SpringCloud Gateway 打印请求和响应信息,直接Copy直接用

该博客主要介绍了如何使用Spring Cloud Gateway的全局过滤器实现对HTTP请求和响应的拦截。在请求过滤器中,捕获了POST和GET请求的参数,并记录了请求头和请求体信息。在响应过滤器中,对响应内容进行了读取,转换并记录,同时对响应数据进行了修改。这两部分过滤器都具有特定的优先级设置,确保了拦截操作的顺序和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请求:

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.UnsupportedEncodingException;
import java.net.URI;

/**
 * 在filter中获取前置预言里面的请求body
 */
@Component
@Slf4j
public class WrapperRequestGlobalFilter implements GlobalFilter, Ordered {
    /**
     * 优先级最高
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        URI URIPath = request.getURI();
        String path = request.getPath().value();
        String method = request.getMethodValue();
        HttpHeaders header = request.getHeaders();
        log.info("");
        log.info("***********************************请求信息**********************************");
        log.info("请求request信息:URI = {}, path = {},method = {},header = {}。", URIPath, path, method, header);
        if ("POST".equals(method)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        try {
                            String bodyString = new String(bytes, "utf-8");
                            log.info("请求参数:" + bodyString);
                            exchange.getAttributes().put("POST_BODY", bodyString);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        DataBufferUtils.release(dataBuffer);
                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer = exchange.getResponse().bufferFactory()
                                    .wrap(bytes);
                            return Mono.just(buffer);
                        });

                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        log.info("****************************************************************************\n");
                        return chain.filter(exchange.mutate().request(mutatedRequest)
                                .build());
                    });
        } else if ("GET".equals(method)) {
            MultiValueMap<String, String> queryParams = request.getQueryParams();
            log.info("请求参数:" + queryParams);
            log.info("****************************************************************************\n");
            return chain.filter(exchange);
        }
        log.info("****************************************************************************\n");
        return chain.filter(exchange);
    }
}

响应:

import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Component
@Slf4j
public class WrapperResponseGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public int getOrder() {
        //-1 is response write filter, must be called before that
        return -2;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取response的 返回数据
        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();
        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                    return super.writeWith(fluxBody.map(dataBuffer -> {
                        byte[] content = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(content);
                        //释放掉内存
                        DataBufferUtils.release(dataBuffer);
                        //responseData就是下游系统返回的内容,可以查看修改
                        String responseData = new String(content, Charset.forName("UTF-8"));
                        log.info("");
                        log.info("***********************************响应信息**********************************");
                        log.info("响应内容:{}", responseData);
                        log.info("****************************************************************************\n");
                        byte[] uppedContent = new String(content, Charset.forName("UTF-8")).getBytes();
                        return bufferFactory.wrap(uppedContent);
                    }));
                } else {
                    log.error("响应code异常:{}", getStatusCode());
                }
                return super.writeWith(body);
            }
        };
        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }
}
<think>嗯,用户想了解或者使用Pig4Cloud相关的信息,特别是教程介绍。首先,我需要确认用户的需求是什么。他们可能是一个开发者,正在寻找一个基于Spring Cloud的权限管理系统,或者是想了解如何快速搭建微服务架构。用户提到的Pig4Cloud是基于Spring Security的实践,可能他们需要知道如何集成安全模块,或者是系统的架构设计。 接下来,我应该先介绍Pig4Cloud的基本情况,包括它的技术栈核心功能。根据提供的引用,Pig4Cloud使用了Spring Cloud 2022、Spring Boot3、Alibaba组件MyBatisPlus,支持SAAS的RBAC权限管理,还有容器化技术生产实践如Lambda等。这些都是关键点,需要简明扼要地概括。 然后,用户可能需要入门教程,所以分步骤说明如何快速启动。引用3提到了启动流程,涉及SecurityAutoConfigurationSecurityFilterChain的构建,这里可能需要简化,让用户知道克隆代码库、配置数据库启动核心模块即可。同时,引用5中的代码示例可以帮助他们理解数据操作,比如使用UpdateWrapper进行更新,这时候可能需要提到MyBatisPlus的使用方法。 接下来,系统架构部分需要解释各个模块的作用,比如认证中心、网关、业务模块等,这样用户能了解整体结构。安全机制部分,引用4详细描述了登录流程Filter链,这里可以总结OAuth2JWT的使用,以及FilterChainProxy的处理流程,但不用太深入,保持易懂。 关于生产实践,容器化支持代码规范是重点,用户可能关心如何部署到Kubernetes或者Docker,以及代码风格是否符合团队要求。最后,相关的问题部分需要引导用户深入,比如权限管理如何扩展,如何处理高并发,或者如何定制安全策略,这些都能帮助他们进一步探索。 需要确保回答结构清晰,分点说明,并且引用正确的来源。同时,避免使用过多技术术语,保持语言通俗。还要检查是否符合用户的要求,比如使用中文,正确的LaTeX格式,以及生成相关问题。可能还需要确认引用的标记是否正确,比如引用3引用4对应启动流程登录流程的部分。 最后,总结用户可能需要的资源,比如官方文档社区支持,帮助他们进一步学习。整个思考过程需要确保信息准确,基于提供的引用内容,同时以用户友好的方式呈现,解决他们的核心问题。</think>### Pig4Cloud 介绍与使用教程 #### 一、Pig4Cloud 基础介绍 Pig4Cloud 是基于 Spring Cloud 微服务架构的企业级开发平台,主要包含以下核心特性: 1. **技术栈** - 采用 $Spring\ Cloud\ 2022 + Spring\ Boot\ 3$ 最新框架 - 集成 MyBatis-Plus 实现 ORM 层高效开发 - 支持容器化部署($Docker/Kubernetes$) 2. **权限管理** - 基于 SAAS 模式的 RBAC 权限系统[^1] - 支持 OAuth2 协议 JWT 令牌认证[^4] - 提供细粒度的数据权限控制 3. **生产实践** - 内置 Lambda、Stream API 等现代化编程模式 - 提供 Webflux 响应式编程支持 #### 二、快速入门教程 ##### 步骤1:环境准备 ```bash # 克隆代码库 git clone https://github.com/pig4cloud/pig.git ``` 需配置 MySQL 数据库 Redis 缓存服务。 ##### 步骤2:核心模块启动 1. **认证中心 (pig-auth)** 引用[^3]中描述的启动流程: ```java // SecurityAutoConfiguration 加载安全配置 @Configuration @ConditionalOnClass(WebSecurityConfigurerAdapter.class) public class SecurityAutoConfiguration { // 自动构建 SecurityFilterChain } ``` 2. **网关服务 (pig-gateway)** 负责路由分发与请求过滤[^2]。 ##### 步骤3:数据操作示例 引用[^5]中 MyBatis-Plus 的更新操作: ```java UpdateWrapper<Station> wrapper = new UpdateWrapper<>(); wrapper.lambda().eq(Station::getId, id) .set(Station::getPlace, "北京") .set(Station::getNumber, null); stationService.update(wrapper); ``` #### 三、系统架构解析 $$系统架构 = 认证中心 + 网关服务 + 业务模块 + 监控体系$$ 通过 $OAuth2.0$ 实现统一认证,使用 $Spring\ Security$ 的 FilterChainProxy 进行请求过滤。 #### 四、安全机制详解 1. **登录流程** - 请求经过 19 层安全过滤器链 - 核心过滤器: - `OAuth2ClientAuthenticationFilter`(客户端校验) - `BearerTokenAuthenticationFilter`(JWT 解析) 2. **令牌签发** 采用 HMAC-SHA256 算法生成 JWT: $$token = header(base64).payload(base64).signature(加密)$$ #### 五、生产实践建议 1. **容器化部署** ```dockerfile FROM openjdk:17 COPY target/pig-auth.jar /app.jar ENTRYPOINT ["java","-jar","/app.jar"] ``` 2. **代码规范** 强制使用 Checkstyle 进行代码格式校验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值