add upload & downlod progress for Java okhttp

This commit is contained in:
Alvin 2015-11-21 15:06:00 +08:00
parent c150247dca
commit b9cf790d1c
6 changed files with 206 additions and 7 deletions

View File

@ -232,6 +232,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
if ("okhttp-gson".equals(getLibrary())) {
// the "okhttp-gson" library template requires "ApiCallback.mustache" for async call
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
supportingFiles.add(new SupportingFile("ProgressRequestBody.mustache", invokerFolder, "ProgressRequestBody.java"));
supportingFiles.add(new SupportingFile("ProgressResponseBody.mustache", invokerFolder, "ProgressResponseBody.java"));
// "build.sbt" is for development with SBT
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
} else if ("retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary())) {

View File

@ -28,4 +28,22 @@ public interface ApiCallback<T> {
* @param responseHeaders Headers of the response
*/
void onSuccess(T result, int statusCode, Map<String, List<String>> responseHeaders);
/**
* This is called when the API upload processing.
*
* @param bytesWritten bytes Written
* @param contentLength content length of request body
* @param done write end
*/
void onUploadProgress(long bytesWritten, long contentLength, boolean done);
/**
* This is called when the API downlond processing.
*
* @param bytesRead bytes Read
* @param contentLength content lenngth of the response
* @param done Read end
*/
void onDownloadProgress(long bytesRead, long contentLength, boolean done);
}

View File

@ -821,7 +821,7 @@ public class ApiClient {
* @param authNames The authentications to apply
* @return The HTTP call
*/
public Call buildCall(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames) throws ApiException {
public Call buildCall(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);
final String url = buildUrl(path, queryParams);
@ -851,7 +851,15 @@ public class ApiClient {
reqBody = RequestBody.create(MediaType.parse(contentType), serialize(body, contentType));
}
Request request = reqBuilder.method(method, reqBody).build();
Request request = null;
if(progressRequestListener != null) {
ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, progressRequestListener);
request = reqBuilder.method(method, progressRequestBody).build();
} else {
request = reqBuilder.method(method, reqBody).build();
}
return httpClient.newCall(request);
}

View File

@ -0,0 +1,70 @@
package {{invokerPackage}};
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;
import java.io.IOException;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;
public class ProgressRequestBody extends RequestBody {
public interface ProgressRequestListener {
void onRequestProgress(long bytesWritten, long contentLength, boolean done);
}
private final RequestBody requestBody;
private final ProgressRequestListener progressListener;
private BufferedSink bufferedSink;
public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) {
this.requestBody = requestBody;
this.progressListener = progressListener;
}
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
if (bufferedSink == null) {
bufferedSink = Okio.buffer(sink(sink));
}
requestBody.writeTo(bufferedSink);
bufferedSink.flush();
}
private Sink sink(Sink sink) {
return new ForwardingSink(sink) {
long bytesWritten = 0L;
long contentLength = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
if (contentLength == 0) {
contentLength = contentLength();
}
bytesWritten += byteCount;
progressListener.onRequestProgress(bytesWritten, contentLength, bytesWritten == contentLength);
}
};
}
}

View File

@ -0,0 +1,63 @@
package {{invokerPackage}};
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.ResponseBody;
import java.io.IOException;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
public class ProgressResponseBody extends ResponseBody {
public interface ProgressListener {
void update(long bytesRead, long contentLength, boolean done);
}
private final ResponseBody responseBody;
private final ProgressListener progressListener;
private BufferedSource bufferedSource;
public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
this.responseBody = responseBody;
this.progressListener = progressListener;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() throws IOException {
return responseBody.contentLength();
}
@Override
public BufferedSource source() throws IOException {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
return bytesRead;
}
};
}
}

View File

@ -5,10 +5,16 @@ import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;
import {{invokerPackage}}.ProgressRequestBody;
import {{invokerPackage}}.ProgressResponseBody;
import com.google.gson.reflect.TypeToken;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.Response;
import java.io.IOException;
{{#imports}}import {{import}};
{{/imports}}
@ -40,7 +46,7 @@ public class {{classname}} {
{{#operation}}
/* Build call for {{nickname}} */
private Call {{nickname}}Call({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
private Call {{nickname}}Call({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
@ -77,8 +83,20 @@ public class {{classname}} {
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
{{localVariablePrefix}}headerParams.put("Content-Type", {{localVariablePrefix}}contentType);
if(progressListener != null) {
apiClient.getHttpClient().networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), progressListener))
.build();
}
});
}
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}authNames);
return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}authNames, progressRequestListener);
}
/**
@ -88,7 +106,7 @@ public class {{classname}} {
* @return {{{returnType}}}{{/returnType}}
*/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}, null, null);
{{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}returnType);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
}
@ -100,8 +118,28 @@ public class {{classname}} {
* @param callback The callback to be executed when the API call finishes
* @return The request call
*/
public Call {{nickname}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
public Call {{nickname}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
ProgressResponseBody.ProgressListener progressListener = null;
ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
if(callback != null) {
progressListener = new ProgressResponseBody.ProgressListener() {
@Override
public void update(long bytesRead, long contentLength, boolean done) {
callback.onDownloadProgress(bytesRead, contentLength, done);
}
};
progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
@Override
public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
callback.onUploadProgress(bytesWritten, contentLength, done);
}
};
}
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}, progressListener, progressRequestListener);
{{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}returnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}}
return {{localVariablePrefix}}call;