
com.zlyx.easyapi.web.ServiceCallController Maven / Gradle / Ivy
package com.zlyx.easyapi.web;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.zlyx.easyapi.ApiManager;
import com.zlyx.easyapi.config.ApiConfigurer;
import com.zlyx.easyapi.http.HttpMatch;
import com.zlyx.easycore.list.Lists;
import com.zlyx.easycore.map.DataMap;
import com.zlyx.easycore.model.ResultData;
import com.zlyx.easycore.utils.JsonUtils;
import com.zlyx.easycore.utils.MethodUtils;
import com.zlyx.easycore.utils.RequestUtils;
import com.zlyx.easycore.utils.TypeUtils;
import io.swagger.annotations.Api;
import io.swagger.util.Json;
import io.swagger.util.PrimitiveType;
@Api(hidden = true)
@Controller
@RequestMapping("service-api")
public class ServiceCallController {
private static Logger logger = LoggerFactory.getLogger(ServiceCallController.class);
private static final String CLUSTER_RPC = "rpc";
private ApiConfigurer configurer;
@Autowired
public ServiceCallController(ApiConfigurer configurer) {
this.configurer = configurer;
}
@RequestMapping(value = "/{interfaceClass}/{methodName}", produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseEntity invokeDubbo(@PathVariable("interfaceClass") String interfaceClass,
@PathVariable("methodName") String methodName, HttpServletRequest request, HttpServletResponse response)
throws Exception {
return invokeDubbo(interfaceClass, methodName, null, request, response);
}
@RequestMapping(value = "/{interfaceClass}/{methodName}/{operationId}", produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseEntity invokeDubbo(@PathVariable("interfaceClass") String interfaceClass,
@PathVariable("methodName") String methodName, @PathVariable("operationId") String operationId,
HttpServletRequest request, HttpServletResponse response) {
try {
// 判断是否禁用
if (configurer.getApiProperties().isDisable()) {
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
// 判断该接口是否注册
Entry, Object> entry = ApiManager.getRef(interfaceClass);
if (null == entry) {
logger.info("No Ref FOUND.");
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
// 判断调用方法是否存在
Object ref = entry.getValue();
HttpMatch httpMatch = new HttpMatch(entry.getKey(), ref.getClass());
Method[] interfaceMethods = httpMatch.findInterfaceMethods(methodName);
Method method = null;
if (null != interfaceMethods && interfaceMethods.length > 0) {
Method[] refMethods = httpMatch.findRefMethods(interfaceMethods, operationId, request.getMethod());
method = httpMatch.matchRefMethod(refMethods, methodName, request.getParameterMap().keySet());
}
if (null == method) {
logger.info("No Service Method FOUND.");
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
// 判断该实现类是否存在接口
if (ref.getClass().getInterfaces().length > 0
&& CLUSTER_RPC.equals(configurer.getApiProperties().getCluster())) {
method = ref.getClass().getMethod(method.getName(), method.getParameterTypes());
if (null == method) {
logger.info("No Service Method FOUND.");
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
}
logger.debug("Invoke method:{},parameter:{}", method, Json.pretty(request.getParameterMap()));
// 调用spring提供的方法获取参数名称
List parameterNames = Lists.toList(MethodUtils.getParamterMap(method).keySet());
Object result = null;
if (null == parameterNames || parameterNames.size() == 0) {
result = method.invoke(ref);
} else {
Object[] args = new Object[parameterNames.size()];
Type[] parameterTypes = method.getGenericParameterTypes();
Class>[] parameterClazz = method.getParameterTypes();
DataMap dataMap = DataMap.newMap(RequestUtils.getParams(), ":");
for (int i = 0; i < parameterNames.size(); i++) {
if (request.getParameter(parameterNames.get(i)) == null) {
if (TypeUtils.isBaseType(parameterClazz[i].getSimpleName())) {
args[i] = 0;
} else {
args[i] = JsonUtils.parseObject(dataMap.get(parameterNames.get(i)), parameterTypes[i]);
}
} else {
args[i] = suggestPrameterValue(parameterTypes[i], parameterClazz[i],
request.getParameter(parameterNames.get(i)));
}
}
result = method.invoke(ref, args);
}
return ResponseEntity.ok(Json.mapper().writeValueAsString(result));
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.ok(ResultData.err(e).toString());
}
}
private Object suggestPrameterValue(Type type, Class> cls, String parameter)
throws JsonParseException, JsonMappingException, IOException {
PrimitiveType fromType = PrimitiveType.fromType(type);
if (null != fromType) {
DefaultConversionService service = new DefaultConversionService();
boolean actual = service.canConvert(String.class, cls);
if (actual) {
return service.convert(parameter, cls);
}
} else {
if (null == parameter)
return null;
try {
return Json.mapper().readValue(parameter, cls);
} catch (Exception e) {
throw new IllegalArgumentException(
"The parameter value [" + parameter + "] should be json of [" + cls.getName() + "] Type.", e);
}
}
try {
return Class.forName(cls.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy