什么是RESTful?
简单说就是一种接口的风格、规范。
详细的介绍请戳下面链接
https://www.runoob.com/w3cnote/restful-architecture.html
为什么要用RESTful?
为了使接口使用起来更方便、实现时代码更简洁
之前做java web接触的form表单提交方式通常只有两种get & post
RESTful就是根据提交方式去进行操作
以前的请求路径
https://localhost:8080/springdemo/getUser
https://localhost:8080/springdemo/deleteUser
使用RESTful后
GET https://localhost:8080/springdemo/user
DELETE https://localhost:8080/springdemo/user
也可以进行版本管理
https://localhost:8080/springdemo/v1/user
https://localhost:8080/springdemo/v2/user
通过自定义注解实现版本管理
1.自定义注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface ApiVersion {
/*
* api version code
*/
int value();
}
2.自定义筛选条件
public class ApiVesrsionCondition implements RequestCondition<ApiVesrsionCondition> {
// 路径中版本的前缀, 这里用 /v[1-9]/的形式
private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+)/");
private int apiVersion;
public ApiVesrsionCondition(int apiVersion){
this.apiVersion = apiVersion;
}
/*
* 将不同的筛选条件合并
*
*/
@Override
public ApiVesrsionCondition combine(ApiVesrsionCondition other) {
return new ApiVesrsionCondition(other.getApiVersion());
}
/*
* 根据request查找匹配到的筛选条件
*
*/
@Override
public ApiVesrsionCondition getMatchingCondition(HttpServletRequest request) {
System.out.println(request.getRequestURI());
Matcher m = VERSION_PREFIX_PATTERN.matcher(request.getRequestURI());
if(m.find()){
Integer version = Integer.valueOf(m.group(1));
if(version >= this.apiVersion) // 如果请求的版本号大于配置版本号, 则返回当前最大版本
return this;
}
return null;
}
/*
* 实现不同条件类的比较,从而实现优先级排序
*
*/
@Override
public int compareTo(ApiVesrsionCondition other, HttpServletRequest request) {
return other.getApiVersion() - this.apiVersion;
}
public int getApiVersion() {
return apiVersion;
}
}
3.重写RequestMappingHandlerMapping 的映射
public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestCondition<ApiVesrsionCondition> getCustomTypeCondition(Class<?> handlerType) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
return createCondition(apiVersion);
}
@Override
protected RequestCondition<ApiVesrsionCondition> getCustomMethodCondition(Method method) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
return createCondition(apiVersion);
}
//实例化RequestCondition
private RequestCondition<ApiVesrsionCondition> createCondition(ApiVersion apiVersion) {
return apiVersion == null ? null : new ApiVesrsionCondition(apiVersion.value());
}
}
这样做是为了在@RequestMapping注解中的整体url可以找到我们自定义的注解
4.使我们自定义的拦截器生效
@Configuration
public class WebConfig extends WebMvcConfigurationSupport{
@Override
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping handlerMapping = new CustomRequestMappingHandlerMapping();
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors());
return handlerMapping;
}
}
5.测试controller
RESTfulTest结果为
v1.png 2.png 3.png
仔细看图3 请求版本为v5,返回为v2 select test
做了高版本匹配为当前存在的最高版本,是第2步筛选条件那里做的处理。
至此结束。
参考文章:
https://www.jianshu.com/p/5b820f393c62
http://www.cnblogs.com/jcli/p/springmvc_restful_version.html
感谢两位大佬的技术分享。
网友评论