diff --git a/src/main/java/im/zhaojun/zfile/core/config/RestTemplateConfig.java b/src/main/java/im/zhaojun/zfile/core/config/RestTemplateConfig.java
index d3e485b..86cef7b 100644
--- a/src/main/java/im/zhaojun/zfile/core/config/RestTemplateConfig.java
+++ b/src/main/java/im/zhaojun/zfile/core/config/RestTemplateConfig.java
@@ -1,25 +1,10 @@
package im.zhaojun.zfile.core.config;
-import im.zhaojun.zfile.module.storage.constant.StorageConfigConstant;
-import im.zhaojun.zfile.module.storage.model.entity.StorageSourceConfig;
-import im.zhaojun.zfile.module.storage.service.StorageSourceConfigService;
-import org.apache.http.client.HttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
+import im.zhaojun.zfile.core.httpclient.ZFileOkHttp3ClientHttpRequestFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.client.ClientHttpRequestInterceptor;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
-import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
-import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
-import javax.annotation.Resource;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.List;
-
/**
* restTemplate 相关配置
*
@@ -27,53 +12,16 @@ import java.util.List;
*/
@Configuration
public class RestTemplateConfig {
-
- @Resource
- private StorageSourceConfigService storageSourceConfigService;
-
- /**
- * OneDrive 请求 RestTemplate.
- * 获取 header 中的 storageId 来判断到底是哪个存储源 ID, 在请求头中添加 Bearer: Authorization {token} 信息, 用于 API 认证.
- */
- @Bean
- public RestTemplate oneDriveRestTemplate() {
- RestTemplate restTemplate = new RestTemplate();
- OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory();
- restTemplate.setRequestFactory(factory);
- ClientHttpRequestInterceptor interceptor = (httpRequest, bytes, clientHttpRequestExecution) -> {
- HttpHeaders headers = httpRequest.getHeaders();
- Integer storageId = Integer.valueOf(((List)headers.get("storageId")).get(0).toString());
-
- StorageSourceConfig accessTokenConfig =
- storageSourceConfigService.findByStorageIdAndName(storageId, StorageConfigConstant.ACCESS_TOKEN_KEY);
-
- String tokenValue = String.format("%s %s", "Bearer", accessTokenConfig.getValue());
- httpRequest.getHeaders().add("Authorization", tokenValue);
- return clientHttpRequestExecution.execute(httpRequest, bytes);
- };
- restTemplate.setInterceptors(Collections.singletonList(interceptor));
- return restTemplate;
- }
-
-
- /**
- * restTemplate 设置请求和响应字符集都为 UTF-8, 并设置响应头为 Content-Type: application/text;
- */
- @Bean
- public RestTemplate restTemplate(){
- HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
- HttpClient httpClient = HttpClientBuilder.create().build();
- httpRequestFactory.setHttpClient(httpClient);
- RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
- restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
- restTemplate.setInterceptors(Collections.singletonList((request, body, execution) -> {
- ClientHttpResponse response = execution.execute(request, body);
- HttpHeaders headers = response.getHeaders();
- headers.put("Content-Type", Collections.singletonList("application/text"));
- return response;
- }));
-
- return restTemplate;
- }
-
+
+ /**
+ * OneDrive 请求 RestTemplate.
+ * 获取 header 中的 storageId 来判断到底是哪个存储源 ID, 在请求头中添加 Bearer: Authorization {token} 信息, 用于 API 认证.
+ */
+ @Bean
+ public RestTemplate oneDriveRestTemplate() {
+ RestTemplate restTemplate = new RestTemplate();
+ restTemplate.setRequestFactory(new ZFileOkHttp3ClientHttpRequestFactory());
+ return restTemplate;
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/im/zhaojun/zfile/core/exception/ZFileRetryException.java b/src/main/java/im/zhaojun/zfile/core/exception/ZFileRetryException.java
new file mode 100644
index 0000000..28138e7
--- /dev/null
+++ b/src/main/java/im/zhaojun/zfile/core/exception/ZFileRetryException.java
@@ -0,0 +1,26 @@
+package im.zhaojun.zfile.core.exception;
+
+/**
+ * @author zhaojun
+ */
+public class ZFileRetryException extends RuntimeException {
+
+ public ZFileRetryException() {
+ }
+
+ public ZFileRetryException(String message) {
+ super(message);
+ }
+
+ public ZFileRetryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ZFileRetryException(Throwable cause) {
+ super(cause);
+ }
+
+ public ZFileRetryException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/im/zhaojun/zfile/core/httpclient/ZFileOkHttp3ClientHttpRequestFactory.java b/src/main/java/im/zhaojun/zfile/core/httpclient/ZFileOkHttp3ClientHttpRequestFactory.java
new file mode 100644
index 0000000..97ee508
--- /dev/null
+++ b/src/main/java/im/zhaojun/zfile/core/httpclient/ZFileOkHttp3ClientHttpRequestFactory.java
@@ -0,0 +1,22 @@
+package im.zhaojun.zfile.core.httpclient;
+
+import im.zhaojun.zfile.core.httpclient.logging.HttpLoggingInterceptor;
+import okhttp3.OkHttpClient;
+import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
+
+/**
+ * 自建 OkHTTP3 客户端工厂类, 增加日志输出拦截器.
+ * @author zhaojun
+ */
+public class ZFileOkHttp3ClientHttpRequestFactory extends OkHttp3ClientHttpRequestFactory {
+
+ public ZFileOkHttp3ClientHttpRequestFactory() {
+ // 使用 OkHttp3 作为底层请求库, 并设置重试机制和日志拦截器
+ super(new OkHttpClient()
+ .newBuilder()
+ .addNetworkInterceptor(new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEBUG)
+ .setLevel(HttpLoggingInterceptor.Level.HEADERS))
+ .build());
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/im/zhaojun/zfile/core/httpclient/logging/HttpLoggingInterceptor.java b/src/main/java/im/zhaojun/zfile/core/httpclient/logging/HttpLoggingInterceptor.java
new file mode 100644
index 0000000..a84b66c
--- /dev/null
+++ b/src/main/java/im/zhaojun/zfile/core/httpclient/logging/HttpLoggingInterceptor.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2015 Square, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package im.zhaojun.zfile.core.httpclient.logging;
+
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.Connection;
+import okhttp3.Headers;
+import okhttp3.Interceptor;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okhttp3.internal.http.HttpHeaders;
+import okhttp3.internal.platform.Platform;
+import okio.Buffer;
+import okio.BufferedSource;
+import okio.GzipSource;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+
+import static okhttp3.internal.platform.Platform.INFO;
+
+/**
+ * 此类代码来源于 logging-interceptor.
+ *
+ * An OkHttp interceptor which logs request and response information. Can be applied as an
+ * {@linkplain OkHttpClient#interceptors() application interceptor} or as a {@linkplain
+ * OkHttpClient#networkInterceptors() network interceptor}.
The format of the logs created by
+ * this class should not be considered stable and may change slightly between releases. If you need
+ * a stable logging format, use your own interceptor.
+ *
+ * @author zhaojun
+ */
+@Slf4j
+public final class HttpLoggingInterceptor implements Interceptor {
+
+ private static final Charset UTF8 = StandardCharsets.UTF_8;
+
+ public enum Level {
+ /** No logs. */
+ NONE,
+ /**
+ * Logs request and response lines.
+ *
+ *
Example: + *
{@code
+ * --> POST /greeting http/1.1 (3-byte body)
+ *
+ * <-- 200 OK (22ms, 6-byte body)
+ * }
+ */
+ BASIC,
+ /**
+ * Logs request and response lines and their respective headers.
+ *
+ * Example: + *
{@code
+ * --> POST /greeting http/1.1
+ * Host: example.com
+ * Content-Type: plain/text
+ * Content-Length: 3
+ * --> END POST
+ *
+ * <-- 200 OK (22ms)
+ * Content-Type: plain/text
+ * Content-Length: 6
+ * <-- END HTTP
+ * }
+ */
+ HEADERS,
+ /**
+ * Logs request and response lines and their respective headers and bodies (if present).
+ *
+ * Example: + *
{@code
+ * --> POST /greeting http/1.1
+ * Host: example.com
+ * Content-Type: plain/text
+ * Content-Length: 3
+ *
+ * Hi?
+ * --> END POST
+ *
+ * <-- 200 OK (22ms)
+ * Content-Type: plain/text
+ * Content-Length: 6
+ *
+ * Hello!
+ * <-- END HTTP
+ * }
+ */
+ BODY
+ }
+
+ public interface Logger {
+ void log(String message);
+
+ /** A {@link Logger} defaults output appropriate for the current platform. */
+ Logger DEFAULT = message -> Platform.get().log(INFO, message, null);
+
+ Logger DEBUG = log::debug;
+ Logger TRACE = log::trace;
+
+ }
+
+ public HttpLoggingInterceptor() {
+ this(Logger.DEFAULT);
+ }
+
+ public HttpLoggingInterceptor(Logger logger) {
+ this.logger = logger;
+ }
+
+ private final Logger logger;
+
+ private volatile Set