java 轻量级 RestClient
package org.rx.socks.http; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.commons.lang3.ArrayUtils;
import org.rx.common.Contract;
import org.rx.beans.Tuple; import org.rx.common.App;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PrioritizedParameterNameDiscoverer; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function; import static org.rx.common.Contract.isNull; public class RestClient {
private static class DynamicProxy implements InvocationHandler, MethodInterceptor {
private String baseUrl, proxyHost;
private ParameterNameDiscoverer parameterNameDiscoverer = new PrioritizedParameterNameDiscoverer(); private DynamicProxy(String baseUrl, String proxyHost) {
this.baseUrl = baseUrl;
this.proxyHost = proxyHost;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass().equals(Object.class)) {
return method.invoke(proxy, args);
} String apiPath = method.getName(),
httpMethod = ArrayUtils.isEmpty(args) ? HttpClient.GetMethod : HttpClient.PostMethod;
boolean isFormParam = args != null && args.length > 1;
RestMethod restMethod = method.getDeclaredAnnotation(RestMethod.class);
if (restMethod != null) {
String temp = isNull(restMethod.path(), restMethod.value());
if (!App.isNullOrEmpty(temp)) {
apiPath = temp;
}
if (!App.isNullOrEmpty(restMethod.method())) {
httpMethod = restMethod.method();
}
isFormParam = restMethod.isFormParam();
}
String url = String.format("%s/%s", baseUrl, apiPath);
HttpClient client = new HttpClient();
client.setProxyHost(proxyHost);
if (App.equals(httpMethod, HttpClient.GetMethod, true)) {
return setResult(method, client.httpGet(url));
} Parameter[] parameters = method.getParameters();
String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
Function<Integer, String> func = offset -> !ArrayUtils.isEmpty(parameterNames)
&& parameters.length == parameterNames.length ? parameterNames[offset]
: parameters[offset].getName();
System.out.println(method.getDeclaringClass().getName() + " pNames: " + Arrays.toString(parameterNames));
if (!isFormParam && parameters.length == 1) {
return setResult(method, client.httpPost(url, args[0]));
} if (!isFormParam) {
JSONObject jsonEntity = new JSONObject();
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
RestParam restParam = p.getDeclaredAnnotation(RestParam.class);
jsonEntity.put(restParam != null ? isNull(restParam.name(), restParam.value()) : func.apply(i),
args[i]);
}
return setResult(method, client.httpPost(url, jsonEntity));
} Map<String, String> params = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
RestParam restParam = p.getDeclaredAnnotation(RestParam.class);
params.put(restParam != null ? isNull(restParam.name(), restParam.value()) : func.apply(i),
Contract.toJsonString(args[i]));
}
return setResult(method, client.httpPost(url, params));
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return invoke(o, method, objects);
} private Object setResult(Method method, String resText) {
Class<?> returnType = method.getReturnType();
if (returnType.equals(Void.TYPE)) {
return Void.TYPE;
}
Tuple<Boolean, ?> r = App.tryConvert(resText, returnType);
System.out.println(r.left + "," + r.right + "=>" + resText + "," + returnType);
return r.left ? r.right : JSON.toJavaObject(JSON.parseObject(resText), returnType);
}
} public static <T> T create(Class<? extends T> restInterface, String baseUrl) {
return create(restInterface, baseUrl, null, true);
} public static <T> T create(Class<? extends T> restInterface, String baseUrl, String proxyHost, boolean byCglib) {
DynamicProxy handler = new DynamicProxy(baseUrl, proxyHost);
return (T) (byCglib ? Enhancer.create(restInterface, handler)
: Proxy.newProxyInstance(handler.getClass().getClassLoader(), new Class[]{restInterface}, handler));
}
}
package org.rx.socks.http; import java.lang.annotation.*; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RestMethod {
String value() default ""; String path() default ""; String method() default "POST"; boolean isFormParam() default false;
}
package org.rx.socks.http; import java.lang.annotation.*; @Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RestParam {
String value() default ""; String name() default "";
}
666 网购半价返利 http://f-li.cn
测试
package org.rx.test.bean; import org.rx.socks.http.RestMethod; public interface RestApi {
@RestMethod(method = "GET")
void test(); int add(@org.rx.socks.http.RestParam("a") int a, @org.rx.socks.http.RestParam("b") int b); String login(@org.rx.socks.http.RestParam("userId") String uid, @org.rx.socks.http.RestParam("pwd") String pwd); @RestMethod("/add24")
RestResult add2(RestParam param);
}
@Test
public void testRest() {
String proxy = null;
proxy = "127.0.0.1:8888";
RestApi client = RestClient.create(RestApi.class, "http://localhost:8081", proxy, true);
System.out.println(client.getClass());
client.test();
client.add(1, 1);
client.login("Rocky", "abc123");
RestParam p = new RestParam();
p.setA(12);
p.setB(12);
client.add2(p);
}
java 轻量级 RestClient的更多相关文章
- java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)
概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...
- java轻量级IOC框架Guice
Google-Guice入门介绍(较为清晰的说明了流程):http://blog.csdn.net/derekjiang/article/details/7231490 使用Guice,需要添加第三方 ...
- java轻量级Http Server
lighttpd 官方主页:www.lighttpd.netLighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全.快速.兼容性好并且灵活的web server环境 ...
- java -- 轻量级锁
在了解轻量级锁之前,首先要知道什么是CAS CAS--Compare And Swap 比较并交换--通过比较传入的旧值和原内存位置中的值比较,来决定是不是要更新数据. CAS的语义是“我认为V的值应 ...
- JAVA轻量级文件监控
原文地址:http://blog.csdn.net/three_man/article/details/31012903?utm_source=tuicool 介绍 本文主要介绍一种轻量级的文件监控方 ...
- java轻量级IOC框架Guice(转)
出处:http://www.cnblogs.com/whitewolf/p/4185908.html Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于 ...
- Java轻量级业务层框架Spring两大核心IOC和AOP原理
IoC(Inversion of Control): IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些 ...
- Restlet+Fastjson 高速构建轻量级 Java RESTful Webservice
自己入门Java时做过一个小型RESTful Web Service的项目,这里总结一下. 服务的数据交换格式主要採用JSON,服务为REST风格.连接採用Http协议,数据库使用MySQL,OR M ...
- 🔥支持 Java 19 的轻量级应用开发框架,Solon v1.10.4 发布
Java 轻量级应用开发框架.可用来快速开发 Java 应用项目,主框架仅 0.1 MB. 相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) ...
随机推荐
- python 使用yaml模块
python:yaml模块一.yaml文件介绍YAML是一种简洁的非标记语言.其以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁.1. yaml文件规则基本规则: 大小写敏感 ...
- IOU计算python实现
def compute_iou(rec1, rec2): """ computing IoU :param rec1: (y0, x0, y1, x1), which r ...
- Java DOM解析器 - 查询XML文档
这是需要我们查询的输入XML文件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0"?> ...
- UVA
A network is composed of N computers connected by N - 1 communication links such that any two comput ...
- 100个常用js代码(转载)
作者:小萧ovo链接:https://zhuanlan.zhihu.com/p/23076321来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. JavaScript定点 ...
- leetcode.数组.769最多能完成排序的块-Java
1. 具体题目 数组arr是[0, 1, ..., arr.length - 1]的一种排列,我们将这个数组分割成几个“块”,并将这些块分别进行排序.之后再连接起来,使得连接的结果和按升序排序后的原数 ...
- CF1220F
CF1220F 把整棵树分成1的左边和1的右边两部分 最优情况两边子树深度的差一定可以是一 如果还可以是2,也可以通过把多的那一边的点往另一边移使他变成1 如果往一个端点加点,一定不会使这一边变优,也 ...
- JS综合面试题1
function foo(){ getName = function () { alert(1); }; return this; } Foo.getName = function(){ alert( ...
- PHP操作XML方法之 XML Expat Parser
XML Expat Parser 简介 此PHP扩展实现了使用PHP支持JamesClark编写的expat.此工具包可解析(但不能验证)XML文档.它支持PHP所提供的3种字符编码:US-ASCII ...
- 让所有Excel数据格全部乘 某个数
1 首先设置单元格格式要是数字 2 然后在随便一个单元格写入你要乘的数字 3 粘贴的时候设置选择性粘贴,然后设置乘就OK