Spring Boot API 版本权限控制
来源:互联网 发布:mac 菜单栏 编辑:程序博客网 时间:2024/06/06 07:32
Spring Boot API 版本权限控制
之前有文章讲述在Spring MVC 中扩展 RequestMappingHandlerMapping 实现对版本的控制。
但是在真正使用过程中不是很理想化,因为其需要替换掉WebMvcConfigurationSupport,替换后后,会将其提供的一系列默认组件全部移除。如我们注册拦截器使用的(RequestMappingHandlerAdapter)、全局异常拦截(ExceptionHandlerExceptionResolver)等。
本文以Spring Boot 为例,解决这个问题。
Spring Boot RequestMappingHandlerMapping
自动配置时序图
由上图则可以清晰看到,关键点在于是否存在WebMvcRegistrations。
进入WebMvcRegistrations发现其接口下提供了WebMvcRegistrationsAdapter转换器,可以轻松扩展我们所需的RequestMappingHandlerMapping,实现版本控制。
自动配置RequestMappingHandlerMapping源码分析
判断是否存在WebMvcConfigurationSupport
Spring Boot 首先加载WebMvcAutoConfiguration
上图可以看到使用注解ConditionalOnMissingBean判断是否存在WebMvcConfigurationSupport,如果不存在,则该类不会注入,故如果我们直接继承WebMvcConfigurationSupport,则会导致整个全部配置失效。
* ps: SpringBoot的自动配置原理基本都是基于此类注解。*
引入WebMvc配置
上图可看到通过@Import注解引入了EnableWebMvcConfiguration,点击进入该类可看到存在的构造方法中引入了WebMvcRegistrations。该类为WebMvcAutoConfiguration的内部类
如何注入RequestMappingHandlerMapping
由上图可发现EnableWebMvcConfiguration类中注入了RequestMappingHandlerMapping。其调用父类requestMappingHandlerMapping方法生成RequestMappingHandlerMapping。跟踪父类可发现:
调用方法,创建了RequestMappingHandlerMapping,跟下去:
发现其有子类,点击左侧箭头查看:
发现回到了WebMvcAutoConfiguration中的EnableWebMvcConfiguration类。
其通过判断mvcRegistrations是否存在以及mvcRegistrations是否扩展RequestMappingHandlerMapping 来选择使用默认还是我们自定义的RequestMappingHandlerMapping 。
如何扩展
创建一个类,继承WebMvcRegistrationsAdapter,重写getRequestMappingHandlerMapping,返回自定义RequestMappingHandlerMapping即可。
其类是WebMvcRegistrations方便对外扩展提供的转换器类,可以点进去看一下,默认全部返回null。
附上版本控制全部代码
WebMvcRegistrationsConfig
import com.sample.core.common.config.version.ApiRequestMappingHandlerMapping;import org.springframework.boot.autoconfigure.web.WebMvcRegistrationsAdapter;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;/** * Created by zhangbowen on 2017/7/8. */@Configurationpublic class WebMvcRegistrationsConfig extends WebMvcRegistrationsAdapter { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new ApiRequestMappingHandlerMapping(); }}
ApiRequestMappingHandlerMapping
import org.springframework.core.annotation.AnnotationUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.mvc.condition.RequestCondition;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import java.lang.reflect.Method;/** * Created by zhangbowen on 2017/7/8. */public class ApiRequestMappingHandlerMapping extends RequestMappingHandlerMapping { @Override protected RequestCondition<?> getCustomMethodCondition(Method method) { return createCondition(method.getClass()); } @Override protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) { return createCondition(handlerType); } private static RequestCondition<ApiVersionCondition> createCondition(Class<?> clazz) { RequestMapping classRequestMapping = AnnotationUtils.findAnnotation(clazz, RequestMapping.class); if (classRequestMapping == null) { return null; } StringBuilder mappingUrlBuilder = new StringBuilder(); if (classRequestMapping.value().length > 0) { mappingUrlBuilder.append(classRequestMapping.value()[0]); } String mappingUrl = mappingUrlBuilder.toString(); if (!mappingUrl.contains("${version}")) { return null; } ApiVersion apiVersion = AnnotationUtils.findAnnotation(clazz, ApiVersion.class); return apiVersion == null ? new ApiVersionCondition(1) : new ApiVersionCondition(apiVersion.value()); }}
@ApiVersion
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by zhangbowen on 2017/4/15. */@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface ApiVersion { /** * 版本号 * @return */ int value();}
ApiVersionCondition
import org.springframework.web.servlet.mvc.condition.RequestCondition;import javax.servlet.http.HttpServletRequest;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Created by zhangbowen on 2017/4/15. */public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> { private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("/v(\\d+).*"); private int apiVersion; ApiVersionCondition(int apiVersion) { this.apiVersion = apiVersion; } public int getApiVersion() { return apiVersion; } @Override public ApiVersionCondition combine(ApiVersionCondition apiVersionCondition) { return new ApiVersionCondition(apiVersionCondition.getApiVersion()); } @Override public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) { Matcher m = VERSION_PREFIX_PATTERN.matcher(httpServletRequest.getRequestURI()); if (m.find()) { Integer version = Integer.valueOf(m.group(1)); if (version >= this.apiVersion) { return this; } } return null; } @Override public int compareTo(ApiVersionCondition apiVersionCondition, HttpServletRequest httpServletRequest) { return apiVersionCondition.getApiVersion() - this.apiVersion; }}
使用
VersionV1Controller
@RequestMapping("/${version}/version")@RestControllerpublic class VersionV1Controller { public String test() { return "version1"; }}
VersionV2Controller
@RequestMapping("/${version}/version")@RestController@ApiVersion(2)public class VersionV2Controller { public String test() { return "version2"; }}
会不会有人发现这样的起名在生产环境会很low。。。下面这样会不会合理一些。
但是这样需要修改Spring 默认的名称生成器。。如何修改?。。。一次解决一个问题。。。。
Spring MVC版本控制参考 http://www.cnblogs.com/jcli/p/springmvc_restful_version.html
- Spring Boot API 版本权限控制
- Spring Boot 之 RESRful API 权限控制
- Spring Boot 之 RESRful API 权限控制
- Spring Boot 之 RESRful API 权限控制
- Spring Boot 之 RESRful API 权限控制
- Spring Boot+Spring Security+JWT 实现 RESTful Api 权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- spring boot 集成shiro(用户授权和权限控制)
- 【转】Spring+Spring Security+OAuth2实现REST API权限控制
- Spring+Spring Security+OAuth2实现REST API权限控制
- spring boot(4) 权限
- REST API权限控制
- spring boot API 完整版
- java基础之流程控制
- 模拟用户登陆
- KMP详解
- POJ 1839 Cattle 笔记
- 最终,还是没能成为吹牛逼的资本!(一)
- Spring Boot API 版本权限控制
- 此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态。
- Centos 6.9 Install ajenti
- Java总结一
- SRM560 Div1Medium DrawingPointsDivOne
- spring mvc框架在官网如何下载
- Linux 目录文件处理文件
- 解决找不到环境变量PATH
- UE4笔记---获取屏幕大小、视口的缩放比例及Widget移动