如何让MicroProfile Rest Client自动解压Gzip格式响应?
问题:MicroProfile Rest Client能否自动解压gzip响应?
场景说明
我正在调用一个接口获取CSV文件,对应的MicroProfile Rest Client接口定义如下:
@RegisterRestClient @Path("/catalogs") public interface Client { @GET @Produces(MediaType.TEXT_PLAIN) @Path("/{catalog}/content/responses/{key}/") Response getResponsesKey(@PathParam("catalog") String catalog, @PathParam("key") String key); }
通过Postman发送GET请求:GET https://toto.com/catalogs/99999/content/responses/forexReport-20241204-forexReport.csv/,可正常获取CSV内容。响应头信息如下:
- Content-Type : text/csv; header=present; charset=utf-8
- content-disposition : attachment; filename=forexReport-20241204-forexReport.csv
- content-encoding : gzip
但使用MicroProfile Rest Client时,我必须手动解压响应内容:
@Inject @RestClient private Client client; private void toto() { String key = "forexReport-20241204-forexReport.csv"; Response response = client.getResponsesKey("99999", key); //unzip the response try(GZIPInputStream gis = new GZIPInputStream(response.readEntity(InputStream.class)); FileOutputStream os = new FileOutputStream("foo.csv") ) { int c = 0; while((c = gis.read()) != -1) { os.write(c); } } }
问题:是否可以配置MicroProfile使其自动解压传入的文件?我使用的是wildfly-29.0.1.Final版本。
解决方案
针对WildFly 29.0.1.Final(基于MicroProfile 6.0),有两种简单方式实现自动解压:
1. 通过配置文件启用自动压缩协商
在项目的src/main/resources/META-INF/microprofile-config.properties中添加配置,可选择全局生效或针对特定接口生效:
# 针对你的Client接口启用(替换为接口的完整包路径) com.yourpackage.Client/mp-rest/accept-encoding=gzip,deflate # 全局启用(所有Rest Client接口都适用) mp-rest/accept-encoding=gzip,deflate
添加后,Rest Client会自动在请求头中携带Accept-Encoding: gzip,deflate,并且自动识别响应的content-encoding: gzip,完成解压操作,无需手动处理。
2. 接口级别添加压缩支持注解
直接在Rest Client接口上注册GZIPEncodingFeature提供者,WildFly已内置该实现:
@RegisterRestClient @Path("/catalogs") @RegisterProvider(GZIPEncodingFeature.class) public interface Client { @GET @Produces(MediaType.TEXT_PLAIN) @Path("/{catalog}/content/responses/{key}/") Response getResponsesKey(@PathParam("catalog") String catalog, @PathParam("key") String key); }
验证修改
配置完成后,代码可以简化为直接读取解压后的内容:
@Inject @RestClient private Client client; private void toto() { String key = "forexReport-20241204-forexReport.csv"; Response response = client.getResponsesKey("99999", key); try(FileOutputStream os = new FileOutputStream("foo.csv")) { response.readEntity(InputStream.class).transferTo(os); } }
内容的提问来源于stack exchange,提问作者grigouille
相关产品推荐
相关产品推荐

