如何修改spring-cloud gateway中multipart/form-data格式的请求参数

发布于 2022-09-11 20:48:37 字数 4941 浏览 16 评论 0

现在打算把鉴权放到网关来做,验证通过后需要修改请求参数。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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沙与沫 2022-09-18 20:48:37

请问 repackageMultipartData() 方法里的几个常量是啥, 方便给出代码吗?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文