美文网首页
Spring Cloud ApiController

Spring Cloud ApiController

作者: 赵哥窟 | 来源:发表于2022-08-09 14:08 被阅读0次

    在Spring Cloud项目开发中,一般的目录结构


    截屏2022-08-09 13.50.44.png

    各个模块是做什么的就不用多说了,主要是web模块,比如我们实现一个登陆功能,首先要在Web模块下面新建一个LoginController,然后再后写接口层和实现层,然后我们需要查询用户又要新建一个UserController,新增加一个功能就要新建一个Controller,那么我不想建这么多的Controller,我想用一个Controller来统一调用接口可不可以,答案是可以。这就是我们接下来要讲的ApiController

    ApiController

    作用,不用每个功能都写一个Controller,只要写在一个公共的模块里面,其他模块引入就可以了

    优点:因为是统一的Controller入口,所以可以做一些拦截,鉴权操作

    下面只提供一些核心代码和思路供大家参考

    @RestController
    @RequestMapping({"/api"})
    public class ApiController implements ApplicationContextAware {
        private static final Logger log = LoggerFactory.getLogger(ApiController.class);
        private ApplicationContext applicationContext;
        private static Map<String, Object> serviceCache = new HashMap();
    
        public ApiController() {
        }
    
        @CrossOrigin
        @RequestMapping(
                value = {"/{serviceName}/{method}"},
                method = {RequestMethod.POST}
        )
    
        /**
         * Api入口
         */
        public Object post(@PathVariable("serviceName") String serviceName, @PathVariable("method") String method, @RequestBody String params, HttpServletRequest request, HttpServletResponse response) {
            long startTime = System.currentTimeMillis();
            ServletThreadLocal.put(request, response);
            Object object = this.doService(serviceName, method, params);
            long executeTime = System.currentTimeMillis() - startTime;
            log.info("调用服务[{}.{}]执行时间:{}ms", new Object[]{serviceName, method, executeTime});
            return object;
        }
    
        /**
         * doService
         *
         * @param serviceName
         * @param method
         * @param params
         * @return
         */
        private Object doService(String serviceName, String method, String params) {
            Object serviceBean = this.getServiceBean(serviceName);
            Result commonResult = null;
            if (serviceBean == null) {
                commonResult = Result.fail(ResultCodeEnum.SERVICE_NOT_FOUND.getDesc());
                log.info("调用服务[{}.{}]响应结果:{}", new Object[]{serviceName, method, JSONObject.toJSONString(commonResult.toString())});
                return commonResult;
            } else {
                Method currentMethod = this.getInvokeMethod(serviceBean, method);
                //方法不存在
                if (currentMethod == null) {
                    commonResult = Result.fail(ResultCodeEnum.METHOD_NOT_FOUND.getDesc());
                    log.info("调用服务[{}.{}]响应结果:{}", new Object[]{serviceName, method, JSONObject.toJSONString(commonResult.toString())});
                    return commonResult;
                } else {
                    Type[] paramTypes = currentMethod.getGenericParameterTypes();
                    if (paramTypes.length != 0 && paramTypes.length <= 1) {
                        CallTypeEnum callType = CallTypeEnum.REAL;
                        BaseParam baseParam = null;
    
                        try {
                            //获取入参
                            Object inputParam = JSONObject.parseObject(params, paramTypes[0]);
                            baseParam = (BaseParam) inputParam;
                            log.info("调用服务[{}.{}]请求参数:{}", new Object[]{serviceName, method, JSONObject.toJSONString(inputParam)});
    
                            callType = baseParam.getCallType();
                            //判断是真实调用还是mock调用,mock调用自己实现
                            if (callType == CallTypeEnum.REAL) {
                                //获取返回结果
                                Object callResult = currentMethod.invoke(serviceBean, inputParam);
                                //判断返回结果类型
                                if (!(callResult instanceof Result)) {
                                    throw new RuntimeException("接口返回类型必须为[com.xxx.base.bean.Result]类型");
                                }
                                commonResult = (Result) callResult;
                                log.info("调用服务[{}.{}]响应结果:{}", new Object[]{serviceName, method, JSONObject.toJSONString(commonResult)});
                                return commonResult;
                            }
                        } catch (Exception var17) {
                            commonResult = Result.buildFail(ResultCodeEnum.FAIL.getDesc());
                            log.error("服务[{}.{}]处理失败", new Object[]{serviceName, method, var17});
                        }
                    } else {
                        log.info("调用服务[{}.{}]响应结果:{}", new Object[]{serviceName, method, "服务定义形参个数只能为一个"});
                        return Result.buildFail("服务定义形参个数只能为一个");
                    }
                }
            }
            return commonResult;
        }
    
        /**
         * 获取ServiceBean
         *
         * @param serviceName
         * @return
         */
        private Object getServiceBean(String serviceName) {
            Object serviceBean = serviceCache.get(serviceName);
            try {
                if (serviceBean == null) {
                    if (serviceName.contains(".")) {
                        Class apiClass = null;
    
                        try {
                            apiClass = Class.forName(serviceName);
                            serviceBean = this.applicationContext.getBean(apiClass);
                        } catch (ClassNotFoundException var5) {
                            log.error("获取服务[" + serviceName + "]出错", var5);
                        } catch (Exception var6) {
                            log.error("获取服务[" + serviceName + "]出错", var6);
                        }
                    } else {
                        serviceBean = this.applicationContext.getBean(serviceName);
                    }
                }
            } catch (Exception var7) {
                log.error("获取服务[" + serviceName + "]出错", var7);
            }
    
            if (serviceBean != null) {
                serviceCache.put(serviceName, serviceBean);
            }
            return serviceBean;
        }
    
        /**
         * 获取方法
         *
         * @param serviceBean
         * @param method
         * @return
         */
        private Method getInvokeMethod(Object serviceBean, String method) {
            Method currentMethod = null;
            Method[] methods = serviceBean.getClass().getDeclaredMethods();
            Method[] var5 = methods;
            int var6 = methods.length;
    
            for (int var7 = 0; var7 < var6; ++var7) {
                Method method1 = var5[var7];
                if (method1.getName().equals(method)) {
                    currentMethod = method1;
                }
            }
    
            return currentMethod;
        }
    
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
    
    public class ServletThreadLocal {
        private static ThreadLocal<HttpServletRequest> requestThreadLocal = new ThreadLocal();
        private static ThreadLocal<HttpServletResponse> responseThreadLocal = new ThreadLocal();
    
        public ServletThreadLocal() {
        }
    
        public static HttpServletRequest getRequest() {
            return (HttpServletRequest)requestThreadLocal.get();
        }
    
        public static HttpServletResponse getResponse() {
            return (HttpServletResponse)responseThreadLocal.get();
        }
    
        public static void putRequest(HttpServletRequest request) {
            requestThreadLocal.set(request);
        }
    
        public static void putResponse(HttpServletResponse response) {
            responseThreadLocal.set(response);
        }
    
        public static void put(HttpServletRequest request, HttpServletResponse response) {
            putRequest(request);
            putResponse(response);
        }
    }
    
    

    Api模块

    public interface OrderServiceFacade {
        Result<OrderResult> getOrderById(OrderParam param);
    }
    

    Service模块

    @Service("orderServiceFacade")
    public class OrderServiceFacadeImpl implements OrderServiceFacade {
    
       @Resource
       OrderMainMapper orderMainMapper;
    
       @Override
       public Result<OrderResult> getOrderById(OrderParam param){
    }
    

    这样就不需要我们在写Controller了

    接口调用

    http://localhost:9091/api/orderServiceFacade/getOrderById
    

    相关文章

      网友评论

          本文标题:Spring Cloud ApiController

          本文链接:https://www.haomeiwen.com/subject/rldnwrtx.html