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

com.ijson.rest.proxy.InvokeParams Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
package com.ijson.rest.proxy;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.ijson.rest.proxy.annotation.*;
import com.ijson.rest.proxy.config.ServiceConfigManager;
import com.ijson.rest.proxy.exception.RestProxyConfigException;
import com.ijson.rest.proxy.exception.RestProxyINFieldException;
import com.ijson.rest.proxy.model.ServiceConfig;
import lombok.Data;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.text.MessageFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by cuiyongxu on 26/12/2016.
 */
@Data
class InvokeParams {
    /**
     * 请求的Url
     */
    private String serviceUrl;
    /**
     * 请求服务器地址
     */
    private String serviceIP;
    /**
     * 方法路径
     */
    private String methodPath;
    /**
     * 服务名称
     */
    private String serviceName;
    /**
     * 服务关键字,与服务地址相关联
     */
    private String serviceKey;
    /**
     * 方法协议类型
     */
    private String methodType;
    private String codec;
    private Map headers = new HashMap<>();
    private Map queryParams = new HashMap<>();
    private Map pathParams = new HashMap<>();
    private Object body;
    private Class resultClazz;

    public static InvokeParams getInstance(String serviceKey, Method method, Object[] args) {
        RestResource restResource = method.getDeclaringClass().getAnnotation(RestResource.class);
        InvokeParams invokeParams = new InvokeParams();
        Object methodType;
        String methodContentType;
        String uri;
        String codec;
        if ((methodType = method.getAnnotation(POST.class)) != null) {
            POST post = (POST) methodType;
            invokeParams.methodType = "POST";
            uri = post.value();
            methodContentType = post.contentType();
            codec = post.codec();
        } else if ((methodType = method.getAnnotation(GET.class)) != null) {
            GET get = (GET) methodType;
            invokeParams.methodType = "GET";
            uri = get.value();
            methodContentType = get.contentType();
            codec = get.codec();
        } else if ((methodType = method.getAnnotation(PUT.class)) != null) {
            PUT put = (PUT) methodType;
            invokeParams.methodType = "PUT";
            uri = put.value();
            methodContentType = put.contentType();
            codec = put.codec();
        } else if ((methodType = method.getAnnotation(DELETE.class)) != null) {
            DELETE delete = (DELETE) methodType;
            invokeParams.methodType = "DELETE";
            uri = delete.value();
            methodContentType = delete.contentType();
            codec = delete.codec();
        } else {
            throw new RestProxyConfigException(method.getName() + " not have method type");
        }
        if (Strings.isNullOrEmpty(codec)) {
            codec = restResource.codec();
        }

        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            Parameter p = parameters[i];
            Annotation[] annotations = p.getAnnotations();
            Annotation annotation;
            if (annotations.length == 0) {
                continue;
            } else {
                annotation = annotations[0];
            }

            if (annotation instanceof Body) {
                invokeParams.body = args[i];
                fieldSettings(invokeParams.body);
            } else if (annotation instanceof PathParams) {
                invokeParams.pathParams = args[i] != null ? (Map) args[i] : null;
            } else if (annotation instanceof QueryParamsMap) {
                invokeParams.queryParams = args[i] != null ? (Map) args[i] : null;
            } else if (annotation instanceof HeaderMap) {
                invokeParams.headers = args[i] != null ? (Map) args[i] : new LinkedHashMap<>();
            }
        }


        ServiceConfig config = ServiceConfigManager.getServiceConfig(serviceKey);
        invokeParams.setServiceName(config.getServiceName());
        String serviceUrl = getResourceAddress(config, uri);
        invokeParams.resultClazz = method.getReturnType();
        invokeParams.setServiceUrl(serviceUrl);
        invokeParams.setMethodPath(uri);
        invokeParams.setServiceIP(config.getAddress());
        invokeParams.setCodec(codec);

        invokeParams.serviceUrl = getServiceURL(serviceUrl, invokeParams.pathParams, invokeParams.queryParams);
        String globContentType = restResource.contentType();
        if (!Strings.isNullOrEmpty(globContentType)) {
            invokeParams.headers.put("Content-Type", globContentType);
        }
        if (!Strings.isNullOrEmpty(methodContentType)) {
            invokeParams.headers.put("Content-Type", methodContentType);
        }
        return invokeParams;
    }

    private static void fieldSettings(Object arg) {
        List fields = getDeclaredField(arg.getClass());
        fields.forEach(field -> {
            field.setAccessible(true);
            INField inField = field.getAnnotation(INField.class);
            if (inField != null) {
                boolean required = inField.required();
                Object value = null;
                try {
                    value = field.get(arg);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (required && value == null) {
                    throw new RestProxyINFieldException(-1, MessageFormat.format(inField.requiredMessage(), field.getName()));
                }
            }
        });
    }


    private static List getDeclaredField(Class clazz) {
        List fieldList = Lists.newArrayList();
        while (clazz != null) {
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass(); //得到父类,然后赋给自己
        }
        return fieldList;
    }

    static Pattern p = Pattern.compile("(\\{[^{}]+\\})+");

    private static String getServiceURL(String url, Map pathParams, Map queryParams) {
        String serviceUrl = url.replaceAll(" ", "");
        if (pathParams != null) {
            Matcher m = p.matcher(url);
            while (m.find()) {
                String pathPlaceHold = m.group();
                String pathPlaceHoldWithOutChar = pathPlaceHold.substring(1, pathPlaceHold.length() - 1);
                String value = pathParams.get(pathPlaceHoldWithOutChar);
                if (Strings.isNullOrEmpty(value)) {
                    throw new RestProxyConfigException(url + "参数" + pathPlaceHoldWithOutChar + "在参数列表中不存在");
                }
                serviceUrl = serviceUrl.replace(pathPlaceHold, value);
            }
        }
        if (queryParams != null) {
            serviceUrl += map2QueryParams(queryParams);
        }
        return serviceUrl;
    }

    private static String map2QueryParams(Map map) {
        StringBuilder sb = new StringBuilder("?");
        map.forEach((k, v) -> {
            sb.append(k).append("=").append(v).append("&");
        });
        if (sb.length() > 1) {
            return sb.toString().substring(0, sb.length() - 1);
        } else {
            return "";
        }
    }

    private static String getResourceAddress(ServiceConfig config, String restUri) {
        String address = config.getAddress();
        if (address == null) {
            address = "";
        }
        String template = "%s";
        if (restUri.startsWith("/")) {
            template += "%s";
        } else {
            template += "/%s";
        }
        return String.format(template, address, restUri);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy