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 倍. (更快) ...
随机推荐
- [CSP-S模拟测试62]题解
A.Graph 因为点可以随便走,所以对于每个联通块,答案为边数/2向下取整. 用类似Tarjan的方式,对于每个联通块建立一棵搜索树,尽量让每一个节点的儿子两两配对,如果做不到就用上头顶的天线. # ...
- JavaScript实现注册时检查邮箱,名称,密码等是否符合规则
大概实现了,用户名是否存在,邮箱是否已注册,密码是否符合复杂度. //对用户名校验是否存在function checkname(){ //alert("checkname"); v ...
- CentOS 安装MySQL rpm方式安装
MySQL源码方式安装:https://www.cnblogs.com/deverz/p/10997723.html 从最新版本的linux系统开始,默认的是 Mariadb而不是mysql!这里依旧 ...
- php 字符串 定界符 json_last_error()
字符串的3种赋值 1:单引号 $str = '111111111111 '; 2:双引号 $str =" 11111111111 "; 3:定界符 $str = <<& ...
- (2)C++基本类型
一.整形 short .int. long. long long sizeof查看类型所占的字节数 cout << sizeof(short)<<endl;//2 字节 cou ...
- Java学习之Static
Static(静态)是一种修饰符,用于修饰成员(成员变量.成员函数) 1.静态方法只能访问静态成员. 2.静态随着类的加载而加载 通过代码分析: class PersonDemo { public s ...
- Find a Way (双bfs)
Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year ...
- mybatis之增删改
前面三小节内容主要是针对查询操作进行讲解,现在对mybatis增删改进行演示. 由于每次建立工程比较复杂,可以参考第一节:mybatis入门来搭建一个简单的工程,然后来测试本节内容. 1.增 1.新增 ...
- Python面试题之这两个参数是什么意思:*args,**kwargs?我们为什么要使用它们?
如果我们不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用*args: 如果我们不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使 ...
- 37-python基础-python3-字典的常用方法-keys()-values()-items()
有 3 个字典方法,它们将返回类似列表的值,分别对应于字典的键.值和键-值对:keys().values()和 items(). 这些方法返回的值不是真正的列表,它们不能被修改,没有append()方 ...