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. BZOJ 2653: middle(主席树+二分答案)

    传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...

  2. nginx查看变量值

    nginx查看变量值 location / { echo $host; #域名 echo $remote_addr; echo $remote_user; echo $time_local; echo ...

  3. 微信小程序学习笔记(二)--框架-全局及页面配置

    描述和功能 框架提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑. 响应的数 ...

  4. 软件-平面设计-CorelDRAW:CorelDRAW

    ylbtech-软件-平面设计-CorelDRAW:CorelDRAW CorelDRAW Graphics Suite是加拿大Corel公司的平面设计软件:该软件是Corel公司出品的矢量图形制作工 ...

  5. 27. Unittest单元测试框架的介绍与使用

    unittest单元测试框架 先贴一下unittest官网地址.unittest文档开头介绍了四个重要的概念:test fixture,test case, test suite, test runn ...

  6. Jenkins 搭建篇

    1.Jenkins 介绍 自动化运维工具:saltstack.jenkins.等.因为他们的目标一样,为了我们的软件.构建.测试.发布更加的敏捷.频繁.可靠 如果运维对git不熟,是无法做自动化部署. ...

  7. Java面试宝典(5)算法

    二.算法与编程 1.编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔. 答: pack ...

  8. cordova 配置 高德地图sdk定位

    获取 sha1 打开 cmd 1. cd .android 2. keytool -list -v -keystore debug.keystore 3. 输入密钥: android 4. 复制 sh ...

  9. opensns的URL模式

    URL模式 如果我们直接访问入口文件的话,由于URL中没有模块.控制器和操作,因此系统会访问默认模块(Home)下面的默认控制器(Index)的默认操作(index),因此下面的访问是等效的: htt ...

  10. MySQL练习题--sqlzoo刷题

    首先查看world表的字段: name continent area population gdp capital tld flag SELECT * FROM world: 2.显示人口至少为2亿的 ...