rescu 是一个方法式调用的http客户端,使开发者不必关心http通讯的细节,更专注于方法调用和业务开发。
rescu 的底层设计和 springcloud 的 feign 一样,都是基于 java 的 Proxy 代理。
Proxy的原理是 提供一个interface和invocationHandler
由invocationHandler来代理interface的具体实现
rescu使用
按照http接口协议创建一个 interface,其中可以包含url path,content-type,header,query参数或者body参数等。
@Path("/api/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface IUserClient {
@GET
@Path("users/{vip}")
User[] queryUsers(@HeaderParam("app") String appId, @PathParam("vip") Integer vip, @QueryParam("term") String term);
}
使用rescu创建一个该interface的实例。
IUserClient userClient = RestProxyFactory.createProxy(IUserClient.class, this.baseUrl, new ClientConfig());
在调用的地方获取userClient对象,直接调用即可
User[] users = userClient.queryUsers('11', 0, null);
高级
创建实例时:baseUrl为http接口的基础地址,如:https://123.com;clientConfig为客户端配置
clientConfig中可以配置 超时时间,网络代理等
ClientConfig clientConfig = new ClientConfig();
// 127.0.0.1:1080 配置网络代理
if (StringUtils.hasText(proxyHost) && proxyPort != null) {
clientConfig.setProxyHost(proxyHost);
clientConfig.setProxyPort(proxyPort);
}
// 正常情况下 当http响应非200或201时,rescu会抛出异常,并且不再解析响应体,
// 如果服务端返回错误且仍返回响应体,并且客户端需要解析响应体,则需要将此参数改为true
clientConfig.setIgnoreHttpErrorCodes(false);
// 单位ms
clientConfig.setHttpReadTimeout(timeout);
clientConfig.setHttpConnTimeout(timeout);
clientConfig.addDefaultParam(HeaderParam.class, "Authorization", "Bearer 123");
除了可以修改clientconfig客户端配置外,rescu还支持interceptor,可以在创建实例时指定。
IUserClient userClient = RestProxyFactory.createProxy(IUserClient.class, this.baseUrl, clientConfig, interceptor);
interceptor需要实现rescu提供的Interceptor接口,Interceptor提供一个aroundInvoke方法。
例:调用时增加日志处理
public class OperateLogInterceptor implements Interceptor {
private LoggerWriter loggerWriter;
public void setLoggerWriter(LoggerWriter loggerWriter) {
this.loggerWriter = loggerWriter;
}
@Override
public Object aroundInvoke(InvocationHandler invocationHandler, Object o, Method method, Object[] objects) throws Throwable {
if (!method.isAnnotationPresent(NeedLog.class)) {
return invocationHandler.invoke(o, method, objects);
}
String ID = UUID.randomUUID().toString();
loggerWriter.logBefore(ID, method, objects);
try {
Object res = invocationHandler.invoke(o, method, objects);
loggerWriter.logAfter(ID, res, null);
return res;
} catch (Throwable e) {
loggerWriter.logAfter(ID, null, e);
throw e;
}
}
}
参数包括:
invocationHandler: 该方法代理实际的方法调用处理器o: 该方法调用时的实例method: 该方法,即前面定义的接口方法,可获取该方法定义所在类,及所有注解,以及定义的形参等objects: 该方法调用时的实际参数