java forwards requests through reflection

     In some scenarios, we need to intercept the service request as early as possible, and then forward it to the corresponding service;

     To achieve such a scenario, we first need to intercept the request of the lower service layer, and then obtain the corresponding request parameters and forward them;

     The following example is to publish the service as a webService through dubbo and then call it;

     Can pass the storm test;

     

     The reference code is as follows:

         1. Simple implementation version, this version only supports basic types

package com.xmm.webserver.service.impl;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xmm.module.utils.SpdEsbQueryParam;
import com.xmm.web.share.interfaces.SpdEsbForwardService;
import com.xmm.webserver.base.GenericService;
import com.xmm.webserver.util.SpringUtil;

@Service("spdEsbForwardService")
public class SpdEsbForwardServiceImpl extends GenericService implements SpdEsbForwardService {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    
    /**
     * Forwarding method
     * @param params encapsulated request data (json format)
     * ************Property description:
     * ************targetName request class full path
     * *************methodName request method
     * *************queryParamsList request parameters
     * *************returnType return type full path
     */
    @SuppressWarnings({ "rawtypes", "unchecked", "unused" })
    public Object spdEsbForward(String params) {
        try {
            Map<String, String> paramMap = JSON.parseObject(params, new TypeReference<Map<String, String>>() {});
            //Get the full path of the calling class
            String targetName = paramMap.get("targetName");
            //Get the calling method name
            String methodName = paramMap.get("methodName");
            //Get the return data type
            String returnType = paramMap.get("returnType");
            //Get query request parameters
            String queryParams = paramMap.get("queryParamsList");   
            //Convert the request type to list
            List<SpdEsbQueryParam> list = JSON.parseObject(queryParams, new TypeReference<List<SpdEsbQueryParam>>() {});
            
            // Collection of requested data types to call the method
            Class classNum[] = new Class[list.size()];
            // Collection of request data values ​​for calling method
            Object objectNum[] = new Object[list.size()];
            int i = 0;
            for (SpdEsbQueryParam spdEsbQueryParam : list) {
                //Get the request data type
                Class paramCalss = Class.forName(spdEsbQueryParam.getPueryParamType());
                //get request data value
                String paramValue=spdEsbQueryParam.getPueryParamValue().toString();
                
                classNum[i] = paramCalss;
                objectNum[i] = JSON.parseObject(paramValue, paramCalss);
                i++;
            }
            
            // instantiate the calling class
            Object obj = SpringUtil.getBean (Class.forName (targetName));
            // load method
            Method method = obj.getClass().getMethod(methodName, classNum);
            // call the method
            Object object =  method.invoke(obj, objectNum);
            return object;
        } catch (Exception e) {
            logger.error("",e);
        }
        return null;
    }
}

 

     Request parameters:

{
    "methodName": "queryRouteInfoList",//Request method
    "targetName": "com.xmm.web.share.interfaces.RouteInfoService",//Request a complete route
    "queryParamsList": [ //Query parameter collection
        {
            "pueryParamValue": { // query parameter value
                "flag": true,
                "pageSize": 20,
                "pageNum": 1,
                "routeName": "Route"
            },
            "pueryParamName": "query", //parameter name
            "pueryParamType": "com.xmm.web.share.query.RouteInfoQuery" //Query parameter type
        }
    ],
    "returnType": "com.xmm.module.commons.SingleResult<RouteInfoDTO>" // return only type
}

 

        2. Complex type, this type supports enumeration, collection, collection in class.....

package com.xmm.webserver.service.impl;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xmm.module.utils.SpdEsbQueryParam;
import com.xmm.web.share.interfaces.SpdEsbForwardService;
import com.xmm.webserver.base.GenericService;
import com.xmm.webserver.util.SpringUtil;

@Service("spdEsbForwardService")
public class SpdEsbForwardServiceImpl extends GenericService implements SpdEsbForwardService {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    
    /**
     * Forwarding method
     * @param params encapsulated request data (json format)
     * ************Property description:
     * ************targetName request class full path
     * *************methodName request method
     * *************queryParamsList request parameters
     * *************returnType return type full path
     */
    @SuppressWarnings({ "rawtypes", "unused", "unchecked" })
    public String spdEsbForward(String params) {
        try {
            Map<String, String> paramMap = JSON.parseObject(params, new TypeReference<Map<String, String>>() {});
            //Get the full path of the calling class
            String targetName = paramMap.get("targetName");
            //Get the calling method name
            String methodName = paramMap.get("methodName");
            //Get the return data type
            String returnType = paramMap.get("returnType");
            //Get query request parameters
            String queryParams = paramMap.get("queryParamsList");   
            //Convert the request type to list
            List<SpdEsbQueryParam> list = JSON.parseObject(queryParams, new TypeReference<List<SpdEsbQueryParam>>() {});
            
            int length = list.size();
            // Collection of requested data types to call the method
            Class classNum[] = new Class[length];
            // request data value for calling method
            String classValue[] = new String[length];
            // Collection of request data values ​​for calling method
            Object objectNum[] = new Object[length];
            
            for (int i=0; i < length; i++) {
                SpdEsbQueryParam spdEsbQueryParam = list.get(i);
                //Get the request data type
                classNum[i] = Class.forName(spdEsbQueryParam.getPueryParamType());
                //get request data value
                classValue[i] = spdEsbQueryParam.getPueryParamValue().toString();
            }
            
            // instantiate the calling class
            Object obj = SpringUtil.getBean (Class.forName (targetName));
            // load method
            Method method = Class.forName(targetName).getMethod(methodName,classNum);
            // Get parameters, there may be multiple, so it is an array
            Type[] types = method.getGenericParameterTypes();   
            for (int i=0; i < length; i++) {
                Type queryType = types[i];
                
                // Determine if this type is an array of Type objects
                if (!(queryType instanceof ParameterizedType)){
                    // get the object
                    Class paramCalss = Class.forName(queryType.getTypeName());
                    // Determine if the object is an enumeration
                    if(paramCalss.isEnum()){
                        objectNum [i] = tresolveEnumValue (classValue [i], paramCalss);
                    }else{
                        objectNum[i] = JSON.parseObject(classValue[i],queryType);
                    }
                } else {
                    objectNum[i] = JSON.parseObject(classValue[i],queryType);
                }
            }
            
            // call the method
            Object object =  method.invoke(obj, objectNum);
            return JSON.toJSONString(object);
        } catch (Exception e) {
            logger.error("",e);
        }
        return null;
    }
    
    private <T> T tresolveEnumValue(String value, Class<T> type) {  
        for (T constant : type.getEnumConstants()){  
            if (constant.toString().equalsIgnoreCase(value)) {  
                return constant;  
            }  
        }     
        return null;  
    }
}

   

    Request parameter 1 - with collection:

{
    "methodName": "enumberOut",
    "targetName": "com.xmm.web.share.interfaces.EnumberService",
    "queryParamsList": [
        {
            "pueryParamValue": {
                "modifyBy": "admin",
                "batchNo": "120598",
                "notOutQuantity": 96,
                "outQuantity": 4
            },
            "pueryParamName": "enumber",
            "pueryParamType": "com.xmm.web.share.dto.EnumberDto"
        },
        {
            "pueryParamValue": [
                {
                    "eCode": "201705160006162"
                },
                {
                    "eCode": "20170000006163"
                },
                {
                    "eCode": "2017000006164"
                },
                {
                    "eCode": "2017516006165"
                }
            ],
            "pueryParamName": "enumberListDetail",
            "pueryParamType": "java.util.List"
        },
        {
            "pueryParamValue": {
                "agent": true,
                "userName": "admin",
                "accountId": "4607"
            },
            "pueryParamName": "user",
            "pueryParamType": "com.xmm.web.share.dto.UserDTO"
        },
        {
            "pueryParamValue": {
                "batchNo": "120598",
                "flag": true,
                "outQuantity": 4,
                "pageSize": 20,
                "remark": "你妹",
                "pageNum": 1
            },
            "pueryParamName": "query",
            "pueryParamType": "com.xmm.web.share.query.EnumberQuery"
        }
    ],
    "returnType": "com.xmm.module.commons.Result"
}

    Request parameter 2 - with enum:

{
    "methodName": "createNewAccount",
    "targetName": "com.xmm.share.interfaces.AccountManagerService",
    "queryParamsList": [
        {
            "pueryParamValue": "11010512",
            "pueryParamName": "agentId",
            "pueryParamType": "java.lang.Integer"
        },
        {
            "pueryParamValue": "AGENT",
            "pueryParamName": "AGENT",
            "pueryParamType": "com.xmm.module.enums.ACCOUNT_TYPE"
        }
    ],
    "returnType": "com.xmm.share.dto.AccountDto"
}

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326357586&siteId=291194637