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" }