reactivex java_使用ReactiveX for Java进行Http调用

如果我理解正确,你需要这样的东西来包装你现有的callExternalUrl

static Observable callExternalUrlAsync(String url, String json, HttpMethod method)

{

return Observable.fromCallable(() -> callExternalUrl(url, json, method))

.subscribeOn(Schedulers.io())

.flatMap(re -> {

if (re.hasBody())

return Observable.just(re.getBody());

else

return Observable.error(new RuntimeException("Bad response status " + re.getStatusCode()));

},

e -> Observable.error(e),

(Func0>) (() -> Observable.empty())) // I need explicit cast or it won't compile :-(

.observeOn(Schedulers.computation());

}

代码简述:

>它计划在Schedulers.io上执行现有的callExternalUrl

> ResponseEntity的最小转换< T>成功的T和错误案例.它也发生在io调度程序上,但它并不重要,因为它非常简短. (如果callExternalUrl中有异常,则按原样传递.)

>使订阅者在Schedulers.computation上执行结果

注意事项:

>您可能希望将自定义调度程序用于subscribeOn和observeOn

>您可能希望在传递给flatMap的第一个lambda中有一些更好的逻辑来区分成功和错误,并且您肯定需要一些更具体的异常类型.

高阶魔术

如果您愿意使用高阶函数并交换一点性能以减少代码重复,您可以执行以下操作:

// Universal wrapper method

static Observable wrapCallExternalAsAsync(Func3> externalCall, String url, String json, HttpMethod method)

{

return Observable.fromCallable(() -> externalCall.call(url, json, method))

.subscribeOn(Schedulers.io())

.flatMap(re -> {

if (re.hasBody())

return Observable.just(re.getBody());

else

return Observable.error(new RuntimeException("Bad response status " + re.getStatusCode()));

},

e -> Observable.error(e),

(Func0>) (() -> Observable.empty())) // I need explicit cast or it won't compile :-(

.observeOn(Schedulers.computation());

}

static Observable callExternalUrlAsync_HigherOrder(String url, String json, HttpMethod method)

{

return wrapCallExternalAsAsync(MyClass::callExternalUrl, url, json, method);

}

MyClass就在你的callExternalUrl的哪个地方.

更新(仅限异步调用)

private static RxClient httpClient = Rx.newClient(RxObservableInvoker.class); //这里你可以传递自定义ExecutorService

private Observable executeHttpAsync(String url, String httpMethod, Entity entity) {

return httpClient.target(url)

.request()

.headers(httpHeaders) // assuming httpHeaders is something global as in your example

.rx()

.method(httpMethod, entity)

.map(resp -> {

if (200 != resp.getStatus()) {

throw new RuntimeException("Bad status code " + resp.getStatus());

} else {

if (!resp.hasEntity()) {

// return null; // or error?

throw new RuntimeException("Empty response"); // or empty?

} else {

try {

return resp.readEntity(String.class);

} catch (Exception ex) {

throw new RuntimeException(ex); // wrap exception into unchecked

}

}

}

})

.observeOn(Schedulers.computation());

}

private Observable executeGetAsync(String url) {

return executeHttpAsync(url, "GET", null);

}

private Observable executePostAsync(String url, String json) {

return executeHttpAsync(url, "POST", Entity.json(json));

}

类似的警告同样适用:

>您可能希望将自定义调度程序用于newClient调用和observeOn

>您可能希望有一些更好的错误处理逻辑,而不仅仅是检查它是否是HTTP 200,并且您肯定需要一些更具体的异常类型.但这是所有业务逻辑特定的,所以它取决于您.

此外,从您的示例中还不清楚请求的主体(HttpEntity)是如何构建的,以及您是否真的总是希望String作为响应,就像在原始示例中一样.我仍然按原样复制你的逻辑.如果您需要更多的东西,您可能应该参考https://jersey.java.net/documentation/2.25/media.html#json的文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值