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

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