英文:
Client-side file download with OpenAPI Generator-Plugin
问题
I'm trying to implement a REST API using OpenAPI (v3.0.3) and the openapi-generator-maven-plugin (v6.6.0). I want the plugin to generate both server and client from the specification.
I'm trying to implement a method to download a (ZIP) file, which I imagine would be a rather common operation, but I cannot get it to work on the client side. And unfortunately, my search didn't turn up any useful hints, so I'm asking a new question. In the spec, I have written:
/download:
get:
operationId: download
responses:
"200":
description: Success
content:
application/zip:
schema:
type: string
format: binary
The server side (generator spring) is generated as expected and returns a ResponseEntity of type "Resource" (I have implemented the method to return a Spring InputStreamResource). When calling the server endpoint with a hand made client, it works as expected and I can read the InputStream without problem.
The generated client however (generator java, with library native) is not really doing what I think it should. Here is a part of the generated download method:
public ApiResponse<File> downloadWithHttpInfo() throws ApiException {
HttpRequest.Builder localVarRequestBuilder = downloadRequestBuilder();
try {
HttpResponse<InputStream> localVarResponse = memberVarHttpClient.send(
localVarRequestBuilder.build(),
HttpResponse.BodyHandlers.ofInputStream());
if (memberVarResponseInterceptor != null) {
memberVarResponseInterceptor.accept(localVarResponse);
}
try {
if (localVarResponse.statusCode()/ 100 != 2) {
throw getApiException("download", localVarResponse);
}
return new ApiResponse<File>(
localVarResponse.statusCode(),
localVarResponse.headers().map(),
localVarResponse.body() == null ? null : memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference<File>() {}) // closes the InputStream
);
} finally {
}
First, it returns a response of type file...Ok, I could live with that. But it just handles the response wrong: First, it retrieves a HttpResponse
So, my questions:
- Should I change my spec in some way to make it clear(er) to the generator what I want?
- Can I get the client to not use the JSON mapper and instead directly return the InputStream from the response?
- If there is no workaround, is there another generator library which works better? I wanted to use native since we're using Java 17, but if there's other generators which work and rely on external libraries I guess I have use one of those.
英文:
I'm trying to implement a REST API using OpenAPI (v3.0.3) and the openapi-generator-maven-plugin (v6.6.0). I want the plugin to generate both server and client from the specification.
I'm trying to implement a method to download a (ZIP) file, which I imagine would be a rather common operation, but I cannot get it to work on the client side. And unfortunately, my search didn't turn up any useful hints, so I'm asking a new question. In the spec, I have written:
/download:
get:
operationId: download
responses:
"200":
description: Success
content:
application/zip:
schema:
type: string
format: binary
The server side (generator spring) is generated as expected and returns a ResponseEntity of type "Resource" (I have implemented the method to return a Spring InputStreamResource). When calling the server endpoint with a hand made client, it works as expected and I can read the InputStream without problem.
The generated client however (generator java, with library native) is not really doing what I think it should. Here is a part of the generated download method:
public ApiResponse<File> downloadWithHttpInfo() throws ApiException {
HttpRequest.Builder localVarRequestBuilder = downloadRequestBuilder();
try {
HttpResponse<InputStream> localVarResponse = memberVarHttpClient.send(
localVarRequestBuilder.build(),
HttpResponse.BodyHandlers.ofInputStream());
if (memberVarResponseInterceptor != null) {
memberVarResponseInterceptor.accept(localVarResponse);
}
try {
if (localVarResponse.statusCode()/ 100 != 2) {
throw getApiException("download", localVarResponse);
}
return new ApiResponse<File>(
localVarResponse.statusCode(),
localVarResponse.headers().map(),
localVarResponse.body() == null ? null : memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference<File>() {}) // closes the InputStream
);
} finally {
}
First, it returns a response of type file...Ok, I could live with that. But it just handles the response wrong: First, it retrieves a HttpResponse<InputStream>. That is correct and gets the input stream, but then it tries to map the response body through a JSON mapper (memberVarObjectMapper). Which is obviously wrong since the return type in the spec is "application/zip", so the method breaks here with a JSON parse error.
So, my questions:
- Should I change my spec in some way to make it clear(er) to the generator what I want?
- Can I get the client to not use the JSON mapper and instead directly return the InputStream from the response?
- If there is no workaround, is there another generator library which works better? I wanted to use native since we're using Java 17, but if there's other generators which work and rely on external libraries I guess I have use one of those.
答案1
得分: 0
我昨天遇到了同样的问题。我切换到使用 resttemplate 库,并将 useAbstractionForFiles 设置为 true,那就可以了。我本来更喜欢使用原生库,但似乎这可能是一个没有得到很多关注的 bug:https://github.com/OpenAPITools/openapi-generator/issues/3672
英文:
I just ran into the same thing yesterday. I switched to using resttemplate library with useAbstractionForFiles set to true, and that worked. I would prefer to have used the native library, but it seems it may be a bug without much traction: https://github.com/OpenAPITools/openapi-generator/issues/3672
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论