SpringCloud Gateway 获取 request body response write
发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,话不多说,直接上码/** * @author liuhanling * @create 2018-12-14 20:01 * @desc */@Slf4j@Componentpublic class
千家信息网最后更新 2025年01月31日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安全错误
数据库的锁怎样保障安全
客户端无法连接到服务器
大数据背景下网络安全的国内研究
网络安全手抄板报8开纸
bv310系统升级服务器地址
六盘水服务器显卡生产厂家
戴尔e38s服务器安装
数据库收费标准
失落的方舟服务器无法建立角色
东营瓷砖软件开发定制
怎么找到容器数据库
各种网络技术
山东腾纵软件开发
档案数据库建设要保证()
冀州软件开发专业
宜宾手机软件开发
音乐软件开发者侵犯著作权
db2查看数据库事物级别
前端学习小软件开发
软件开发的管理方案
芝麻鲸选用什么软件开发
小说服务器选择英文
pdo连接数据库代码如何编写
服务器技术架构三个大趋势
三级网络技术多少钱
泸洲鸣思网络技术有限公司
俞能海中科大网络安全学院
白色数据库
网络安全需求的真实性
软件开发是属于IT
vpn服务器原理