Java网络请求代理API的设计思路
一个具有代理功能的API,用于对远程请求进行包装,从而进行日志记录/数值记录/响应检查/...
https://github.com/kevinten10/vrml/
问题背景
在项目开发中,网络请求部分存在很多问题。
请问自己:
1.调用接口后,如果未引发任何异常,是否将其视为成功? 2.即使没有抛出异常,您是否考虑了返回状态代码为不成功代码的情况? 2.您是否考虑过计算不成功代码的原因和频率?
如果您说“不!”。我认为您需要此API来规范您的行为。这将迫使您首先考虑并提供支持。
解决思路
提供了用于调用远程请求的一系列方法,用于快速方便的对以上问题进行检查。
同时提供一套代理规范API,用于统一的日志记录和错误码的生成。
- 通用日志实现
- 提供方便的检查机制
- 强制性的响应码检查
- 提供失败响应码的record记录
- 提供易用的API
用例演示
RequestAPI
Requests API提供了用于调用远程请求的一系列方法。
// responseResponse response = Requests.of(() -> {// start a remote request processreturn Client.request(requestObj);}).check(response -> {// check response code and othersif (Math.random() > 0.5) {// you can throws exception when check illegalthrow new RuntimeException();}}).record(o -> {// record response to report cachereturn new RequestConfiguration.RequestReportValue// request name.ReportBuilder("default")// request value (you can supply response code).recordValue(o.getClass().getSimpleName())// use remote config (autowired by spring bean).useConfig().build();})// throws when failure / get value when success.get();
Request代理
扩展AbstractRequestProxy以提供请求日志和异常处理。
// 继承AbstractHttpRequestProxy提供通用的Http-Proxy能力
@Component
public class HttpProxy extends AbstractHttpRequestProxy<Request, Response> {// 使用Http服务private static final ServiceClient SERVICE_CLIENT = ServiceClient.getInstance();// 提供日志埋点的前缀名@Overrideprotected String requestName() {return "ServiceClient.getResponse";}// 使用RequestsAPI进行Http操作,基于Requests提供的能力对响应结果进行检查@Overrideprotected Response invokeRequest(Request Request) throws Exception {return Requests.of(() -> SERVICE_CLIENT.getResponse(Request)).check(Response -> {this.assertResponseNotNull(Response);this.assertResponseStatusSuccess(Response);this.assertNotNull(Response.getResult(), "result");this.assertCodeSuccess(Response.getResult().getCode(), ErrorCodes.DEPENDENT_SERVICE_CODE_ERROR);}).get();}// 自定义ErrorCode@Overrideprotected ErrorCodes dependentErrorCode() {return ErrorCodes.QUERY_SERVICE_ERROR;}
}
Request报表
如果打开报告功能,则远程请求的响应值将在缓存中计数。当达到配置的阈值时,将使用自定义警报方法来发送警报通知。
// open record function.record(o -> {// record response to report cachereturn new RequestConfiguration.RequestReportValue// request name as cache key.ReportBuilder("default")// request value (you can supply response code).recordValue(response.code)// use remote config (autowired by spring bean).useConfig().build();})
您可以使用.useConfig()
从您的自定义spring bean中获取缓存配置。例如,您可以使用远程config-center中的配置。
Spring configuration bean
如果要使用请求报告功能。您可以使用.useConfig()
从您的自定义spring bean中获取缓存配置。
/*** Request configuration.* Please provide your custom {@code configuration} through* {@link Configuration} and* {@link org.springframework.context.annotation.Bean}*/@Configurationpublic class YourCustomSpringBean implements RequestConfiguration {}
例如,您可以使用远程config-center中的配置。远程配置中心文件,例如:
[{"requestReportName": "default","openRequestReport": true,"reportTriggerCount": 100,"reportExpiredSeconds": 1000,"reportPoolMaxSize": 1000,"noRecordKeys": ["0"]}
]
Example
这是一个远程请求调用
// init mode -> ignoreRequests.of(() -> {requestType.setMode(FIRST_REQUEST_MODE);return client.invokeRequest(requestType);}).onSuccess(responseType -> {try {Thread.sleep(FIRST_CALL_WAIT_TIME);} catch (InterruptedException e) {throw throwsError(ErrorCodes.SYSTEM_PROCESS_ERROR, e);}}).recover(throwable -> null);// first mode -> normalreturn Requests.of(() -> {requestType.setMode(FORMAL_REQUEST_MODE);return client.invokeRequest(requestType);})// check response status.check(responseType -> {this.assertNotNull(responseType, "response");this.assertNotNull(responseType.getResponseStatus(), "responseStatus");this.assertNotNull(responseType.getResponseHead(), "responseHead");})// record response code.record(responseType -> new RequestConfiguration.RequestReportValue.ReportBuilder(REPORT).recordValue(responseType.getResponseHead().getErrorCode()).useConfig().build())// check response code.check(responseType -> {this.assertCodeSuccess(responseType.getResponseHead().getErrorCode(), ErrorCodes.DEPENDENT_SERVICE_CODE_ERROR);}).get();
Maven
<dependency><groupId>com.kevinten</groupId><artifactId>vrml-request</artifactId><version>1.0.0</version>
</dependency>
Java网络请求代理API的设计思路相关推荐
- Android开发——网络请求(一)网络请求的API、授权和方法
网络请求的API 网络请求的授权 <!--网络权限--><uses-permission android:name="android.permission.INTERNET ...
- 基于jsp(java)网络教学平台系统的设计与实现
欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye2 摘 要 远程教育作为现代教育技术的形式,给教育思想与技术带来了革命性的变革,己经成为现代教育的 ...
- 基于jsp(java)网络教学平台系统的设计和开发(含源文件)
获取项目源文件,联系Q:1225467431,可指导毕设,课设 摘 要 远程教育作为现代教育技术的形式,给教育思想与技术带来了革命性的变革,己经成为现代教育的必然要求.远程教育要得以顺利.高效的实施, ...
- java实现遍历树形菜单方法——设计思路【含源代码】
开发工具:MyEclipse 10 后台框架:Hibernate + Struts2 数据库:Oracle 11g 前台框架:EasyUi 浏览器:谷歌 在开发中我们经常会遇到左边是树形菜单,右边是一 ...
- Java网络请求api
直接上代码: public void httpRequest(String path){try {//创建一个URL对象URL url = new URL(path);//获取URL连接,open方法 ...
- Restful API的设计思路
API的就是程序员的UI,和其他UI一样,你必须仔细考虑它的用户体验! Restful只是web api/Json传输接口通过http调,取到还要自己解.Rpc一般都是配套的,客户端直接像调本地函数一 ...
- HttpProxy网络请求代理
版权声明:本文为延成原创文章,转载请标明出处 //Application可以随意切换网络框架 // HttpProxy.init(VolleyHelper.getInstance(this));Htt ...
- java网络请求失败后,一段时间后重新尝试建立连接
biling 实例的 setConnection() 方法似乎接受一个 Listener 对象作为参数,他有两个回调ok和error,当error的时候需要sleep后再重试.我们可以假设该方法用于建 ...
- java web权限_Javaweb权限管理设计思路
权限管理业务界面如下: 数据库方面需要建立六张表: 用户表:user(用于存放用户的相关属性) id,登录名,用户姓名... 角色表:role(用于存放角色):roleId,roleName 用户-角 ...
最新文章
- 【转】Cvmat与IplImage的相互转换
- STM32程序设计心得以及易错点
- 安全:形式盖过内涵?
- TMS320F28335项目开发记录9_28335之中断系统
- flask + 蓝图 用 sqlalchemy 对 mysql 进行 增删查改 的 demo
- OpenCore 的代码结构
- html字体颜色选择插件,css3改变选择文本背景颜色
- python编程是啥-Python编程
- 汇编语言-学习笔记(一)
- [渝粤教育] 中国地质大学 中外美术史 复习题 (2)
- linux 多线程计算pi,单/多线程计算测试:SuperPI/国际象棋_IntelCPU_CPUCPU评测-中关村在线...
- JSP页面乱码的几种解决方案
- Android学习笔记之MeasureSpec
- ToLua 入门07_GameObject
- 论文笔记:SAIN: Self-Attentive Integration Network for Recommendation(SIGIR 2019)
- 如何查看计算机关机事件,深度技术win7系统如何查看电脑的开关机时间【图文】...
- 一文读懂哈希算法SHA256
- “酒香也怕巷子深” Smartflow-Sharp 工作流
- Python 进程 自定义进程子类 继承
- TB6612FNG与直流电机控制教程
热门文章
- matlab的程序设计实验报告答案,实验二 MATLAB程序设计(含实验报告).doc
- Arduino按键控制MP3模块随机播放音乐(YX5300 MP3音乐模块)
- sipXecs技术交流QQ群
- linux如何修改机器名,简单修改Linux主机名
- ERROR Error when sending message to topic test_topic with key: null, value: 3 bytes……:部署Kafka时遇到两个问题
- 添加常用查询新增方法
- 盐城工学院c语言试卷,听说盐工版的高考题难度系数为A !你能得100分吗?
- C语言旅途之用switch计算本利和
- 时间序列数据集:UCR Time Series Classification Archive【共128个数据集】
- 使用ffmpeg进行视频文件转换成FLV整理