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);
    }

猜你喜欢

转载自www.cnblogs.com/Googler/p/10887380.html