WebClient下载两张图片后处理

函数需要做两件事情,根据请求vo里的url字段,下载2个图片。调用myService的方法,将结果填在返回vo里。使用Webflux的webclient
三种方法的共同代码:

    private void writeRecord(String logId, String f1Url, String f2Url, Float similarity) {
        IdentityEntity e = new IdentityEntity();
        e.setF1Url(f1Url);
        e.setF2Url(f2Url);
        e.setSimilarity(similarity);
        e.setLogId(logId);
        this.repository.save(e);
    }

方法一的共同代码:

private Mono<ClientResponse> getImage(String url) {
        return webClient.get()
                .uri(url)
                .exchange();
    }

方案一、下载图片1,如果成功,再下载图片2。都下载之后进行处理。


    @Override
    public Mono<IdentityResponseVo> compare(Mono<IdentityRequestVo> vo) {
        return vo.flatMap(v -> {
            Mono<ClientResponse> r1 = getImage(v.getF1Url());
            Mono<IdentityResponseVo> map = r1.flatMap(clientResponse -> {
                if (!clientResponse.statusCode().is2xxSuccessful()) {
                    return Mono.just(new IdentityResponseVo(ERR_DOWNLOAD, v.getLogId()));
                } else {
                    Mono<ClientResponse> r2 = getImage(v.getF2Url());
                    Mono<IdentityResponseVo> map1 = r2.flatMap(clientResponse2 -> {
                        if (!clientResponse2.statusCode().is2xxSuccessful()) {

                            return Mono.just(new IdentityResponseVo(ERR_DOWNLOAD, v.getLogId()));
                        } else {
                            // Convert first image to base64
                            Mono<String> f1Base64Mono = r1.flatMap(response -> response.bodyToMono(byte[].class))
                                    .map(Base64::encodeAsString);

                            // Convert second image to base64
                            Mono<String> f2Base64Mono = r2.flatMap(response -> response.bodyToMono(byte[].class))
                                    .map(Base64::encodeAsString);

                            Mono<AiIdentity> aiIdentityMono = f1Base64Mono.flatMap(f1Base64 ->
                                    f2Base64Mono.map(f2Base64 -> myService.handle(f1Base64, f2Base64))
                                            .doOnNext(ret -> this.writeRecord(v.getLogId(), v.getF1Url(), v.getF2Url(), ret.getSimilarity())));
                            return aiIdentityMono.map(ret -> IdentityResponseVo.transform(ret, v.getLogId()));
                        }
                    });
                    return map1;
                }
            });
            return map;
        });
    }

方案二、下载两个图片,如果都是2xx才会进行处理,否则返回错误:

    @Override
    public Mono<IdentityResponseVo> compare2(Mono<IdentityRequestVo> vo) {
        return vo.flatMap(v -> {
            Mono<ClientResponse> r1 = getImage(v.getF1Url());
            Mono<ClientResponse> r2 = getImage(v.getF2Url());
            Mono<Boolean> both2xx = Mono.zip(r1.map(ClientResponse::statusCode), r2.map(ClientResponse::statusCode))
                    .map(statusCode -> {
                        log.info("{} is error: {} and {} is error: {}",
                                v.getF1Url(), statusCode.getT1().is2xxSuccessful(),
                                v.getF2Url(), statusCode.getT2().is2xxSuccessful());
                        return statusCode.getT1().is2xxSuccessful() && statusCode.getT2().is2xxSuccessful();
                    });


            return both2xx.flatMap(received -> {
                if (received) {
                    // Convert first image to base64
                    Mono<String> f1Base64Mono = r1.flatMap(response -> response.bodyToMono(byte[].class))
                            .map(Base64::encodeAsString);

                    // Convert second image to base64
                    Mono<String> f2Base64Mono = r2.flatMap(response -> response.bodyToMono(byte[].class))
                            .map(Base64::encodeAsString);

                    Mono<AiIdentity> aiIdentityMono = f1Base64Mono.flatMap(f1Base64 ->
                            f2Base64Mono.map(f2Base64 -> myService.handle(f1Base64, f2Base64))
                    ).doOnNext(ret -> this.writeRecord(v.getLogId(), v.getF1Url(), v.getF2Url(), ret.getSimilarity()));
                    return aiIdentityMono.map(ret -> IdentityResponseVo.transform(ret, v.getLogId()));
                } else {
                    // Return default JSON if any of the images were not received successfully
                    return Mono.just(new IdentityResponseVo(ERR_DOWNLOAD, v.getLogId()));
                }
            });
        });
    }

方案三、“同时”下载图片1和2,通过onErrorReturn,处理任何一个图片响应不是2xx的情况
如果下载图片响应不是404,会得到Mono.error, WebResponseException,这时onErrorReturn就会执行。如果响应404,Controller层直接返回,没有任何的body或者日志。那是因为Mono.empty,终止了整个数据流。

    private Mono<String> getImageByUrl(String url) {
        Mono<byte[]> mono = webClient.get()
                .uri(url)
                .retrieve()
                .bodyToMono(byte[].class)
                .onErrorResume(WebClientResponseException.class,
                        ex -> ex.getRawStatusCode() == 404 ? Mono.empty() : Mono.error(ex));
        return mono.map(Base64::encodeAsString);
    }

    @Override
    public Mono<IdentityResponseVo> compare(Mono<IdentityRequestVo> vo) {
        return vo.flatMap(v -> {
            Mono<String> f1Base64Mono = getImageByUrl(v.getF1Url());
            Mono<String> f2Base64Mono = getImageByUrl(v.getF2Url());
            Mono<AiIdentity> aiIdentityMono = f1Base64Mono.flatMap(f1Base64 ->
                    f2Base64Mono.map(f2Base64 -> myService.handle(f1Base64, f2Base64))
            ).doOnNext(ret -> this.writeRecord(v.getLogId(), v.getF1Url(), v.getF2Url(), ret.getSimilarity()));
            return aiIdentityMono.map(ret -> IdentityResponseVo.transform(ret, v.getLogId()))
                    .onErrorReturn(new IdentityResponseVo(ResponseState.ERR_DOWNLOAD, v.getLogId()));
        });
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值