• gateway 实现接口日志保存


    1.CachePostBodyFilter将request body 取出来重存

    import io.netty.buffer.UnpooledByteBufAllocator;
    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.NettyDataBufferFactory;
    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.web.reactive.function.server.HandlerStrategies;
    import org.springframework.web.reactive.function.server.ServerRequest;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @Component
    public class CachePostBodyFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest serverHttpRequest = exchange.getRequest();
            String method = serverHttpRequest.getMethodValue();
            if ("POST".equalsIgnoreCase(method)) {
                ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
                Mono<String> bodyToMono = serverRequest.bodyToMono(String.class);
                return bodyToMono.flatMap(body -> {
                    exchange.getAttributes().put("cachedRequestBody", body);
                    ServerHttpRequest newRequest = new ServerHttpRequestDecorator(serverHttpRequest) {
                        @Override
                        public HttpHeaders getHeaders() {
                            HttpHeaders httpHeaders = new HttpHeaders();
                            httpHeaders.putAll(super.getHeaders());
                            httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                            return httpHeaders;
                        }
    
                        @Override
                        public Flux<DataBuffer> getBody() {
                            NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
                            DataBuffer bodyDataBuffer = nettyDataBufferFactory.wrap(body.getBytes());
                            return Flux.just(bodyDataBuffer);
                        }
                    };
                    return chain.filter(exchange.mutate().request(newRequest).build());
                });
            }
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return -21;
        }
    
    }
    
    

    2.LogFilter 收集请求参数和返回参数

    import com.alibaba.fastjson.JSONObject;
    import com.msl.mafa.entity.RequestLog;
    import com.msl.mafa.service.IRequestLogService;
    import com.msl.mafa.utils.DateTimeUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.reactivestreams.Publisher;
    import org.springframework.beans.factory.annotation.Autowired;
    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.server.reactive.ServerHttpRequest;
    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.Date;
    
    @Slf4j
    @Component
    public class LogFilter implements GlobalFilter, Ordered {
    
        @Autowired
        private IRequestLogService iRequestLogService;
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
            try {
                Date startTime = DateTimeUtil.getFormattedDate(new Date(),DateTimeUtil.yyyyMMddHHmmss);
                StringBuilder logBuilder = new StringBuilder();
                StringBuilder requestBody=new StringBuilder();
                ServerHttpRequest serverHttpRequest = exchange.getRequest();
                String method = serverHttpRequest.getMethodValue().toUpperCase();
                logBuilder.append(method).append(",").append(serverHttpRequest.getURI());
                if ("POST".equals(method)) {
                    requestBody.append(exchange.getAttributeOrDefault("cachedRequestBody", ""));
                    if (StringUtils.isNotBlank(requestBody)) {
                        logBuilder.append(",body=").append(requestBody);
                    }
                }else if("GET".equals(method)){
                    MultiValueMap<String, String> queryParams = serverHttpRequest.getQueryParams();
                    logBuilder.append(",body=").append(JSONObject.toJSONString(queryParams));
                    requestBody.append(JSONObject.toJSONString(queryParams));
                }
                ServerHttpResponse serverHttpResponse = exchange.getResponse();
                DataBufferFactory bufferFactory = serverHttpResponse.bufferFactory();
                ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(serverHttpResponse) {
                    @Override
                    public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                        if (body instanceof Flux) {
                            Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
                            return super.writeWith(fluxBody.map(dataBuffer -> {
                                byte[] content = new byte[dataBuffer.readableByteCount()];
                                dataBuffer.read(content);
                                DataBufferUtils.release(dataBuffer);
                                try {
                                    String resp = new String(content, Charset.forName("UTF-8"));
                                    Date endTime = DateTimeUtil.getFormattedDate(new Date(),DateTimeUtil.yyyyMMddHHmmss);
                                    //保存日志到数据库
                                    buildLog(exchange, requestBody.toString(),resp,startTime,endTime);
                                    logBuilder.append(",resp=").append(resp);
                                }catch (Exception e){
                                    log.info("save log err!");
                                    log.info(e.getMessage(),e);
                                }
                                log.info(logBuilder.toString());
                                byte[] uppedContent = new String(content, Charset.forName("UTF-8")).getBytes();
                                return bufferFactory.wrap(uppedContent);
                            }));
                        }
                        return super.writeWith(body);
                    }
                };
                return chain.filter(exchange.mutate().response(decoratedResponse).build());
            }catch (Exception e){
                log.info("logfilter exception!");
                log.info(e.getMessage(),e);
            }
            return chain.filter(exchange);
    
        }
       @Override
        public int getOrder() {
            return -20;
        }
    

    参考:https://blog.csdn.net/autfish/article/details/90637957?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control

  • 相关阅读:
    CMD 已存在的表, 没有主键的 添加主键属性
    回调函数 call_back
    在Ubuntu下安装MySQL,并将它连接到Navicat for Mysql
    F查询和Q查询,事务及其他
    Djabgo ORM
    Diango 模板层
    Django视图系统
    Django简介
    Web 框架
    HTTP协议
  • 原文地址:https://www.cnblogs.com/staystand/p/14788850.html
Copyright © 2020-2023  润新知