package com.product.module.data.utli; import com.product.core.exception.BaseException; import com.product.module.data.config.CmnCode; import com.product.module.sys.version.ApiVersion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * cheng */ @Component public class SystemApiToMethods { @Autowired ConfigurableApplicationContext applicationContext; /** * 只读map */ Map beans; public Boolean getBeanIsExist(String api) { Bean bean = this.beans.get(api); return bean != null; } /** * 通过api调用Controller层入口 * * @param api * @return * @throws BaseException */ public Object run(String api, Integer verion) throws BaseException { if (api == null) { return null; } if (api.indexOf("/") != 0) { api = "/" + api; } //通过上下文获取 request response HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); return run(request, response, api, verion); } public boolean isVersion(String api) { String str = api; String pattern = ".*/v[0-9]*\\d$"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(str); return m.matches(); } public static void main(String args[]) { } /** * 通过api调用Controller层入口 * * @param request * @param response * @param api * @return * @throws BaseException */ public Object run(HttpServletRequest request, HttpServletResponse response, String api, Integer version) throws BaseException { if (beans == null || api == null) return null; try { if (api.indexOf("/") != 0) { api = "/" + api; } api += version == null ? "" : !isVersion(api) ? "/v" + version : ""; if (!getBeanIsExist(api)) { throw new BaseException(CmnCode.EXPORT_GET_API_METHOD_FILA.getValue(), CmnCode.EXPORT_GET_API_METHOD_FILA.getText() + api); } Bean bean = this.beans.get(api); if (bean != null) { Class[] parameterType = bean.getParameterType(); if (parameterType != null) { Object[] params = new Object[parameterType.length]; for (int i = 0; i < parameterType.length; i++) { Class aClass = parameterType[i]; Class httpServletRequestClass = HttpServletRequest.class; Class HttpServletResponseClass = HttpServletResponse.class; if (aClass == httpServletRequestClass) { params[i] = request; continue; } if (aClass == HttpServletResponseClass) { params[i] = response; continue; } params[i] = null; } return bean.method.invoke(bean.bean, params); } return bean.method.invoke(bean.bean); } return null; } catch (Exception e) { e.printStackTrace(); throw new BaseException(e); } } /** * 启动时初始化拿到所有的请求地址 */ @PostConstruct private void getAll() { //获取restcontroller注解的类名 String[] beanNamesForAnnotation = applicationContext.getBeanNamesForAnnotation(RestController.class); Map beanMap = new HashMap<>(); //获取类对象 for (String str : beanNamesForAnnotation) { Object bean = applicationContext.getBean(str); Class forName = bean.getClass(); //获取requestmapping注解的类 RequestMapping declaredAnnotation = forName.getAnnotation(RequestMapping.class); if (declaredAnnotation != null) { String[] value = (declaredAnnotation.value()); for (Method method : forName.getDeclaredMethods()) { ApiVersion version = method.getAnnotation(ApiVersion.class); RequestMapping api_value = method.getAnnotation(RequestMapping.class); PostMapping annotation = method.getAnnotation(PostMapping.class); if (api_value != null) { Bean bean1 = new Bean(); String class_url = value[0] + api_value.value()[0].replace("{version}", "v" + (version == null ? "1" : String.valueOf(version.value()))); bean1.apiUrl = class_url; bean1.version = version == null ? 1 : version.value(); bean1.bean = bean; bean1.method = method; beanMap.put(class_url, bean1); } else if (annotation != null) { Bean bean1 = new Bean(); String class_url = value[0] + annotation.value()[0].replace("{version}", "v" + (version == null ? "1" : "" + version.value())); bean1.apiUrl = class_url; bean1.version = version == null ? 1 : version.value(); bean1.bean = bean; bean1.method = method; beanMap.put(class_url, bean1); } } } PostMapping annotation = forName.getAnnotation(PostMapping.class); if (annotation != null) { String[] value = annotation.value(); for (Method method : forName.getDeclaredMethods()) { ApiVersion version = method.getAnnotation(ApiVersion.class); PostMapping api_value = method.getAnnotation(PostMapping.class); if (api_value != null) { Bean bean1 = new Bean(); String class_url = value[0] + api_value.value()[0].replace("{version}", "v" + (version == null ? "1" : "" + version.value())); bean1.apiUrl = class_url; bean1.version = version == null ? 1 : version.value(); bean1.bean = bean; bean1.method = method; beanMap.put(class_url, bean1); } } } } this.beans = Collections.unmodifiableMap(beanMap); } private class Bean implements Serializable { private String apiUrl; private int version; private Object bean; private Method method; private ParameterizedType parameterizedType; public Method getMethod() { return method; } public void setMethod(Method method) { this.method = method; } public String getApiUrl() { return apiUrl; } public void setApiUrl(String apiUrl) { this.apiUrl = apiUrl; } public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } public Object getBean() { return bean; } public void setBean(Object bean) { this.bean = bean; } private Class[] getParameterType() { if (this.bean != null && this.method != null) { return this.method.getParameterTypes(); } return null; } } }