如何修改spring-cloud gateway中multipart/form-data格式的请求参数
现在打算把鉴权放到网关来做,验证通过后需要修改请求参数。multipart/form-data格式的请求参数比较复杂,要怎么替换呢?
这里可以获取到multipart/form-data格式参数
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(mediaType)) {
exchange.getRequest().getBody().collectList().flatMap(dataBuffers -> {
final byte[] totalBytes = dataBuffers.stream().map(dataBuffer -> {
try {
final byte[] bytes = IOUtils.toByteArray(dataBuffer.asInputStream());
return bytes;
} catch (IOException e) {
throw new RuntimeException(e);
}
}).reduce(this::addBytes).get();
final ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return Flux.just(buffer(totalBytes));
}
};
final ServerCodecConfigurer configurer = ServerCodecConfigurer.create();
final Mono<MultiValueMap<String, Part>> multiValueMapMono = repackageMultipartData(decorator, configurer);
return multiValueMapMono.flatMap(part -> {
for (String key : part.keySet()) {
// 这里可以获取到具体的参数信息
}
return chain.filter(exchange.mutate().request(decorator).build());
});
});
}
private DataBuffer buffer(byte[] bytes) {
final NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
final DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}
@SuppressWarnings("unchecked")
private static Mono<MultiValueMap<String, Part>> repackageMultipartData(ServerHttpRequest request, ServerCodecConfigurer configurer) {
try {
final MediaType contentType = request.getHeaders().getContentType();
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
return ((HttpMessageReader<MultiValueMap<String, Part>>) configurer
.getReaders()
.stream()
.filter(reader -> reader.canRead(MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No multipart HttpMessageReader.")))
.readMono(MULTIPART_DATA_TYPE, request, Collections.emptyMap())
.switchIfEmpty(EMPTY_MULTIPART_DATA)
.cache();
}
} catch (InvalidMediaTypeException ex) {
// Ignore
}
return EMPTY_MULTIPART_DATA;
}
public byte[] addBytes(byte[] first, byte[] second) {
final byte[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
json格式的参数我是这样转换的
Mono<?> modifiedBody = serverRequest.bodyToMono(inClass).flatMap(o -> {
exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, o);
return Mono.justOrEmpty(newRequestBody);
});
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, inClass);
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
@SuppressWarnings("unchecked")
Mono<Void> result = bodyInserter.insert(outputMessage, new BodyInserterContext())
.then(Mono.defer(() -> {
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.get
@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<DataBuffer> getBody() {
return outputMessage.getBody();
}
};
return chain.filter(exchange.mutate().request(decorator).build());
}));
return result;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
参考:https://blog.csdn.net/qq_3274...
请问 repackageMultipartData() 方法里的几个常量是啥, 方便给出代码吗?