springMVC实现多版本接口
最近的一个需求,在现有的系统上实现同一接口的多版本访问,便于以后的接口升级,客户端不改变请求地址,在参数中传递一个version字段指定访问哪个版本的接口。
在前一篇博文 springMVC修改接口注册映射逻辑 中,用修改springMVC注册和映射接口的逻辑实现了该功能,但缺点也很明显,客户端传入的版本号必须在服务端存在,如传入v2.0,则服务端必须存在v2.0版本的接口,否则会抛出404,无法实现降级调用最新接口或默认接口的功能。
网上有两篇博文 SpringMVC源码解读 - RequestMapping注解实现解读 - RequestCondition体系 和 详解SpringMVC请求的时候是如何找到正确的Controller详细讲解了RequestCondition
,RequestMappingHandlerMapping
真正实现接口匹配的是RequestCondition
。
RequestMappingInfo
类是Spring3.1版本之后引入的。是一个封装了各种请求映射条件并实现了RequestCondition
接口的类。有各种RequestCondition
实现类属性,patternsCondition
,methodsCondition
,paramsCondition
,headersCondition
,consumesCondition
以及producesCondition
,分别代表http请求的路径模式、方法、参数、头部等信息。
在RequestMappingHandlerMapping
的父类RequestMappingHandlerMapping
中有两个方法getCustomTypeCondition
和getCustomMethodCondition
,这两个方法返回一个RequestCondition
实例,默认实现返回null。在springMVC扫描注解创建映射时,获取的RequestCondition
实例保存在RequestMappingInfo
的customConditionHolder
属性中。实现接口版本管理的关键是重写这两个方法,创建一个自定义的RequestCondition
并实现比较。
首先创建一个注解ApiVersion
,给方法标注版本号
创建自定义类ApiVersionCondition
,实现RequestCondition
接口
实现比较简单,重要的是getMatchingCondition
方法,在上面实现中,所有比请求版本号小的接口都是符合条件的,compareTo
方法比对所有符合条件的接口,取最新的接口。
重写getCustomTypeCondition
和getCustomMethodCondition
方法
修改applicationContext-servlet.xml
示例