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); Functionfunc = 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 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 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 create(Class extends T> restInterface, String baseUrl) { return create(restInterface, baseUrl, null, true); } public static 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); }
posted on 2019-05-18 22:16 RockyLOMO 阅读(...) 评论(...) 编辑 收藏