springcloudgateway中如何读取请求参数spring cloud gateway读取请求参数
1. 我的版本:
spring-cloud:Hoxton.RELEASE
spring-boot:2.2.2.RELEASE
spring-cloud-starter-gateway
2. 请求⽇志
slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import io.buffer.DataBuffer;
import io.buffer.DataBufferUtils;
import org.springframework.http.HttpMethod;
import org.springframework.active.ServerHttpRequest;
import org.springframework.active.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
publisher.Flux;
publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author MinWeikai
* @date 2019-12-20 18:09:39
*/
@Slf4j
@Component
public class LoggerFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = Request();
String method = MethodValue();
if (HttpMethod.POST.matches(method)) {
return DataBufferUtils.Request().getBody())
.flatMap(dataBuffer -> {
byte[] bytes = new adableByteCount()];
String bodyString = new String(bytes, StandardCharsets.UTF_8);
logtrace(exchange, bodyString);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
DataBuffer buffer = Response().bufferFactory()
.wrap(bytes);
return Mono.just(buffer);
});
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
return chain.filter(exchange.mutate().request(mutatedRequest)
.build());
});
} else if (HttpMethod.GET.matches(method)) {
Map m = QueryParams();
logtrace(exchange, m.toString());
}
return chain.filter(exchange);
}
/**
* ⽇志信息
*
* @param exchange
* @param param    请求参数
*/
private void logtrace(ServerWebExchange exchange, String param) {
ServerHttpRequest serverHttpRequest = Request();
String path = URI().getPath();
String method = MethodValue();
String headers = Headers().entrySet()
.stream()
.map(entry -> "            " + Key() + ": [" + String.join(";", Value()) + "]")
.collect(Collectors.joining("\n"));
log.info("\n" + "----------------            ----------------            ---------------->>\n" +
"HttpMethod : {}\n" +
"Uri        : {}\n" +
"Param      : {}\n" +
"Headers    : \n" +
"{}\n" +
"\"<<----------------            ----------------            ----------------"
, method, path, param, headers);
}
}
3. 测试输出,我这边测试没有问题,⽇志正常输出
gateway⽹关转发请求添加参数
在继承AbstractGatewayFilterFactory的过滤器中
GET请求添加参数
// 参考api⽂档中GatewapFilter中“添加请求参数”:AddRequestParameterGatewayFilterFactory.java            //记录⽇志
//logger.info("全局参数处理: {} url:{} 参数:{}",String(),URI().getRawPath(),String());
// 获取原参数
URI uri = URI();
StringBuilder query = new StringBuilder();
String originalQuery = RawQuery();
if (org.springframework.util.StringUtils.hasText(originalQuery)) {
query.append(originalQuery);
if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
query.append('&');
}
}
// 添加查询参数
query.append(ServiceConstants.COMMON_PARAMETER_ENTERPRISEID+"="+EnterpriseId()
+"&"+ServiceConstants.COMMON_PARAMETER_USERID+"="+UserId());
// 替换查询参数
URI newUri = UriComponentsBuilder.fromUri(uri)
.String())
.
build(true)
.toUri();
ServerHttpRequest request = Request().mutate().uri(newUri).build();
return chain.filter(exchange.mutate().request(request).build());
POST请求添加参数
//从请求⾥获取Post请求体
String bodyStr = resolveBodyFromRequest(serverHttpRequest);
String userId = "123";
// 这种处理⽅式,必须保证post请求时,原始post表单必须有数据过来,不然会报错
if (StringUtils.isEmpty(bodyStr)) {
<("请求异常:{} POST请求必须传递参数", URI().getRawPath());
ServerHttpResponse response = Response();
response.setStatusCode(HttpStatus.BAD_REQUEST);
return response.setComplete();
}
//application/x-www-form-urlencoded和application/json才添加参数
//其他上传⽂件之类的,不做参数处理,因为⽂件流添加参数,⽂件原格式就会出问题了
/* if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)) {
// 普通键值对,增加参数
bodyStr = String.format(bodyStr+"&%s=%s&%s=%s",ServiceConstants.COMMON_PARAMETER_EnterpriseId()                                ,ServiceConstants.COMMON_PARAMETER_UserId());
}*/
// 新增body参数
if (MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)) {
JSONObject jsonObject = new JSONObject(bodyStr);
jsonObject.put("userId", userId);
bodyStr = String();
}
//记录⽇志
logger.info("全局参数处理: {} url:{} 参数:{}", String(), URI().getRawPath(), bodyStr);
//下⾯的将请求体再次封装写回到request⾥,传到下⼀级,否则,由于请求体已被消费,后续的服务将取不到值
URI uri = URI();
URI newUri = UriComponentsBuilder.fromUri(uri).build(true).toUri();
ServerHttpRequest request = Request().mutate().uri(newUri).build();
DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
// 定义新的消息头
HttpHeaders headers = new HttpHeaders();
headers.Request().getHeaders());
// 添加消息头
//                    headers.set(ServiceConstants.SHIRO_SESSION_Json(authenticationVO));
// 由于修改了传递参数,需要重新设置CONTENT_LENGTH,长度是字节长度,不是字符串长度
int length = Bytes().length;
headers.setContentLength(length);
// 设置CONTENT_TYPE
if (StringUtils.isEmpty(contentType)) {
headers.set(HttpHeaders.CONTENT_TYPE, contentType);
}
// 由于post的body只能订阅⼀次,由于上⾯代码中已经订阅过⼀次body。所以要再次封装请求到request才⾏,不然会报错请求已经订阅过
request = new ServerHttpRequestDecorator(request) {
@Override
public HttpHeaders getHeaders() {
long contentLength = ContentLength();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.Headers());
if (contentLength > 0) {
httpHeaders.setContentLength(contentLength);
} else {
// TODO: this causes a 'HTTP/1.1 411 Length Required'
httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
}
return httpHeaders;
}
@Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
}
};
//封装request,传给下⼀级
request.mutate().header(HttpHeaders.CONTENT_LENGTH, String(bodyStr.length()));                    return chain.filter(exchange.mutate().request(request).build());
/**
* 从Flux<DataBuffer>中获取字符串的⽅法
* @return 请求体
*/
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
//获取请求体
Flux<DataBuffer> body = Body();
AtomicReference<String> bodyRef = new AtomicReference<>();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
bodyRef.String());
});
//获取request body
();
}
/**
* 字符串转DataBuffer
* @param value
* @return
*/
private DataBuffer stringBuffer(String value) {
byte[] bytes = Bytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
session如何设置和读取}
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。