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的更多相关文章

  1. java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)

    概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...

  2. java轻量级IOC框架Guice

    Google-Guice入门介绍(较为清晰的说明了流程):http://blog.csdn.net/derekjiang/article/details/7231490 使用Guice,需要添加第三方 ...

  3. java轻量级Http Server

    lighttpd 官方主页:www.lighttpd.netLighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全.快速.兼容性好并且灵活的web server环境 ...

  4. java -- 轻量级锁

    在了解轻量级锁之前,首先要知道什么是CAS CAS--Compare And Swap 比较并交换--通过比较传入的旧值和原内存位置中的值比较,来决定是不是要更新数据. CAS的语义是“我认为V的值应 ...

  5. JAVA轻量级文件监控

    原文地址:http://blog.csdn.net/three_man/article/details/31012903?utm_source=tuicool 介绍 本文主要介绍一种轻量级的文件监控方 ...

  6. java轻量级IOC框架Guice(转)

    出处:http://www.cnblogs.com/whitewolf/p/4185908.html Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于 ...

  7. Java轻量级业务层框架Spring两大核心IOC和AOP原理

    IoC(Inversion of Control): IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些 ...

  8. Restlet+Fastjson 高速构建轻量级 Java RESTful Webservice

    自己入门Java时做过一个小型RESTful Web Service的项目,这里总结一下. 服务的数据交换格式主要採用JSON,服务为REST风格.连接採用Http协议,数据库使用MySQL,OR M ...

  9. 🔥支持 Java 19 的轻量级应用开发框架,Solon v1.10.4 发布

    Java 轻量级应用开发框架.可用来快速开发 Java 应用项目,主框架仅 0.1 MB. 相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) ...

随机推荐

  1. ibatis 中的 $和#的区别

    在sql配置中比如in(#rewr#) 与in ($rewr$) 在Ibatis中我们使用SqlMap进行Sql查询时需要引用参数,在参数引用中遇到的符号#和$之间的区分为,#可以进行与编译,进行类型 ...

  2. mysql存储过程、函数、触发器、

    当数据库版本不允许直接使用存储过程.函数的语法时用delimiter // 将结束符改成//用完之后再写delimiter;将结束符改回来即可,调用过程.函数用call+其名字即可返回结果 delim ...

  3. jQuery.Deferred exception: a.indexOf is not a function TypeError: a.indexOf is not a function

    jq版本问题 3.2换成1.9就可以了

  4. 解决oracle v$sqlarea sql不完整

    解决oracle v$sqlarea sql不完整根据SELECT * FROM v$sqlarea中找到hash_value然后执行SELECT * FROM v$sqltext WHERE has ...

  5. 20. Cookie 和 Session

    之前我们在Cookie 和Session是什么?已经说过Cookie 和Session,但是为了保证系列的完整性,我们决定重新说一遍,当然可能会有一些区别,建议先从Cookie 和Session是什么 ...

  6. WinDows应急响应基础

    文件排查 开机启动有无异常文件 msconfig 敏感的文件路径 %WINDIR% %WINDIR%\SYSTEM32\ %TEMP% %LOCALAPPDATA% %APPDATA% 用户目录 新建 ...

  7. java 重新学习 (五)

    Set 集合 一.HashSet按照Hash算法存储集合元素(hashCode方法获取hashCode值,根据hashCode值获取元素位置,通过equals判断对象是否相等并且hashCode值是否 ...

  8. C# winform 文件管理

    1.FolderBrowserDialog 打开文件夹中默认路径下的excl文件 private void button7_Click(object sender, EventArgs e) { Fo ...

  9. NetCore利用CsvHelper解析支付宝对账单

    支付宝账单是zip压缩文件流,里面包含了两个.csv文件. 1.请求支付宝账单下载链接,获取到zip文件流. var httpClient = _clientFactory.CreateClient( ...

  10. 欧拉路径 && 欧拉回路