如何在Java 11中读取HttpRequest的正文? [英] How to read the body of a HttpRequest in Java 11?

查看:187
本文介绍了如何在Java 11中读取HttpRequest的正文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在测试中,我想查看HttpRequest的正文.我想把琴弦当作琴弦.似乎唯一的方法是订阅BodyPublisher,但这是如何工作的?

In a test, I'd like to look inside the body of a HttpRequest. I'd like to get the body as a string. It seems that the only way to do that, is to subscribe to the BodyPublisher but how does that work?

推荐答案

这是一个有趣的问题.您从哪里获得HttpRequest?最简单的方法是直接从创建HttpRequest的代码中获取主体.如果那不可能,那么下一步是克隆该请求,并将其主体发布者包装在您自己的BodyPublisher实现中,然后再通过HttpClient发送请求.编写HttpRequest的子类来包装HttpRequest的另一个实例,并将每个调用委派给该包装的实例,但是重写HttpRequest::bodyPublisher来执行类似的操作,应该相对容易(如果很乏味):

This is an interesting question. Where do you get your HttpRequest from? The easiest way would be to obtain the body directly from the code that creates the HttpRequest. If that's not possible then the next thing would be to clone that request and wraps its body publisher in your own implementation of BodyPublisher before sending the request through the HttpClient. It should be relatively easy (if tedious) to write a subclass of HttpRequest that wraps an other instance of HttpRequest and delegates every calls to the wrapped instance, but overrides HttpRequest::bodyPublisher to do something like:

return request.bodyPublisher().map(this::wrapBodyPublisher);

否则,您可能还尝试订阅请求主体发布者并从中获取主体字节-但请注意,并非BodyPublisher的所有实现都可能支持多个订阅者(并发或顺序).

Otherwise, you might also try to subscribe to the request body publisher and obtain the body bytes from it - but be aware that not all implementations of BodyPublisher may support multiple subscribers (whether concurrent or sequential).

在上面说明我的建议:根据正文发布者的具体实现,并且在您可以防止并发订阅正文发布者的情况下,类似以下的内容可能会起作用.那就是-在一个您知道所有各方的受控测试环境中,这可能是可行的.不要在生产中使用任何东西:

To illustrate my suggestion above: something like below may work, depending on the concrete implementation of the body publisher, and provided that you can guard against concurrent subscriptions to the body publisher. That is - in a controlled test environment where you know all the parties, then it might be workable. Don't use anything this in production:

public class HttpRequestBody {

    // adapt Flow.Subscriber<List<ByteBuffer>> to Flow.Subscriber<ByteBuffer>
    static final class StringSubscriber implements Flow.Subscriber<ByteBuffer> {
        final BodySubscriber<String> wrapped;
        StringSubscriber(BodySubscriber<String> wrapped) {
            this.wrapped = wrapped;
        }
        @Override
        public void onSubscribe(Flow.Subscription subscription) {
            wrapped.onSubscribe(subscription);
        }
        @Override
        public void onNext(ByteBuffer item) { wrapped.onNext(List.of(item)); }
        @Override
        public void onError(Throwable throwable) { wrapped.onError(throwable); }
        @Override
        public void onComplete() { wrapped.onComplete(); }
    }

    public static void main(String[] args) throws Exception {
        var request = HttpRequest.newBuilder(new URI("http://example.com/blah"))
                .POST(BodyPublishers.ofString("Lorem ipsum dolor sit amet"))
                .build();

        // you must be very sure that nobody else is concurrently 
        // subscribed to the body publisher when executing this code,
        // otherwise one of the subscribers is likely to fail.
        String reqbody = request.bodyPublisher().map(p -> {
            var bodySubscriber = BodySubscribers.ofString(StandardCharsets.UTF_8);
            var flowSubscriber = new StringSubscriber(bodySubscriber);
            p.subscribe(flowSubscriber);
            return bodySubscriber.getBody().toCompletableFuture().join();
        }).get();
        System.out.println(reqbody);
    }

}

这篇关于如何在Java 11中读取HttpRequest的正文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆