All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.nezha.httpfetch.HttpApiService Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
package com.github.nezha.httpfetch;

import com.github.nezha.httpfetch.chains.HttpApiChain;
import com.github.nezha.httpfetch.convertor.ResponseGeneratorConvertor;
import com.github.nezha.httpfetch.resolver.FormParam;
import com.github.nezha.httpfetch.resolver.PostParam;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by daiqiang on 16/12/6.
 */
public class HttpApiService {

    private final static Logger LOGGER = LoggerFactory.getLogger(HttpApiService.class);

    private HttpApiConfiguration configuration;

    private HttpApiInvoker startInvoker = null;

    private Map, Object> serviceCache = new ConcurrentHashMap<>();

    private Map methodsCache = new HashMap<>();

    public HttpApiService(HttpApiConfiguration configuration){
        this.configuration = configuration;
    }

    public void init(){
        //创建调用链
        configuration.init();
        List chains = configuration.getChains();

        //排序
        Collections.sort(chains, new Comparator() {
            @Override
            public int compare(HttpApiChain o1, HttpApiChain o2) {
                int order1 = o1.getOrder();
                int order2 = o2.getOrder();
                return order2 > order1 ? 1 : -1;
            }
        });

        HttpApiInvoker last = null;
        for(int i= chains.size()-1;i>=0;i--){
            final HttpApiChain chain = chains.get(i);
            final HttpApiInvoker next = last;
            last = new HttpApiInvoker(){
                @Override
                public HttpResult invoke(Invocation invocation) {
                    return chain.doChain(next, invocation);
                }
            };
        }
        startInvoker = last;
    }

    public  T getOrCreateService(Class serviceCls){
        Object service;
        if(!serviceCache.containsKey(serviceCls)){
            try {
                service = createService(serviceCls);
            } catch (Exception e) {
                String msg = String.format("服务创建失败! serviceCls ["+serviceCls+"]");
                LOGGER.error(msg, e);
                throw new RuntimeException(msg);
            }
            serviceCache.put(serviceCls, service);
        }else{
            service = serviceCache.get(serviceCls);
        }
        return (T) service;
    }

    /**
     * 创建代理服务,对代理类和头参数等进行封装
     * @param serviceCls 服务接口类
     * @return
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private Object createService(final Class serviceCls) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        ProxyFactory factory = new ProxyFactory();
        if(serviceCls.isInterface()){
            factory.setInterfaces(new Class[] {serviceCls});
        }else{
            String msg = String.format("类[%s]不是接口!", serviceCls);
            LOGGER.error(msg);
            throw new IllegalArgumentException(msg);
        }
        return factory.create(null, null, new HttpApiMethodHandler(serviceCls));
    }

    class HttpApiMethodHandler implements MethodHandler {

        private Class serviceCls;

        public HttpApiMethodHandler(Class serviceCls) {
            this.serviceCls = serviceCls;
        }

        public Object invoke(Object target, Method method, Method arg2, Object[] args) throws Throwable {

            HttpApi httpApiAnno = method.getAnnotation(HttpApi.class);
            if (httpApiAnno == null) {
                //没有httpApi注解
                throw new RuntimeException("系统异常,httpapi注解不存在!");
            }

            Invocation invocation = new Invocation();
            HttpApiMethodWrapper wrapper = getOrNewWrapper(method, httpApiAnno);
            invocation.setWrapper(wrapper);

            this.wrapRequestParameter(invocation, wrapper, args);

            //设置请求参数
            HttpApiRequestParam requestParam = new HttpApiRequestParam();
            requestParam.setEncoding(wrapper.getEncoding());
            requestParam.addHeaders(wrapper.getHeaders());
            invocation.setRequestParam(requestParam);

            invocation.setMethod(method);
            invocation.setServiceCls(serviceCls);

            HttpResult httpResult = startInvoker.invoke(invocation);
            return httpResult.getData();
        }

        private void wrapRequestParameter(Invocation invocation, HttpApiMethodWrapper wrapper, Object[] args){
            //封装参数
            if(!CommonUtils.isArrayEmpty(wrapper.getParameters())){
                for(int i=0;i headers = getHeaders(httpApiAnno);
                wrapper.setHeaders(headers);

                //查询指定的结果转换类获取结果转换服务类
                ResponseGeneratorConvertor generatorService = null;
                if (!CommonUtils.isStringEmpty(httpApiAnno.generator())) {
                    for (ResponseGeneratorConvertor handler : configuration.getConvertors()) {
                        if (httpApiAnno instanceof ResponseGeneratorConvertor){
                            generatorService = handler;
                            break;
                        }
                    }
                }

                wrapper.setGeneratorService(generatorService);

                //去函数的返回类
                wrapper.setResponseCls(method.getReturnType());

                if (httpApiAnno.timeout() > 0) {
                    wrapper.setTimeout(httpApiAnno.timeout());
                }
                if (httpApiAnno.readTimeout() > 0) {
                    wrapper.setReadTimeout(httpApiAnno.readTimeout());
                }

                methodsCache.put(method, wrapper);
            }
            return wrapper;
        }

        /**
         * 从methods中读取
         * @param method
         * @return
         */
        private ParameterWrapper[] wrapperPameters(Method method){
            Annotation[][] annotationArray = method.getParameterAnnotations();
            if(annotationArray == null || annotationArray.length == 0){
                LOGGER.info("该函数没有参数!method [{}]", method.getName());
                return new ParameterWrapper[]{};
            }
            String[] paramNames = new String[annotationArray.length];
            for(int i=0;i getHeaders(HttpApi anno){
            Map headers = new HashMap<>();
            Header[] headersAnno = anno.headers();
            if(!CommonUtils.isArrayEmpty(headersAnno)){
                for(Header header : headersAnno){
                    if(header != null){
                        headers.put(header.key(), header.value());
                    }
                }
            }
            return headers;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy