Переглянути джерело

RestAPI uploadFile 支持上传文件,支持 put

zhaopingxi 5 місяців тому
батько
коміт
05223dd67a
2 змінених файлів з 90 додано та 33 видалено
  1. 4 4
      httpclient/FluentHttpClient.java
  2. 86 29
      httpclient/RestApiUtils.java

+ 4 - 4
httpclient/FluentHttpClient.java

@@ -1,26 +1,26 @@
 <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpcore</artifactId>
-      <version>4.4.10</version>
+      <version>4.4.16</version>
       <scope>compile</scope>
     </dependency>
 
 <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
-      <version>4.5.6</version>
+      <version>4.5.14</version>
       <scope>compile</scope>
     </dependency>
 
 <dependency>
 			<groupId>org.apache.httpcomponents</groupId>
 			<artifactId>httpmime</artifactId>
-			<version>4.5.6</version>
+			<version>4.5.14</version>
 		</dependency>
 		<dependency>
 			<groupId>org.apache.httpcomponents</groupId>
 			<artifactId>fluent-hc</artifactId>
-			<version>4.5.6</version>
+			<version>4.5.14</version>
 		</dependency>
 
 

+ 86 - 29
httpclient/RestApiUtils.java

@@ -17,8 +17,10 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
 import org.apache.http.config.Registry;
 import org.apache.http.config.RegistryBuilder;
 import org.apache.http.config.SocketConfig;
@@ -26,11 +28,13 @@ import org.apache.http.conn.socket.ConnectionSocketFactory;
 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 import org.apache.http.conn.ssl.DefaultHostnameVerifier;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.FileEntity;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.http.params.BasicHttpParams;
@@ -106,6 +110,13 @@ public class RestApiUtils {
                             .setConnectTimeout(65000)
                             .setSocketTimeout(30000)
                             .setConnectionRequestTimeout(30000).build())
+                    .setRedirectStrategy(new DefaultRedirectStrategy() {
+                        @Override
+                        protected boolean isRedirectable(String method) {
+                            // If the connection target is FE, you need to handle 307 redirect.
+                            return true;
+                        }
+                    })
                     .setRetryHandler(new DefaultHttpRequestRetryHandler(3, false))
                     .build();
         } catch (Exception e) {
@@ -493,7 +504,7 @@ public class RestApiUtils {
         return filename;
     }
 
-
+    // -------------------------------上传文件-----------------------------------
     /**
      * 根据url上传文件
      *
@@ -503,26 +514,29 @@ public class RestApiUtils {
      */
     public static Map<String, Object> upload(String url,
                                              File uploadFile) throws IOException {
-        return upload(url, null, null, uploadFile, true);
+        return upload(url, null, null, uploadFile);
     }
 
     /**
      * 根据url上传文件
      *
      * @param url
+     * @param json payload 负载的消息参数
      * @param uploadFile
      * @return 返回 下载的文件路径
      */
     public static Map<String, Object> upload(String url,
                                              Map<String, Object> json,
                                              File uploadFile) throws IOException {
-        return upload(url, json, null, uploadFile, true);
+        return upload(url, json, null, uploadFile);
     }
 
     /**
      * 根据url上传文件
      *
      * @param url
+     * @param json payload 负载的消息参数
+     * @param headers Http Header
      * @param uploadFile
      * @return 返回 下载的文件路径
      */
@@ -530,13 +544,33 @@ public class RestApiUtils {
                                              Map<String, Object> json,
                                              Map<String, String> headers,
                                              File uploadFile) throws IOException {
-        return upload(url, json, headers, uploadFile, true);
+        return upload(url, json, headers, uploadFile, -1, -1, true);
     }
 
     /**
      * 根据url上传文件
      *
      * @param url
+     * @param json payload 负载的消息参数
+     * @param headers Http Header
+     * @param uploadFile
+     * @param usePut 采用 PUT 请求上传文件
+     * @return 返回 下载的文件路径
+     */
+    public static Map<String, Object> upload(String url,
+                                             Map<String, Object> json,
+                                             Map<String, String> headers,
+                                             File uploadFile,
+                                             boolean usePut) throws IOException {
+        return upload(url, json, headers, uploadFile, -1, -1, usePut, true);
+    }
+
+    /**
+     * 根据 url 上传文件
+     *
+     * @param url
+     * @param json payload 负载的消息
+     * @param headers Http Header
      * @param uploadFile
      * @return 返回 下载的文件路径
      */
@@ -544,45 +578,72 @@ public class RestApiUtils {
                                              Map<String, Object> json,
                                              Map<String, String> headers,
                                              File uploadFile,
+                                             int connectTimeout,
+                                             int socketTimeout,
+                                             boolean not200ThrowError) throws IOException {
+        return upload(url, json, headers, uploadFile, connectTimeout, socketTimeout, false, not200ThrowError);
+    }
+
+    /**
+     * 根据 url 上传文件
+     *
+     * @param url
+     * @param json payload 负载的消息
+     * @param headers Http Header
+     * @param uploadFile
+     * @param usePut 采用 PUT 请求
+     * @return 返回 下载的文件路径
+     */
+    public static Map<String, Object> upload(String url,
+                                             Map<String, Object> json,
+                                             Map<String, String> headers,
+                                             File uploadFile,
+                                             int connectTimeout,
+                                             int socketTimeout,
+                                             boolean usePut,
                                              boolean not200ThrowError) throws IOException {
         // 文件夹 或者 是 文件不存在
         if(!uploadFile.exists()) {
-            throw new FileNotFoundException(uploadFile.getAbsolutePath() + " can not found!");
+            throw new FileNotFoundException("upload file: " + uploadFile.getAbsolutePath() + " can not found!");
         }
         if(uploadFile.isDirectory()) {
             throw new IllegalStateException("upload payload must be file, but found directory.");
         }
 
-        HttpPost httpPost = new HttpPost(url);
-        RequestConfig requestConfig = RequestConfig.custom()
-                .setConnectTimeout(30000)  // 服务器端链接超时设置 30s
-                .setSocketTimeout(10 * 60 * 1000)  // 上传等待 10 分钟
-                .build();
-        httpPost.setConfig(requestConfig);
+        HttpEntityEnclosingRequestBase httpPost = usePut ? new HttpPut(url) : new HttpPost(url);
+        if(connectTimeout > 0 || socketTimeout >= 0) {
+            RequestConfig requestConfig = RequestConfig.custom()
+                    .setConnectTimeout(connectTimeout <= 0 ? 30000 : connectTimeout)  // 服务器端链接超时设置 30s
+                    .setSocketTimeout(socketTimeout <= 0 ? 10 * 60 * 1000 : socketTimeout)  // 上传等待 10 分钟
+                    .build();
+            httpPost.setConfig(requestConfig);
+        }
         if(headers != null) {
             for (Map.Entry<String, String> entry : headers.entrySet()) {
                 httpPost.setHeader(entry.getKey(), entry.getValue());
             }
         }
 
-        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
-        multipartEntityBuilder.setCharset(StandardCharsets.UTF_8);
-
-        //multipartEntityBuilder.addBinaryBody("file", file,ContentType.create("image/png"),"abc.pdf");
-        //当设置了setSocketTimeout参数后,以下代码上传PDF不能成功,将setSocketTimeout参数去掉后此可以上传成功。上传图片则没有个限制
-        //multipartEntityBuilder.addBinaryBody("file",file,ContentType.create("application/octet-stream"),"abd.pdf");
-        multipartEntityBuilder.addBinaryBody("file", uploadFile);
-        if(json != null) {
+        if(json != null && !json.isEmpty()) {
+            // 有文件上传,并且又负载的消息
+            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
+            multipartEntityBuilder.setCharset(StandardCharsets.UTF_8);
+
+            //multipartEntityBuilder.addBinaryBody("file", file,ContentType.create("image/png"),"abc.pdf");
+            //当设置了setSocketTimeout参数后,以下代码上传PDF不能成功,将setSocketTimeout参数去掉后此可以上传成功。上传图片则没有个限制
+            //multipartEntityBuilder.addBinaryBody("file",file,ContentType.create("application/octet-stream"),"abd.pdf");
+            multipartEntityBuilder.addBinaryBody("file", uploadFile);
             for (Map.Entry<String, Object> entry : json.entrySet()) {
                 multipartEntityBuilder.addTextBody(entry.getKey(), (String) entry.getValue());
             }
+            HttpEntity httpEntity = multipartEntityBuilder.build();
+            httpPost.setEntity(httpEntity);
+        } else {
+            // 只有文件上传
+            FileEntity entity = new FileEntity(uploadFile);
+            httpPost.setEntity(entity);
         }
-        HttpEntity httpEntity = multipartEntityBuilder.build();
-        httpPost.setEntity(httpEntity);
-
-        CloseableHttpResponse httpResponse = null;
-        try {
-            httpResponse = httpClient.execute(httpPost);
+        try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost);){
             HttpEntity responseEntity = httpResponse.getEntity();
             int statusCode = httpResponse.getStatusLine().getStatusCode();
             String result = EntityUtils.toString(responseEntity);
@@ -599,10 +660,6 @@ public class RestApiUtils {
             }
             jsonObject.put("status_code", statusCode);
             return jsonObject;
-        } finally {
-            if(httpResponse != null) {
-                httpResponse.close();
-            }
         }
     }