fhs_framework springcloud使用统一的控制器来接收rpc调用请求教程,无需每个rpc接口都写控制器

从dubbo转到springcloud,觉得springcloud家族组件很全,但是用起来稍微麻烦,每个api 都要写一个控制器来处理http请求 .

于是对相关代码进行抽象,使用统一控制器方法来处理请求,返回结果.

 

1   RPC接口定义

        在定义接口的时候,url使用统一的开头  /api/*,将需要调用的类和方法标记到url中.比如

@RequestLine("GET /api/com.fhs.basics.api.rpc.FeignWordBookApiService/getWordBookListByWordBookGroupCode?wordBookGroupCode={wordBookGroupCode}")

    然后定义好参数的处理方式,如果是表单参数使用@Param注解标记,如果是@RequestBody 使用 @RequestBody标记.

   

/**
 * 字典公共服务
 */
@FeignClient(value = "basics", configuration = FeignConfiguration.class,primary = false)
public interface FeignWordBookApiService {

    /**
     * 根据字典编码获取字典信息
     * @param wordBookGroupCode 字典编码
     * @return HttpResult 角色数据权限
     */
    @RequestLine("GET /api/com.fhs.basics.api.rpc.FeignWordBookApiService/getWordBookListByWordBookGroupCode?wordBookGroupCode={wordBookGroupCode}")
    HttpResult> getWordBookListByWordBookGroupCode(@Param("wordBookGroupCode") String wordBookGroupCode);
}

     这样由统一的控制器拦截处理此请求后就拿到了 类,方法,参数.

            

2  统一处理控制器

       首先拿到类名,方法名,然后通过反射拿到方法,解析方法的参数(根据注解来决定从body读取还是通过request.getParameter获取),拿到参数后,调用方法返回返回值.

  

/**
     * 执行RPC方法
     *
     * @param serviceClass 方法类
     * @param methodName   方法名
     * @param request      req
     * @param response     res
     */
    @RequestMapping("/api/{serviceClass}/{methodName}")
    public void doExec(@PathVariable() String serviceClass,@PathVariable() String methodName, HttpServletRequest request, HttpServletResponse response) {
        ParamChecker.isNotNullOrEmpty(serviceClass, "serviceClass 不可为空");
        ParamChecker.isNotNullOrEmpty(methodName, "methodName 不可为空");
        if(!this.apiToken.equals(request.getHeader("apiToken"))){
            throw new ParamException("token不正确,非法调用");
        }
        try {
            Class clazz = Class.forName(serviceClass);
            if (!clazz.isAnnotationPresent(FeignClient.class)) {
                throw new ParamException("调用方法非Feign接口");
            }
            Method method = ReflectUtils.getMethodd(clazz, methodName);
            if (method == null) {
                throw new ParamException("方法不存在");
            }

            Object[] params = new Object[method.getParameterTypes().length];
            Annotation[][] annotations = method.getParameterAnnotations();
            int index = 0;
            outside:
            for (Annotation[] oneParamAnnotations : annotations) {
                for (Annotation annotation : oneParamAnnotations) {
                    if (annotation instanceof RequestBody) {
                        String jsonString = readAsChars(request);
                        params = new Object[]{JSONObject.parseObject(jsonString, method.getParameters()[0].getType())};
                        break outside;
                    } else if (annotation instanceof RequestParam) {
                        RequestParam tempParam = (RequestParam)annotation;
                        params[index] = request.getParameter(tempParam.defaultValue());
                    }
                }
                index++;
            }
            Object service = SpringContextUtil.getBeanByClassForApi(clazz);
            try {
                Object result = method.invoke(service, params);
                JsonUtils.outJson(response, JsonUtils.bean2json(result));
            } catch (IllegalAccessException e) {
                log.error("", e);
            } catch (InvocationTargetException e) {
                log.error("", e);
            }
        } catch (ClassNotFoundException e) {
            throw new ParamException("serviceClass 名称错误");
        }
    }

 

全部源码地址:https://gitee.com/fhs-opensource/fhs-framework/blob/v2.x/fhs_extends/fhs_base/fhs_base_other/src/main/java/com/fhs/core/base/controller/ApiController.java

开源项目地址:https://gitee.com/fhs-opensource/fhs-framework

fhs framework qq群:976278956

 

你可能感兴趣的:(fhs_framework)