Python 官方文档:入门教程 => 点击学习
目录SpringBoot 接口版本区分一、新建springboot项目二、实现自定义版本控制的代码三、编写测试的控制器四、测试demospringboot 两个版本的差异一、WEBm
在进行REST接口的开发中,如果项目不断的进行迭代开发,需求不断的变化,会出现不同的版本,一个接口版本1和版本2的业务逻辑可能完全不同,但是又需要兼容之前的版本,我们可能不能在之前的接口进行修改,只能重新另外一个版本的接口,那该如何实现了?
目前有几种方法,常见的有:一种是在url中加入版本号,第二种是在请求头中加入版本号。
下面我给出一个小demo,基于在请求的url中加入版本号,扩展可以根据自己的需要。
新建一个springboot项目,pom.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="Http://Maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jack</groupId>
<artifactId>springboot_version</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot_version</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件如下:
server:
port: 9090
1,自定义版本控制的注解
package com.jack.springboot_version.annotation;
import org.springframework.web.bind.annotation.Mapping;
import java.lang.annotation.*;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface apiVersion {
int value();
}
2,自定义url匹配逻辑
package com.jack.springboot_version.config;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import javax.servlet.http.httpservletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
// 路径中版本的前缀, 这里用 /v[1-9]/的形式
private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+)/");
private int apiVersion;
public ApiVersionCondition(int apiVersion) {
this.apiVersion = apiVersion;
}
@Override
public ApiVersionCondition combine(ApiVersionCondition apiVersionCondition) {
//return null;
// 采用最后定义优先原则,则方法上的定义覆盖类上面的定义
return new ApiVersionCondition(apiVersionCondition.getApiVersion());
}
@Nullable
@Override
public ApiVersionCondition getMatchinGCondition(HttpServletRequest httpServletRequest) {
//return null;
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 0;
// 优先匹配最新的版本号
return apiVersionCondition.getApiVersion() - this.apiVersion;
}
public int getApiVersion() {
return apiVersion;
}
}
3,自定义匹配的处理器
package com.jack.springboot_version.config;
import com.jack.springboot_version.annotation.ApiVersion;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestCondition<ApiVersionCondition> getCustomTypeCondition(Class<?> handlerType) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
return createCondition(apiVersion);
}
@Override
protected RequestCondition<ApiVersionCondition> getCustomMethodCondition(Method method) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
return createCondition(apiVersion);
}
private RequestCondition<ApiVersionCondition> createCondition(ApiVersion apiVersion) {
return apiVersion == null ? null : new ApiVersionCondition(apiVersion.value());
}
}
4,自定义WebMvcConfigurationSupport
核心代码如下:
package com.jack.springboot_version.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@SpringBootConfiguration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
//return super.requestMappingHandlerMapping();
RequestMappingHandlerMapping handlerMapping = new CustomRequestMappingHandlerMapping();
handlerMapping.setOrder(0);
return handlerMapping;
}
}
1,版本1的控制器:
package com.jack.springboot_version.controller.v1;
import com.jack.springboot_version.annotation.ApiVersion;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ApiVersion(1)
@RestController
@RequestMapping("{version}/hello")
public class Hello1Controller {
@RequestMapping("/world")
public String helloWorld(){
System.out.println("版本是1的接口");
return "hello,world .version is 1";
}
}
2,版本2的控制器:
package com.jack.springboot_version.controller.v2;
import com.jack.springboot_version.annotation.ApiVersion;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ApiVersion(2)
@RestController
@RequestMapping("{version}/hello")
public class Hello2Controller {
@RequestMapping("/world")
public String helloWorld(){
System.out.println("版本是2的接口");
return "hello,world .version is 2";
}
}
使用postman进行测试:
1,测试版本1,:
测试url:http://localhost:9090/v1/hello/world
测试结果:
2,测试版本2,:
测试url:http://localhost:9090/v2/hello/world
测试结果:
git:https://GitHub.com/wj903829182/SpringCloud5/tree/master/springboot_version
总结:通过自定义springmvc的url匹配规则,实现接口的版本控制,url增加了版本号,如果不存在高版本的版本接口则匹配代码中版本号最高的处理逻辑。使用版本号对我们项目的接口的迭代开发提供了方便。
背景:前几天被人问到了SpringBoot 使用的是哪个版本的?两个版本的差异?完全Hold不住,今天记起来去稍微了解下。
如今市面上就有SpringBoot2.X.X 和SpringBoot1.X.X 两个新旧大版本。其中,SpringBoot1和SpringBoot2主要区别有如下两个方面(MVC部分):
WebMvcConfigurerAdapter该抽象类在新版的SpringBoot中有改动,部分方法过时。由于SpringBoot的2.0 及其以上版本最低已支持Java1.8,而Java1.8中有个defualt关键字的新特性,于是SpringBoot 2.0.0 对WebMvcConfigurerAdapter该抽象类的上层接口WebMvcConfigurer进行了改造,将WebMvcConfigurer中的方法全部改为使用default关键字修饰;因此,SpringBoot2版本在使用WebMvcConfigurerAdapter抽象类时不需要再使用适配器进行适配。
WebMvcConfigurer部分代码如下:
public interface WebMvcConfigurer {
void configurePathMatch(PathMatchConfigurer configurer);
void configureContentNeGotiation(ContentNegotiationConfigurer configurer);
void configureAsyncSupport(AsyncSupportConfigurer configurer);
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
void addFORMatters(FormatterReGIStry registry);
更直接的说,就是WebMvcConfigurerAdapter 被WebMvcConfigurer 接口替代了,可以直接通过继承WebMvcConfigurer接口,然后实现它的defalut方法来使用WebMvcConfigurerAdapter。
除此之外,WebMvcConfigurerAdapter 还可以用 WebMvcConfigurationSupport 替代,只不过使用WebMvcConfigurationSupport这个类来替换WebMvcConfigurerAdapter时会全面接管对SpringMVC的配置,即SpringBoot对SpringMVC的自动配置全部失效,均使用用户对SpringMVC的配置。
SpringBoot1旧版本中配置的拦截器对静态资源默认是放行不拦截对,而在SpringBoot 2.0.0及其以上版本的拦截器不会对静态资源默认放行,同样也会进行拦截。此时,就需要为使用到的静态资源排除排除其请求路径,这样在使用SpringBoot2新版本时拦截器才不会拦截静态资源。
排除拦截静态资源示例如下:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerIntercepter()).addPathPatterns("/**") .excludePathPatterns("/asserts/**","/webjars/**"); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
--结束END--
本文标题: springboot 接口版本区分方式
本文链接: https://www.lsjlt.com/news/154343.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0