springboot gateway 记录请求和响应日志
spring cloud gateway是基于webflux的项目,因而不能跟使用spring mvc一样直接获取request body,因此需要重新构造再转发。
如果我们在spring cloud gateway 封装之前读取了一次request body,比如打印request body日志,在下游获取数据的时候会出现错误:[spring cloud] [error] java.lang.IllegalStateException: Only one connection receive subscriber allowed. 因为request body只能读取一次,它是属于消费类型的。
出现这样的原因是InputStream的read()方法内部有一个postion,标志当前流被读取到的位置,每读取一次,该标志就会移动一次,如果读到最后,read()会返回-1,表示已经读取完了。如果想要重新读取则需要调用reset()方法,position就会移动到上次调用mark的位置,mark默认是0,所以就能从头再读了。调用reset()方法的前提是已经重写了reset()方法,当然能否reset也是有条件的,它取决于markSupported()方法是否返回true,InputStream默认不实现reset(),并且markSupported()默认也是返回false。综上,InputStream默认不实现reset的相关方法,而ServletInputStream也没有重写reset的相关方法,这样就无法重复读取流,这就是我们从request对象中获取的输入流就只能读取一次的原因。
直接上代码
1.实体类
-
import lombok.Data;
-
-
import java.io.Serializable;
-
import java.util.Date;
-
-
-
public class GatewayLog implements Serializable {
-
private static final long serialVersionUID = 1983879536575766072L;
-
/**访问实例*/
-
private String targetServer;
-
/**请求路径*/
-
private String requestPath;
-
/**请求方法*/
-
private String requestMethod;
-
/**协议 */
-
private String schema;
-
/**请求体*/
-
private String requestBody;
-
/**响应体*/
-
private String responseData;
-
/**请求ip*/
-
private String ip;
-
/**请求时间*/
-
private Date requestTime;
-
/**响应时间*/
-
private Date responseTime;
-
/**执行时间*/
-
private long executeTime;
-
/**返回码*/
-
private long code;
-
/**返回数据类型*/
-
private String responseContentType;
-
/**请求数据类型*/
-
private String requestContentType;
-
/**请求用户id*/
-
private String userId;
-
-
}
2.Service
-
public interface AccessLogService {
-
void saveAccessLog(GatewayLog gatewayLog);
-
}
3.AccessLogFilter
-
import cn.hutool.core.collection.CollectionUtil;
-
import com.shouwei.gateway.entity.GatewayLog;
-
import com.shouwei.gateway.service.AccessLogService;
-
import com.shouwei.gateway.utils.IpUtils;
-
import lombok.extern.slf4j.Slf4j;
-
import org.apache.commons.lang.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.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
-
import org.springframework.cloud.gateway.route.Route;
-
import org.springframework.cloud.gateway.support.BodyInserterContext;
-
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
-
import org.springframework.core.Ordered;
-
import org.springframework.core.ResolvableType;
-
import org.springframework.core.io.buffer.*;
-
import org.springframework.http.HttpHeaders;
-
import org.springframework.http.MediaType;
-
import org.springframework.http.codec.HttpMessageReader;
-
import org.springframework.http.codec.multipart.FormFieldPart;
-
import org.springframework.http.codec.multipart.Part;
-
import org.springframework.http.server.reactive.ServerHttpRequest;
-
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
-
import org.springframework.http.server.reactive.ServerHttpResponse;
-
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
-
import org.springframework.stereotype.Component;
-
import org.springframework.util.LinkedMultiValueMap;
-
import org.springframework.util.MultiValueMap;
-
import org.springframework.web.reactive.function.BodyInserter;
-
import org.springframework.web.reactive.function.BodyInserters;
-
import org.springframework.web.reactive.function.server.HandlerStrategies;
-
import org.springframework.web.reactive.function.server.ServerRequest;
-
import org.springframework.web.server.ServerWebExchange;
-
import org.springframework.web.util.UriComponentsBuilder;
-
import reactor.core.publisher.Flux;
-
import reactor.core.publisher.Mono;
-
-
import java.io.UnsupportedEncodingException;
-
import java.nio.charset.StandardCharsets;
-
import java.util.*;
-
import java.util.regex.M
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfikifh
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13