SpringCloud Gateway 获取 request body response write
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,话不多说,直接上码/** * @author liuhanling * @create 2018-12-14 20:01 * @desc */@Slf4j@Componentpublic class
千家信息网最后更新 2025年12月03日SpringCloud Gateway 获取 request body response write
话不多说,直接上码
/** * @author liuhanling * @create 2018-12-14 20:01 * @desc */@Slf4j@Componentpublic class RequestBodyFilter implements GatewayFilter, Ordered { private static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject"; @Override @SuppressWarnings("unchecked") public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { Class inClass = String.class; ServerRequest serverRequest = new DefaultServerRequest(exchange); ServerHttpRequest request = exchange.getRequest(); //只记录 http 请求(包含 https) String schema = request.getURI().getScheme(); if ((!"http".equals(schema) && !"https".equals(schema))) { return chain.filter(exchange); } String contentType = request.getHeaders().getFirst("Content-Type"); String upload = request.getHeaders().getFirst("upload"); //get 方法获取参数 if ("GET".equals(request.getMethod().name())) { if (!request.getQueryParams().isEmpty()) { Map map = new HashMap<>(); request.getQueryParams().toSingleValueMap().forEach((key, val) -> map.put(key, getURLDecoder(val))); String param = new Gson().toJson(map); exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, param); } return chain.filter(exchange); } //没有内容类型不读取body if (contentType == null || contentType.length() == 0) { return chain.filter(exchange); } //文件上传不读取body if ("true".equals(upload)) { return chain.filter(exchange); } Mono> modifiedBody = serverRequest.bodyToMono(inClass).flatMap(o -> { log.debug("requestBody:{}", o); exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, o); return Mono.justOrEmpty(o); }); BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, inClass); HttpHeaders headers = new HttpHeaders(); headers.putAll(exchange.getRequest().getHeaders()); CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); return bodyInserter.insert(outputMessage, new BodyInserterContext()) .then(Mono.defer(() -> { ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) { @Override public HttpHeaders getHeaders() { long contentLength = headers.getContentLength(); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.putAll(super.getHeaders()); if (contentLength > 0) { httpHeaders.setContentLength(contentLength); } else { // TODO: this causes a 'HTTP/1.1 411 Length Required' on httpbin.org httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); } return httpHeaders; } @Override public Flux getBody() { return outputMessage.getBody(); } }; return chain.filter(exchange.mutate().request(decorator).build()); })); } @Override public int getOrder() { return 0; } /** * URL 转码 * @param val * @return */ private String getURLDecoder(String val){ try{ return URLDecoder.decode(val, "utf-8"); }catch (Exception e){ log.error("getURLDecoder error",e); } return val; }} 重写 ResponseBody
/** * @author liuhanling * @create 2018-12-27 10:39 * @desc */@Component@Slf4jpublic class ResponseBodyFilter implements GatewayFilter, Ordered { @Override @SuppressWarnings("unchecked") public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpResponseDecorator responseDecorator = new ServerHttpResponseDecorator(exchange.getResponse()) { @Override public Mono writeWith(Publisher extends DataBuffer> body) { Class inClass = String.class; Class outClass = String.class; String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR); HttpHeaders httpHeaders = new HttpHeaders(); //explicitly add it in this way instead of 'httpHeaders.setContentType(originalResponseContentType)' //this will prevent exception in case of using non-standard media types like "Content-Type: image" httpHeaders.add(HttpHeaders.CONTENT_TYPE, originalResponseContentType); ResponseAdapter responseAdapter = new ResponseAdapter(body, httpHeaders); DefaultClientResponse clientResponse = new DefaultClientResponse(responseAdapter, ExchangeStrategies.withDefaults()); //TODO: flux or mono Mono modifiedBody = clientResponse.bodyToMono(inClass) .flatMap(originalBody -> { //如果是文件 Gson gson = new Gson(); Map res = gson.fromJson(String.valueOf(originalBody),new TypeToken>() {}.getType()); //修改 res.put("test_id",UUID.randomUUID().toString().replace("-","")); return Mono.just(gson.toJson(res)); }); BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass); CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, exchange.getResponse().getHeaders()); return bodyInserter.insert(outputMessage, new BodyInserterContext()) .then(Mono.defer(() -> { Flux messageBody = outputMessage.getBody(); //TODO: if (inputStream instanceof Mono) { HttpHeaders headers = getDelegate().getHeaders(); if (!headers.containsKey(HttpHeaders.TRANSFER_ENCODING)) { messageBody = messageBody.doOnNext(data -> headers.setContentLength(data.readableByteCount())); } // } //TODO: use isStreamingMediaType? return getDelegate().writeWith(messageBody); })); } @Override public Mono writeAndFlushWith(Publisher extends Publisher extends DataBuffer>> body) { return writeWith(Flux.from(body) .flatMapSequential(p -> p)); } }; return chain.filter(exchange.mutate().response(responseDecorator).build()); } @Override public int getOrder() { return 0; } public class ResponseAdapter implements ClientHttpResponse { private final Flux flux; private final HttpHeaders headers; public ResponseAdapter(Publisher extends DataBuffer> body, HttpHeaders headers) { this.headers = headers; if (body instanceof Flux) { flux = (Flux) body; } else { flux = ((Mono)body).flux(); } } @Override public Flux getBody() { return flux; } @Override public HttpHeaders getHeaders() { return headers; } @Override public HttpStatus getStatusCode() { return null; } @Override public int getRawStatusCode() { return 0; } @Override public MultiValueMap getCookies() { return null; } }} 版本信息
org.springframework.boot spring-boot-starter-parent 2.0.2.RELEASE UTF-8 UTF-8 1.8 Finchley.SR2 理论部分参考: https://blog.51cto.com/thinklili/2329184
文件
UTF-8
信息
内容
参数
方法
版本
理论
类型
部分
utf-8
参考
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
明日之后腾讯版服务器有哪些
公安机关网络安全事件
数据库写一个超市
西安 软件开发 薪资
我的世界出现无法访问服务器
渣浪 网络安全法
知鸟网络安全法律法规
临汾网络技术参考价格
工具管理软件开发
数据库如何连接系统
峡谷服务器多少钱
arcgis注册数据库
湖北交友软件开发哪里好
网络安全工具使用视频
网络安全黑板报加e
数据库er图详细点怎么画
济南锐盾网络技术
redis端口连接数据库
服务器只能访问80个端口
以下属于学术性期刊数据库的
fiery服务器与EFI公司
一款软件开发的研究内容是啥
服务器配置文件管理器
数据库模式设计原则
数据库技术比较好的社区
微羽服务器
html5和数据库的对接
redis端口连接数据库
吉林机电软件开发要多少钱
服务器管理区如何配置