一个好的代码,就是一次开发到处可用,开发者不用关注其细节,专心核心实现。奔着这个目标,有没有什么实现思路?那接下来,我不管你怎么想的,都听我的。
在本场 Chat 中,会讲到如下内容:
涉及技术:接口开发、装饰者模式 、自定义注解、反射、md5 加密、过滤器
接口提供方仅通过配置、写实现具体的签名规则方法和获取 appKey 的方法,即可实现。
接口调用方仅通过注解、使用工具类、写签名规则方法和签名的参数拼接方法,即可实现。
是不是感觉大大简化了接口的开发和接入。不懂可以参考笔者的默认实现,但不建议直接使用。
代码在 github 上,最后会 post 上地址,请大家多多支持和 star。
当产品跟你说要开发接口提供给其他系统使用或者说你要通过接口方式接入某些系统时,肯定先会问需要怎么签名?数据要加密?需要什么方式传输?
一般写个工具类进行签名认证或者解密,验证通过后这些便进行实际的业务逻辑。签名验证等的非业务逻辑的参数看着“碍眼”,因为“用完即走”嘛。那还能怎么办?难道接口开发还能不要验证的接口参数?嗯....下文会填坑。
要对接新接口,如果是开发言语一致还好,就询问对方要接口验证的工具类,然后自己再加工下写个新的工具类实现调用咯。开发言语不一致?嗯...还真没有其他办法,只能按着签名逻辑,自己写工具类。无论如何,接口调用方最麻烦的就是按照接口约定的参数进行拼接签名,不同接口不一样,都要写一遍把需要参数传入。那好像没啥办法。不要担心,还有点办法。
接口提供方的接口方法可能还需要其他地方使用,但是又加上了一些接口验证的参数。老手当然业务代码抽出来作为新的方法同时给接口和其他地方使用。此时一位萌新使用了 ctrl+c 和 ctrl+v,并膜拜了下大神的代码。接口调用方对接同一系统的新接口,又要 get、set 的搬砖模式。
接口的开发流程基本固定,在那些环节可以“用完即走”?
我们先梳理下接口交互的全过程:接口调用>>>接口服务>>>认证通过>>>返回业务数据。
相信有经验的开发者,已经想到前文提到的问题产生的原因是接口认证过程和业务耦合了。要想解耦,我们再把 java-http-json 接口开发的关键技术摆出来:http、json、servlet、签名算法等。其中 servlet 技术还有 listener、filter。停...可以了。就是 filter 过滤器了,它可以承载接口的认证全过程,从过滤器再到实际的业务逻辑,对于开发者来说几乎是无感的,因为签名验证等的非业务逻辑的参数都可以不出现在业务方法中。
接口调用方要摆脱“约定的参数进行拼接签名”的 get、set 的搬砖模式,笔者能想到的是使用自定义注解的技术和解析注解的工具类实现。或许你有更好的办法,不妨联系笔者技术交流。
上述进行了伪代码实现,主要为了更好地理解 sdk 的主要实现。sdk 的 github 地址:[email protected]:smooth-mirror/http-json.git环境要求:JDK1.8+、servlet3.1+使用前记得 clone 到本地然后 install 到本地 maven 仓库。
首先引入 maven 依赖或者引入 jar 包,参考 DefaultApiRequestAuthFilter 继承 BaseApiRequestAuthFilter 自定义 filter 过滤器,接口提供方提供了两种接入方式。
注意这里的 DefaultApiRequestAuthFilter,都应该换掉使用自定义过滤器,这里只是演示用
DefaultApiRequestAuthFilter cn.windflute.http.filter.DefaultApiRequestAuthFilter maxLeadingTimeSecond 30 maxTimeoutSecond 30 DefaultApiRequestAuthFilter URL1 DefaultApiRequestAuthFilter URL2
修改继承 BaseApiRequestAuthFilter 自定义 filter 过滤器,添加注解配置并重写 init 方法,使 springbean 的注解生效。
@WebFilter(urlPatterns = "修改成需要拦截的接口地址", initParams = {//最大超前时间,默认 30 秒 @WebInitParam(name = "maxLeadingTimeSecond", value = "30"),// 最大超时时间,默认 30 秒 @WebInitParam(name = "maxTimeoutSecond", value = "30"),})public class TestFilter extends BaseApiRequestAuthFilter{//添加需要用到的 springbean,这里需要自己写服务,仅供参考 @Autowired IAppKeyService appKeyService; @Override public void init(FilterConfig filterConfig) throws ServletException { super.init(filterConfig); WebApplicationContextUtils .getWebApplicationContext(filterConfig.getServletContext()) .getAutowireCapableBeanFactory().autowireBean(this); }//使用 springbean 获取 AppKey 的方法,仅供参考 @Override public String getAppKey(PostParameterRequestWrapper request, String appId) { return appKeyService.getAppKey(request,appId); }}
接口方法使用@ResponseBody、@PostMapping 等注解,如果方法的参数是对象则需要增加@RequestBody 注解。例如:
@ResponseBody @PostMapping(value = "find.json") public Result find(@RequestBody ApiFindDTO findDTO) { // todo }
笔者开发的 java-http-json 接口 sdk,本意是为了可以非侵入、快速改造历史的 http-json 接口问题以及后续接口的高效开发,因为历史的 http-json 接口存在很多安全问题,欠下的技术债务是要还的。
本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。
阅读全文: http://gitbook.cn/gitchat/activity/5d655a990fe1fb2495bfa504
您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。