本文共 3508 字,大约阅读时间需要 11 分钟。
从dubbo转到springcloud,觉得springcloud家族组件很全,但是用起来稍微麻烦,每个api 都要写一个控制器来处理http请求 .
于是对相关代码进行抽象,使用统一控制器方法来处理请求,返回结果.
在定义接口的时候,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);}
这样由统一的控制器拦截处理此请求后就拿到了 类,方法,参数.
首先拿到类名,方法名,然后通过反射拿到方法,解析方法的参数(根据注解来决定从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 名称错误"); } }
全部源码地址:
开源项目地址:
fhs framework qq群:976278956
转载地址:http://bhwni.baihongyu.com/