OpenFeign是一種聲明式的Web服務客戶端,它使得編寫HTTP客戶端變得更加簡單和直觀。它使用了注解方式來描述HTTP API,使得開發者可以使用Java接口來調用遠程HTTP服務。
OpenFeign的核心特點包括:
聲明式API: 您可以使用注解聲明要調用的遠程API,然后使用Java接口調用它們。
定制化接口: 您可以使用FeignBuilder類定制客戶端接口的行為。
支持編碼器和解碼器: Feign支持多種編碼器和解碼器,可以將請求和響應轉換為Java對象。
支持請求和響應壓縮: OpenFeign支持gzip和deflate壓縮算法。
支持負載均衡: OpenFeign可以與負載均衡組件(如Ribbon)一起使用,以實現服務調用的負載均衡。
總之,OpenFeign是一個方便易用的Web服務客戶端,可以幫助開發者快速、靈活地調用遠程HTTP服務。
業務場景:獲取下游服務的文件下載流,然后上傳到minio,獲取分享鏈接?
場景復現
代碼
rpc類
@FeignClient(url = "ip:port", name = "infer")
public interface InferRpcService {@GetMapping(value = "/download", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)Response download(@RequestParam("text") String text);
}
調用類
@Slf4j
@Service
public class InferServiceImpl implements InferService {@Resourceprivate InferRpcService inferRpcService;@Resourceprivate MinioClient minioClient;@Overridepublic CommonResponse<String> tts(InferRequest inferRequest, HttpServletResponse response) {if (!CollectionUtils.isEmpty(userRecords) && Objects.nonNull(inferRequest) && StringUtils.isNoneEmpty(inferRequest.getText())) {try {Response transferred = inferRpcService.transferString(inferRequest.getText());Response.Body body = transferred.body();if (Objects.nonNull(body) && !body.isRepeatable()) {record.setTtsStatus(InferStatusConstant.SYNTHESIS_SUCCESSFUL);InputStream in = body.asInputStream();String filename = UUID.randomUUID().toString().replaceAll("-",""); String sharedWavUrl = MinioUtils.uploadFile(minioClient, in, MinioConstant.VITS_BUCKET, allFilename);record.setSharedWavUrl(sharedWavUrl);return CommonResponse.ok(sharedWavUrl);}} catch (IOException e) {throw new RuntimeException(e);}}return CommonResponse.error("合成失敗");}
}
工具類
@Slf4j
public class MinioUtils {public static String uploadFile(MinioClient minioClient, InputStream inputStream, String bucket, String filename) {try {log.info("返回的字節流大小: {}",inputStream.available());boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("public").build());if (!found) {minioClient.makeBucket(MakeBucketArgs.builder().bucket("public").build());}ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(filename).stream(inputStream, inputStream.available(), -1).contentType(InferStatusConstant.WAV_CONTENT_TYPE).build());String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucket).expiry(7 * 24 * 60 * 60).object(filename).method(Method.GET).build());log.info("分享地址:" + url);return url;} catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |XmlParserException e) {throw new RuntimeException(e);}}
}
現象
比如獲取下又服務的音頻的時候,會出現不完整的情況,我這邊的現象是只有前五秒的音頻
解決
借助restTemplate
代碼
@Configuration
public class RestTemplateConfiguration {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {RestTemplate restTemplate = restTemplateBuilder.build();return restTemplate;}
}
public CommonResponse<String> download(InferRequest inferRequest, HttpServletResponse response, int a) {String url = "you_url";ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null,byte[].class);byte[] bytes = responseEntity.getBody();if (!ArrayUtils.isEmpty(bytes)) {record.setTtsStatus(InferStatusConstant.SYNTHESIS_SUCCESSFUL);String filename = UUID.randomUUID().toString().replaceAll("-", "");String allFilename = "/" + openId + "/" + filename + MinioConstant.WAV_SUFFIX;String sharedWavUrl = MinioUtils.uploadFile(minioClient, new ByteArrayInputStream(bytes), MinioConstant.VITS_BUCKET, allFilename);return CommonResponse.ok(sharedWavUrl);return CommonResponse.error("失敗");}
下載沒有問題