Merge pull request #1998 from WoodWing/master

Support file downloading in Java jersey2 client
This commit is contained in:
wing328 2016-01-31 19:57:55 +08:00
commit 0e0508cf5a
18 changed files with 187 additions and 31 deletions

View File

@ -20,6 +20,9 @@ import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.MultiPart; import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.MultiPartFeature;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -37,6 +40,8 @@ import java.io.UnsupportedEncodingException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import {{invokerPackage}}.auth.Authentication; import {{invokerPackage}}.auth.Authentication;
import {{invokerPackage}}.auth.HttpBasicAuth; import {{invokerPackage}}.auth.HttpBasicAuth;
@ -52,6 +57,7 @@ public class ApiClient {
private Client httpClient; private Client httpClient;
private JSON json; private JSON json;
private String tempFolderPath = null;
private Map<String, Authentication> authentications; private Map<String, Authentication> authentications;
@ -236,8 +242,24 @@ public class ApiClient {
} }
/** /**
* Connect timeout (in milliseconds). * The path of temporary folder used to store downloaded files from endpoints
*/ * with file response. The default value is <code>null</code>, i.e. using
* the system's default tempopary folder.
*
* @see https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File)
*/
public String getTempFolderPath() {
return tempFolderPath;
}
public ApiClient setTempFolderPath(String tempFolderPath) {
this.tempFolderPath = tempFolderPath;
return this;
}
/**
* Connect timeout (in milliseconds).
*/
public int getConnectTimeout() { public int getConnectTimeout() {
return connectionTimeout; return connectionTimeout;
} }
@ -247,11 +269,11 @@ public class ApiClient {
* A value of 0 means no timeout, otherwise values must be between 1 and * A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}. * {@link Integer#MAX_VALUE}.
*/ */
public ApiClient setConnectTimeout(int connectionTimeout) { public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout; this.connectionTimeout = connectionTimeout;
httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout); httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout);
return this; return this;
} }
/** /**
* Get the date format used to parse/format date parameters. * Get the date format used to parse/format date parameters.
@ -467,6 +489,13 @@ public class ApiClient {
* Deserialize response body to Java object according to the Content-Type. * Deserialize response body to Java object according to the Content-Type.
*/ */
public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException { public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException {
// Handle file downloading.
if (returnType.equals(File.class)) {
@SuppressWarnings("unchecked")
T file = (T) downloadFileFromResponse(response);
return file;
}
String contentType = null; String contentType = null;
List<Object> contentTypes = response.getHeaders().get("Content-Type"); List<Object> contentTypes = response.getHeaders().get("Content-Type");
if (contentTypes != null && !contentTypes.isEmpty()) if (contentTypes != null && !contentTypes.isEmpty())
@ -477,6 +506,55 @@ public class ApiClient {
return response.readEntity(returnType); return response.readEntity(returnType);
} }
/**
* Download file from the given response.
* @throws ApiException If fail to read file content from response and write to disk
*/
public File downloadFileFromResponse(Response response) throws ApiException {
try {
File file = prepareDownloadFile(response);
Files.copy(response.readEntity(InputStream.class), file.toPath());
return file;
} catch (IOException e) {
throw new ApiException(e);
}
}
public File prepareDownloadFile(Response response) throws IOException {
String filename = null;
String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition");
if (contentDisposition != null && !"".equals(contentDisposition)) {
// Get filename from the Content-Disposition header.
Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
Matcher matcher = pattern.matcher(contentDisposition);
if (matcher.find())
filename = matcher.group(1);
}
String prefix = null;
String suffix = null;
if (filename == null) {
prefix = "download-";
suffix = "";
} else {
int pos = filename.lastIndexOf(".");
if (pos == -1) {
prefix = filename + "-";
} else {
prefix = filename.substring(0, pos) + "-";
suffix = filename.substring(pos);
}
// File.createTempFile requires the prefix to be at least three characters long
if (prefix.length() < 3)
prefix = "download-";
}
if (tempFolderPath == null)
return File.createTempFile(prefix, suffix);
else
return File.createTempFile(prefix, suffix, new File(tempFolderPath));
}
/** /**
* Invoke API by sending HTTP request with the given options. * Invoke API by sending HTTP request with the given options.
* *

View File

@ -20,6 +20,9 @@ import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.MultiPart; import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.MultiPartFeature;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -37,13 +40,15 @@ import java.io.UnsupportedEncodingException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.swagger.client.auth.Authentication; import io.swagger.client.auth.Authentication;
import io.swagger.client.auth.HttpBasicAuth; import io.swagger.client.auth.HttpBasicAuth;
import io.swagger.client.auth.ApiKeyAuth; import io.swagger.client.auth.ApiKeyAuth;
import io.swagger.client.auth.OAuth; import io.swagger.client.auth.OAuth;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class ApiClient { public class ApiClient {
private Map<String, String> defaultHeaderMap = new HashMap<String, String>(); private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private String basePath = "http://petstore.swagger.io/v2"; private String basePath = "http://petstore.swagger.io/v2";
@ -52,6 +57,7 @@ public class ApiClient {
private Client httpClient; private Client httpClient;
private JSON json; private JSON json;
private String tempFolderPath = null;
private Map<String, Authentication> authentications; private Map<String, Authentication> authentications;
@ -235,8 +241,24 @@ public class ApiClient {
} }
/** /**
* Connect timeout (in milliseconds). * The path of temporary folder used to store downloaded files from endpoints
*/ * with file response. The default value is <code>null</code>, i.e. using
* the system's default tempopary folder.
*
* @see https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File)
*/
public String getTempFolderPath() {
return tempFolderPath;
}
public ApiClient setTempFolderPath(String tempFolderPath) {
this.tempFolderPath = tempFolderPath;
return this;
}
/**
* Connect timeout (in milliseconds).
*/
public int getConnectTimeout() { public int getConnectTimeout() {
return connectionTimeout; return connectionTimeout;
} }
@ -246,11 +268,11 @@ public class ApiClient {
* A value of 0 means no timeout, otherwise values must be between 1 and * A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}. * {@link Integer#MAX_VALUE}.
*/ */
public ApiClient setConnectTimeout(int connectionTimeout) { public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout; this.connectionTimeout = connectionTimeout;
httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout); httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout);
return this; return this;
} }
/** /**
* Get the date format used to parse/format date parameters. * Get the date format used to parse/format date parameters.
@ -466,6 +488,13 @@ public class ApiClient {
* Deserialize response body to Java object according to the Content-Type. * Deserialize response body to Java object according to the Content-Type.
*/ */
public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException { public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException {
// Handle file downloading.
if (returnType.equals(File.class)) {
@SuppressWarnings("unchecked")
T file = (T) downloadFileFromResponse(response);
return file;
}
String contentType = null; String contentType = null;
List<Object> contentTypes = response.getHeaders().get("Content-Type"); List<Object> contentTypes = response.getHeaders().get("Content-Type");
if (contentTypes != null && !contentTypes.isEmpty()) if (contentTypes != null && !contentTypes.isEmpty())
@ -476,6 +505,55 @@ public class ApiClient {
return response.readEntity(returnType); return response.readEntity(returnType);
} }
/**
* Download file from the given response.
* @throws ApiException If fail to read file content from response and write to disk
*/
public File downloadFileFromResponse(Response response) throws ApiException {
try {
File file = prepareDownloadFile(response);
Files.copy(response.readEntity(InputStream.class), file.toPath());
return file;
} catch (IOException e) {
throw new ApiException(e);
}
}
public File prepareDownloadFile(Response response) throws IOException {
String filename = null;
String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition");
if (contentDisposition != null && !"".equals(contentDisposition)) {
// Get filename from the Content-Disposition header.
Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
Matcher matcher = pattern.matcher(contentDisposition);
if (matcher.find())
filename = matcher.group(1);
}
String prefix = null;
String suffix = null;
if (filename == null) {
prefix = "download-";
suffix = "";
} else {
int pos = filename.lastIndexOf(".");
if (pos == -1) {
prefix = filename + "-";
} else {
prefix = filename.substring(0, pos) + "-";
suffix = filename.substring(pos);
}
// File.createTempFile requires the prefix to be at least three characters long
if (prefix.length() < 3)
prefix = "download-";
}
if (tempFolderPath == null)
return File.createTempFile(prefix, suffix);
else
return File.createTempFile(prefix, suffix, new File(tempFolderPath));
}
/** /**
* Invoke API by sending HTTP request with the given options. * Invoke API by sending HTTP request with the given options.
* *

View File

@ -3,7 +3,7 @@ package io.swagger.client;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class ApiException extends Exception { public class ApiException extends Exception {
private int code = 0; private int code = 0;
private Map<String, List<String>> responseHeaders = null; private Map<String, List<String>> responseHeaders = null;

View File

@ -1,6 +1,6 @@
package io.swagger.client; package io.swagger.client;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class Configuration { public class Configuration {
private static ApiClient defaultApiClient = new ApiClient(); private static ApiClient defaultApiClient = new ApiClient();

View File

@ -8,7 +8,7 @@ import java.text.DateFormat;
import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.ContextResolver;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class JSON implements ContextResolver<ObjectMapper> { public class JSON implements ContextResolver<ObjectMapper> {
private ObjectMapper mapper; private ObjectMapper mapper;

View File

@ -1,6 +1,6 @@
package io.swagger.client; package io.swagger.client;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class Pair { public class Pair {
private String name = ""; private String name = "";
private String value = ""; private String value = "";

View File

@ -1,6 +1,6 @@
package io.swagger.client; package io.swagger.client;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class StringUtil { public class StringUtil {
/** /**
* Check if the given array contains the given value (with case-insensitive comparison). * Check if the given array contains the given value (with case-insensitive comparison).

View File

@ -12,7 +12,7 @@ import java.io.File;
import java.util.*; import java.util.*;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class PetApi { public class PetApi {
private ApiClient apiClient; private ApiClient apiClient;

View File

@ -12,7 +12,7 @@ import io.swagger.client.model.Order;
import java.util.*; import java.util.*;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class StoreApi { public class StoreApi {
private ApiClient apiClient; private ApiClient apiClient;

View File

@ -12,7 +12,7 @@ import java.util.*;
import java.util.*; import java.util.*;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class UserApi { public class UserApi {
private ApiClient apiClient; private ApiClient apiClient;

View File

@ -5,7 +5,7 @@ import io.swagger.client.Pair;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class ApiKeyAuth implements Authentication { public class ApiKeyAuth implements Authentication {
private final String location; private final String location;
private final String paramName; private final String paramName;

View File

@ -9,7 +9,7 @@ import java.util.List;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class HttpBasicAuth implements Authentication { public class HttpBasicAuth implements Authentication {
private String username; private String username;
private String password; private String password;

View File

@ -5,7 +5,7 @@ import io.swagger.client.Pair;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-05T14:39:17.660+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class OAuth implements Authentication { public class OAuth implements Authentication {
private String accessToken; private String accessToken;

View File

@ -10,7 +10,7 @@ import io.swagger.annotations.ApiModelProperty;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class Category { public class Category {
private Long id = null; private Long id = null;

View File

@ -11,7 +11,7 @@ import java.util.Date;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class Order { public class Order {
private Long id = null; private Long id = null;

View File

@ -13,7 +13,7 @@ import java.util.*;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class Pet { public class Pet {
private Long id = null; private Long id = null;

View File

@ -10,7 +10,7 @@ import io.swagger.annotations.ApiModelProperty;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class Tag { public class Tag {
private Long id = null; private Long id = null;

View File

@ -10,7 +10,7 @@ import io.swagger.annotations.ApiModelProperty;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-15T19:00:52.199+08:00") @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-01-28T16:23:25.238+01:00")
public class User { public class User {
private Long id = null; private Long id = null;