feat: 优化代码,清理冗余项目,修复超时时间

This commit is contained in:
wangyu 2023-01-11 10:55:33 +08:00
parent 4345b9543a
commit 605615d370
21 changed files with 305 additions and 80 deletions

11
pom.xml
View File

@ -20,7 +20,6 @@
<maven.compiler.target>8</maven.compiler.target> <maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<fastjson.version>2.0.22</fastjson.version>
<commons-collection.version>4.4</commons-collection.version> <commons-collection.version>4.4</commons-collection.version>
<commons.lang.version>2.6</commons.lang.version> <commons.lang.version>2.6</commons.lang.version>
<sdk.version>1.0.0</sdk.version> <sdk.version>1.0.0</sdk.version>
@ -46,21 +45,11 @@
<artifactId>commons-collections4</artifactId> <artifactId>commons-collections4</artifactId>
<version>${commons-collection.version}</version> <version>${commons-collection.version}</version>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency> <dependency>
<groupId>org.reflections</groupId> <groupId>org.reflections</groupId>
<artifactId>reflections</artifactId> <artifactId>reflections</artifactId>
<version>0.10.2</version> <version>0.10.2</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency> <dependency>
<groupId>group.flyfish</groupId> <groupId>group.flyfish</groupId>
<artifactId>rest-proxy-api</artifactId> <artifactId>rest-proxy-api</artifactId>

View File

@ -31,5 +31,5 @@ public @interface RestService {
* *
* @return 结果 * @return 结果
*/ */
long timeout() default -1L; int timeout() default -1;
} }

View File

@ -57,10 +57,6 @@
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId> <artifactId>httpmime</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>

View File

@ -1,18 +1,15 @@
package group.flyfish.rest.client; package group.flyfish.rest.core.client;
import group.flyfish.rest.core.builder.RestClientBuilder;
import group.flyfish.rest.core.exception.RestClientException;
import group.flyfish.rest.core.produce.HttpClientProducer;
import group.flyfish.rest.enums.ResponseType;
import group.flyfish.rest.utils.JacksonUtil;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JavaType;
import group.flyfish.rest.core.exception.RestClientException;
import group.flyfish.rest.enums.ResponseType;
import group.flyfish.rest.utils.JacksonUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.StatusLine; import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
@ -27,7 +24,7 @@ import java.util.function.Consumer;
import static group.flyfish.rest.constants.RestConstants.DEFAULT_EXECUTOR; import static group.flyfish.rest.constants.RestConstants.DEFAULT_EXECUTOR;
/** /**
* Rest请求客户端 * Rest请求客户端 Apache http实现
* *
* @author Mr.Wang * @author Mr.Wang
* <p> * <p>
@ -39,9 +36,8 @@ import static group.flyfish.rest.constants.RestConstants.DEFAULT_EXECUTOR;
* 6. 新增单例httpClient模式复用连接让应用更高效 * 6. 新增单例httpClient模式复用连接让应用更高效
*/ */
@Slf4j @Slf4j
public final class RestClient { final class DefaultRestClient implements RestClient {
private static volatile CloseableHttpClient client;
private final HttpRequestBase request; private final HttpRequestBase request;
private boolean async = false; private boolean async = false;
private Consumer<HttpEntity> consumer; private Consumer<HttpEntity> consumer;
@ -57,34 +53,17 @@ public final class RestClient {
* *
* @param request 请求信息 * @param request 请求信息
*/ */
public RestClient(HttpRequestBase request) { DefaultRestClient(HttpRequestBase request) {
this.request = request; this.request = request;
} }
/**
* 设置单例的客户端
*
* @param client 客户端
*/
public static void setClient(CloseableHttpClient client) {
RestClient.client = client;
}
/**
* 新增一个构建器
*
* @return 结果
*/
public static RestClientBuilder create() {
return new RestClientBuilder();
}
/** /**
* 设置请求失败时的回调 * 设置请求失败时的回调
* *
* @param errorConsumer 错误回调 * @param errorConsumer 错误回调
* @return 结果 * @return 结果
*/ */
@Override
public RestClient onError(Consumer<RestClientException> errorConsumer) { public RestClient onError(Consumer<RestClientException> errorConsumer) {
this.errorConsumer = errorConsumer; this.errorConsumer = errorConsumer;
return this; return this;
@ -109,6 +88,7 @@ public final class RestClient {
* @param responseType 响应类型 * @param responseType 响应类型
* @return 结果 * @return 结果
*/ */
@Override
public RestClient responseType(ResponseType responseType) { public RestClient responseType(ResponseType responseType) {
this.responseType = responseType; this.responseType = responseType;
return this; return this;
@ -119,6 +99,7 @@ public final class RestClient {
* *
* @return 结果 * @return 结果
*/ */
@Override
public RestClient async() { public RestClient async() {
this.async = true; this.async = true;
this.executorService = DEFAULT_EXECUTOR; this.executorService = DEFAULT_EXECUTOR;
@ -131,6 +112,7 @@ public final class RestClient {
* @param executorService 线程池 * @param executorService 线程池
* @return 结果 * @return 结果
*/ */
@Override
public RestClient async(ExecutorService executorService) { public RestClient async(ExecutorService executorService) {
this.async = true; this.async = true;
this.executorService = executorService; this.executorService = executorService;
@ -142,6 +124,7 @@ public final class RestClient {
* *
* @param consumer 结果 * @param consumer 结果
*/ */
@Override
public void execute(Consumer<HttpEntity> consumer) { public void execute(Consumer<HttpEntity> consumer) {
this.consumer = consumer; this.consumer = consumer;
if (this.async) { if (this.async) {
@ -157,6 +140,7 @@ public final class RestClient {
/** /**
* 静默执行抛弃全部异常 * 静默执行抛弃全部异常
*/ */
@Override
public void executeSilent() { public void executeSilent() {
executeSafety(); executeSafety();
} }
@ -167,6 +151,7 @@ public final class RestClient {
* @return map * @return map
* @throws IOException 异常 * @throws IOException 异常
*/ */
@Override
public Map<String, Object> executeForMap() throws IOException { public Map<String, Object> executeForMap() throws IOException {
this.responseType = ResponseType.JSON; this.responseType = ResponseType.JSON;
return innerExecute(); return innerExecute();
@ -178,6 +163,7 @@ public final class RestClient {
* @return 字符串 * @return 字符串
* @throws IOException 异常 * @throws IOException 异常
*/ */
@Override
public String executeForString() throws IOException { public String executeForString() throws IOException {
this.responseType = ResponseType.TEXT; this.responseType = ResponseType.TEXT;
return innerExecute(); return innerExecute();
@ -202,13 +188,14 @@ public final class RestClient {
* @return 结果 * @return 结果
*/ */
@Nullable @Nullable
@Override
public <T> T execute(Class<T> clazz) { public <T> T execute(Class<T> clazz) {
this.responseType = ResponseType.OBJECT; this.responseType = ResponseType.OBJECT;
this.resultClass = clazz; this.resultClass = clazz;
try { try {
return innerExecute(); return innerExecute();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("请求时发生异常!", e);
} }
return null; return null;
} }
@ -221,25 +208,34 @@ public final class RestClient {
* @return 结果 * @return 结果
*/ */
@Nullable @Nullable
@Override
public <T> T execute(JavaType type) { public <T> T execute(JavaType type) {
this.responseType = ResponseType.OBJECT; this.responseType = ResponseType.OBJECT;
this.resultType = type; this.resultType = type;
try { try {
return innerExecute(); return innerExecute();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("请求时发生异常!", e);
} }
return null; return null;
} }
/**
* 执行序列化使用类型引用
*
* @param typeReference jackson 类型引用
* @param <T> 泛型
* @return 序列化结果
*/
@Nullable @Nullable
@Override
public <T> T execute(TypeReference<T> typeReference) { public <T> T execute(TypeReference<T> typeReference) {
this.responseType = ResponseType.OBJECT; this.responseType = ResponseType.OBJECT;
this.typeReference = typeReference; this.typeReference = typeReference;
try { try {
return innerExecute(); return innerExecute();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("请求时发生异常!", e);
} }
return null; return null;
} }
@ -250,10 +246,12 @@ public final class RestClient {
* @return 响应实体 * @return 响应实体
* @throws IOException 异常 * @throws IOException 异常
*/ */
@Override
public <T> T execute() throws IOException { public <T> T execute() throws IOException {
return innerExecute(); return innerExecute();
} }
/** /**
* 内部执行方法预处理结果 * 内部执行方法预处理结果
* *
@ -261,11 +259,8 @@ public final class RestClient {
* @return 结果 * @return 结果
*/ */
private <T> T innerExecute() throws IOException { private <T> T innerExecute() throws IOException {
if (null == client) {
client = HttpClientProducer.produce();
}
log.info("【Rest Invoke】{} {}", request.getMethod(), request.getURI()); log.info("【Rest Invoke】{} {}", request.getMethod(), request.getURI());
try (CloseableHttpResponse response = client.execute(request)) { try (CloseableHttpResponse response = HttpClientCache.getClient().execute(request)) {
StatusLine statusLine = response.getStatusLine(); StatusLine statusLine = response.getStatusLine();
if (200 == statusLine.getStatusCode()) { if (200 == statusLine.getStatusCode()) {
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();

View File

@ -0,0 +1,41 @@
package group.flyfish.rest.core.client;
import group.flyfish.rest.core.produce.HttpClientProducer;
import org.apache.http.impl.client.CloseableHttpClient;
import java.io.IOException;
/**
* http请求客户端缓存
*
* @author wangyu
*/
class HttpClientCache {
private volatile CloseableHttpClient client;
private static final HttpClientCache INSTANCE = new HttpClientCache();
/**
* 获取共享client
*
* @return 结果
*/
CloseableHttpClient computeClient() throws IOException {
if (null == client) {
synchronized (INSTANCE) {
if (null != client) return client;
return client = HttpClientProducer.produce();
}
}
return client;
}
public static CloseableHttpClient getClient() throws IOException {
return INSTANCE.computeClient();
}
public static void setClient(CloseableHttpClient client) {
INSTANCE.client = client;
}
}

View File

@ -0,0 +1,144 @@
package group.flyfish.rest.core.client;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import group.flyfish.rest.core.exception.RestClientException;
import group.flyfish.rest.enums.ResponseType;
import org.apache.http.HttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.lang.Nullable;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
/**
* Rest请求客户端
*
* @author Mr.Wang
* <p>
* @apiNote 1. 全builder调用用户系统内部相互通信
* 2. 支持异步回调
* 3. 多样性组合
* 4. 解耦实现
* 5. 支持上传文件FormDataJSON支持自定义无侵入扩展
* 6. 新增单例httpClient模式复用连接让应用更高效
*/
public interface RestClient {
/**
* 新增一个构建器
*
* @return 结果
*/
static RestClientBuilder create() {
return new RestClientBuilder();
}
/**
* 设置单例的客户端
*
* @param client 客户端
*/
static void setClient(CloseableHttpClient client) {
HttpClientCache.setClient(client);
}
/**
* 标记线程池执行
*
* @return 结果
*/
RestClient async();
/**
* 标记指定线程池执行
*
* @param executorService 线程池
* @return 结果
*/
RestClient async(ExecutorService executorService);
/**
* 设置响应类型
*
* @param responseType 响应类型
* @return 结果
*/
RestClient responseType(ResponseType responseType);
/**
* 异步执行接收结果
*
* @param consumer 结果
*/
void execute(Consumer<HttpEntity> consumer);
/**
* 静默执行抛弃全部异常
*/
void executeSilent();
/**
* 执行请求返回Map
*
* @return map
* @throws IOException 异常
*/
Map<String, Object> executeForMap() throws IOException;
/**
* 执行请求返回字符串
*
* @return 字符串
* @throws IOException 异常
*/
String executeForString() throws IOException;
/**
* 执行并序列化该方法会安全的返回对象或者空
*
* @param clazz
* @param <T> 泛型
* @return 结果
*/
@Nullable
<T> T execute(Class<T> clazz);
/**
* 执行并序列化使用复杂的自动构造的类型
*
* @param type jackson的强化类型
* @param <T> 泛型
* @return 结果
*/
@Nullable
<T> T execute(JavaType type);
/**
* 执行序列化使用类型引用
*
* @param typeReference jackson 类型引用
* @param <T> 泛型
* @return 序列化结果
*/
@Nullable
<T> T execute(TypeReference<T> typeReference);
/**
* 执行请求返回响应实体自行处理
*
* @return 响应实体
* @throws IOException 异常
*/
<T> T execute() throws IOException;
/**
* 设置请求失败时的回调
*
* @param errorConsumer 错误回调
* @return 结果
*/
RestClient onError(Consumer<RestClientException> errorConsumer);
}

View File

@ -1,11 +1,11 @@
package group.flyfish.rest.core.builder; package group.flyfish.rest.core.client;
import group.flyfish.rest.client.RestClient;
import group.flyfish.rest.core.entity.Multipart; import group.flyfish.rest.core.entity.Multipart;
import group.flyfish.rest.enums.HttpMethod; import group.flyfish.rest.enums.HttpMethod;
import group.flyfish.rest.utils.DataUtils; import group.flyfish.rest.utils.DataUtils;
import group.flyfish.rest.utils.JacksonUtil; import group.flyfish.rest.utils.JacksonUtil;
import group.flyfish.rest.utils.RequestContext; import group.flyfish.rest.utils.RequestContext;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -42,6 +42,8 @@ public class RestClientBuilder {
private String charset; private String charset;
private RequestConfig config;
public String getUrl() { public String getUrl() {
return url; return url;
} }
@ -109,6 +111,11 @@ public class RestClientBuilder {
return this; return this;
} }
public RestClientBuilder config(RequestConfig config) {
this.config = config;
return this;
}
public Charset getCharset() { public Charset getCharset() {
return DataUtils.isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset); return DataUtils.isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset);
} }
@ -179,7 +186,7 @@ public class RestClientBuilder {
// 添加头 // 添加头
getHeaders().forEach(request::addHeader); getHeaders().forEach(request::addHeader);
// 设置公共设置 // 设置公共设置
request.setConfig(REQUEST_CONFIG); request.setConfig(null == config ? REQUEST_CONFIG : config);
// 返回 // 返回
return request; return request;
} }
@ -192,8 +199,7 @@ public class RestClientBuilder {
public RestClient build() { public RestClient build() {
// 创建请求 // 创建请求
HttpRequestBase request = buildRequest(); HttpRequestBase request = buildRequest();
return new RestClient(request); return new DefaultRestClient(request);
} }
} }

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver; package group.flyfish.rest.core.resolver;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.core.resolver.support.AbstractParamResolver; import group.flyfish.rest.core.resolver.support.AbstractParamResolver;
import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver; package group.flyfish.rest.core.resolver;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.core.resolver.support.AbstractParamResolver; import group.flyfish.rest.core.resolver.support.AbstractParamResolver;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver; package group.flyfish.rest.core.resolver;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;
/** /**

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver; package group.flyfish.rest.core.resolver;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.core.resolver.support.AbstractBodyResolver; import group.flyfish.rest.core.resolver.support.AbstractBodyResolver;
import org.apache.http.client.methods.HttpPatch; import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver; package group.flyfish.rest.core.resolver;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.core.resolver.support.AbstractBodyResolver; import group.flyfish.rest.core.resolver.support.AbstractBodyResolver;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver; package group.flyfish.rest.core.resolver;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.core.resolver.support.AbstractBodyResolver; import group.flyfish.rest.core.resolver.support.AbstractBodyResolver;
import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;

View File

@ -1,8 +1,7 @@
package group.flyfish.rest.core.resolver.support; package group.flyfish.rest.core.resolver.support;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.utils.DataUtils; import group.flyfish.rest.utils.DataUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.entity.UrlEncodedFormEntity;
@ -54,11 +53,11 @@ public abstract class AbstractBodyResolver {
String filename = multipart.getFilename(); String filename = multipart.getFilename();
if (data instanceof byte[]) { if (data instanceof byte[]) {
builder.addBinaryBody(name, (byte[]) data, builder.addBinaryBody(name, (byte[]) data,
ContentType.create(MIME_MAP.getOrDefault(FilenameUtils.getExtension(filename), ContentType.create(MIME_MAP.getOrDefault(DataUtils.getExtension(filename),
ContentType.APPLICATION_OCTET_STREAM.getMimeType())), filename); ContentType.APPLICATION_OCTET_STREAM.getMimeType())), filename);
} else if (data instanceof File) { } else if (data instanceof File) {
builder.addBinaryBody(name, (File) data, builder.addBinaryBody(name, (File) data,
ContentType.create(MIME_MAP.getOrDefault(FilenameUtils.getExtension(filename), ContentType.create(MIME_MAP.getOrDefault(DataUtils.getExtension(filename),
ContentType.APPLICATION_OCTET_STREAM.getMimeType())), filename); ContentType.APPLICATION_OCTET_STREAM.getMimeType())), filename);
} else { } else {
throw new IllegalArgumentException("上传时,输入的数据不被支持!"); throw new IllegalArgumentException("上传时,输入的数据不被支持!");

View File

@ -1,6 +1,6 @@
package group.flyfish.rest.core.resolver.support; package group.flyfish.rest.core.resolver.support;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.utils.DataUtils; import group.flyfish.rest.utils.DataUtils;
import java.util.stream.Collectors; import java.util.stream.Collectors;

View File

@ -2,7 +2,7 @@ package group.flyfish.rest.registry;
import group.flyfish.rest.annotation.EnableRestApiProxy; import group.flyfish.rest.annotation.EnableRestApiProxy;
import group.flyfish.rest.annotation.RestService; import group.flyfish.rest.annotation.RestService;
import group.flyfish.rest.client.RestClient; import group.flyfish.rest.core.client.RestClient;
import group.flyfish.rest.configuration.RestClientProperties; import group.flyfish.rest.configuration.RestClientProperties;
import group.flyfish.rest.core.produce.HttpClientProducer; import group.flyfish.rest.core.produce.HttpClientProducer;
import group.flyfish.rest.registry.proxy.RestProxyInvoker; import group.flyfish.rest.registry.proxy.RestProxyInvoker;

View File

@ -1,11 +1,12 @@
package group.flyfish.rest.registry.proxy; package group.flyfish.rest.registry.proxy;
import com.fasterxml.jackson.databind.JavaType;
import group.flyfish.rest.annotation.AutoMapping; import group.flyfish.rest.annotation.AutoMapping;
import group.flyfish.rest.annotation.RestApi; import group.flyfish.rest.annotation.RestApi;
import group.flyfish.rest.annotation.RestService; import group.flyfish.rest.annotation.RestService;
import group.flyfish.rest.client.RestClient;
import group.flyfish.rest.configuration.RestClientProperties; import group.flyfish.rest.configuration.RestClientProperties;
import group.flyfish.rest.core.builder.RestClientBuilder; import group.flyfish.rest.core.client.RestClient;
import group.flyfish.rest.core.client.RestClientBuilder;
import group.flyfish.rest.mapping.RestResultMapping; import group.flyfish.rest.mapping.RestResultMapping;
import group.flyfish.rest.registry.proxy.support.ArgumentResolveContext; import group.flyfish.rest.registry.proxy.support.ArgumentResolveContext;
import group.flyfish.rest.registry.proxy.support.RestArgumentResolverComposite; import group.flyfish.rest.registry.proxy.support.RestArgumentResolverComposite;
@ -13,7 +14,8 @@ import group.flyfish.rest.registry.proxy.support.UrlCompiler;
import group.flyfish.rest.registry.wrapper.DefaultRestResultMapping; import group.flyfish.rest.registry.wrapper.DefaultRestResultMapping;
import group.flyfish.rest.utils.DataUtils; import group.flyfish.rest.utils.DataUtils;
import group.flyfish.rest.utils.JacksonUtil; import group.flyfish.rest.utils.JacksonUtil;
import com.fasterxml.jackson.databind.JavaType; import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.springframework.aop.support.AopUtils; import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -34,19 +36,25 @@ import java.util.stream.Stream;
* *
* @author wangyu * @author wangyu
*/ */
@Slf4j
public class RestProxyInvoker<T> implements InvocationHandler { public class RestProxyInvoker<T> implements InvocationHandler {
// 要代理的目标类 // 要代理的目标类
private final Class<T> targetType; private final Class<T> targetType;
// 解析集合 // 解析集合
private final RestArgumentResolverComposite composite; private final RestArgumentResolverComposite composite;
// 服务映射
private final RestService restService;
// 初始的基本路径 // 初始的基本路径
private String baseUrl; private String baseUrl;
// 超时时间
private RequestConfig config;
// 基础url // 基础url
private RestClientProperties properties; private RestClientProperties properties;
// 结果映射 // 结果映射
private RestResultMapping mapping; private RestResultMapping mapping;
/** /**
* 构造器 * 构造器
* *
@ -56,6 +64,8 @@ public class RestProxyInvoker<T> implements InvocationHandler {
public RestProxyInvoker(Class<T> targetType, RestArgumentResolverComposite composite) { public RestProxyInvoker(Class<T> targetType, RestArgumentResolverComposite composite) {
this.targetType = targetType; this.targetType = targetType;
this.composite = composite; this.composite = composite;
// 注解的优先级高于全局基本路径
this.restService = AnnotationUtils.findAnnotation(targetType, RestService.class);
} }
/** /**
@ -78,6 +88,10 @@ public class RestProxyInvoker<T> implements InvocationHandler {
*/ */
public void configure(RestClientProperties properties) { public void configure(RestClientProperties properties) {
this.properties = properties; this.properties = properties;
this.config = RequestConfig.custom()
.setConnectTimeout((int) properties.getConnectionTimeout().toMillis())
.setSocketTimeout(restService.timeout())
.build();
this.baseUrl = this.findBaseUrl(); this.baseUrl = this.findBaseUrl();
} }
@ -112,7 +126,8 @@ public class RestProxyInvoker<T> implements InvocationHandler {
// 构造和调用这里的restClient不保存状态 // 构造和调用这里的restClient不保存状态
RestClientBuilder builder = RestClient.create() RestClientBuilder builder = RestClient.create()
.url(determineUrl(restApi, context)) .url(determineUrl(restApi, context))
.method(restApi.method()); .method(restApi.method())
.config(config);
// 需要带cookie的带上 // 需要带cookie的带上
if (restApi.credentials()) { if (restApi.credentials()) {
builder.withCredential(); builder.withCredential();
@ -173,8 +188,6 @@ public class RestProxyInvoker<T> implements InvocationHandler {
* 找到配置固化的基本url * 找到配置固化的基本url
*/ */
private String findBaseUrl() { private String findBaseUrl() {
// 注解的优先级高于全局基本路径
RestService restService = AnnotationUtils.findAnnotation(targetType, RestService.class);
// 当且仅当存在时进入 // 当且仅当存在时进入
if (null != restService) { if (null != restService) {
// 注解的路径解析 // 注解的路径解析

View File

@ -13,7 +13,19 @@ import java.util.Map;
*/ */
public final class DataUtils { public final class DataUtils {
public static final int INDEX_NOT_FOUND = -1; private static final int INDEX_NOT_FOUND = -1;
private static final String EXTENSION_SEPARATOR = ".";
/**
* The Unix separator character.
*/
private static final char UNIX_SEPARATOR = '/';
/**
* The Windows separator character.
*/
private static final char WINDOWS_SEPARATOR = '\\';
/** /**
* 判断字符串是否不为空 * 判断字符串是否不为空
@ -109,4 +121,34 @@ public final class DataUtils {
public static boolean isTrue(Boolean value) { public static boolean isTrue(Boolean value) {
return Boolean.TRUE.equals(value); return Boolean.TRUE.equals(value);
} }
public static String getExtension(final String filename) {
if (filename == null) {
return null;
}
final int index = indexOfExtension(filename);
if (index == INDEX_NOT_FOUND) {
return "";
} else {
return filename.substring(index + 1);
}
}
public static int indexOfExtension(final String filename) {
if (filename == null) {
return INDEX_NOT_FOUND;
}
final int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
final int lastSeparator = indexOfLastSeparator(filename);
return lastSeparator > extensionPos ? INDEX_NOT_FOUND : extensionPos;
}
public static int indexOfLastSeparator(final String filename) {
if (filename == null) {
return INDEX_NOT_FOUND;
}
final int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
final int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
return Math.max(lastUnixPos, lastWindowsPos);
}
} }

View File

@ -1,6 +1,6 @@
package group.flyfish.rest; package group.flyfish.rest;
import group.flyfish.rest.client.RestClient; import group.flyfish.rest.core.client.RestClient;
import group.flyfish.rest.core.builder.MapParamBuilder; import group.flyfish.rest.core.builder.MapParamBuilder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;

View File

@ -52,7 +52,7 @@ public class RestProxyTest {
log.info(items.toString()); log.info(items.toString());
} }
@RestService(baseUrl = "http://60.221.255.208:18092/api/") @RestService(baseUrl = "http://60.221.255.208:18092/api/", timeout = 500)
@AutoMapping(TestRestResultMapping.class) @AutoMapping(TestRestResultMapping.class)
public interface TestRestService { public interface TestRestService {
@ -61,7 +61,7 @@ public class RestProxyTest {
} }
@RestService(baseUrl = "http://220.194.160.4:8083/interface") @RestService(baseUrl = "http://220.194.160.4:8083/interface", timeout = 500)
@AutoMapping(TestRestResultMapping.class) @AutoMapping(TestRestResultMapping.class)
public interface TestPostService { public interface TestPostService {

View File

@ -1,6 +1,6 @@
rest: rest:
client: client:
connection-timeout: 30s connection-timeout: 10s
base-url: http://localhost:8089 base-url: http://localhost:8089
always-trust: true always-trust: true
urls: urls: