java 接口版本控制_SpringBoot系统列 5 - 接口版本控制、SpringBoot FreeMarker模板引擎...

接着上篇博客的代码继续写

1.接口版本控制

一个系统上线后会不断迭代更新,需求也会不断变化,有可能接口的参数也会发生变化,如果在原有的参数上直接修改,可能会影响线上系统的正常运行,这时我们就需要设置不同的版本,这样即使参数发生变化,由于老版本没有变化,因此不会影响上线系统的运行。

一般我们可以在地址上带上版本号,也可以在参数上带上版本号,还可以再 header 里带上版本号,这里我们在地址上带上版本号,大致的地址如:http://api.example.com/v1/test,其中,v1 即代表的是版本号。具体做法请看代码:

importorg.springframework.web.bind.annotation.Mapping;import java.lang.annotation.*;/*** 版本控制

*@authorXIHONGLEI

* @date 2018-11-15*/@Target({ElementType.METHOD, ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Mappingpublic @interfaceApiVersion {intvalue();

}

importorg.springframework.web.servlet.mvc.condition.RequestCondition;importjavax.servlet.http.HttpServletRequest;importjava.util.regex.Matcher;importjava.util.regex.Pattern;/***@authorXIHONGLEI

* @date 2018-11-15*/

public class ApiVersionCondition implements RequestCondition{//路径中版本的前缀, 这里用 /v[1-9]/的形式

private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+)/");private intapiVersion;public ApiVersionCondition(intapiVersion) {this.apiVersion =apiVersion;

}

@OverridepublicApiVersionCondition combine(ApiVersionCondition other) {//采用最后定义优先原则,则方法上的定义覆盖类上面的定义

return newApiVersionCondition(other.getApiVersion());

}

@OverridepublicApiVersionCondition getMatchingCondition(HttpServletRequest request) {

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;

}

@Overridepublic intcompareTo(ApiVersionCondition other, HttpServletRequest request) {//优先匹配最新的版本号

return other.getApiVersion() - this.apiVersion;

}public intgetApiVersion() {returnapiVersion;

}

}

importorg.springframework.core.annotation.AnnotationUtils;importorg.springframework.web.servlet.mvc.condition.RequestCondition;importorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;importjava.lang.reflect.Method;/***@authorXIHONGLEI

* @date 2018-11-15*/

public class CustomRequestMappingHandlerMapping extendsRequestMappingHandlerMapping {

@Overrideprotected RequestCondition getCustomTypeCondition(Class>handlerType) {

ApiVersion apiVersion= AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);returncreateCondition(apiVersion);

}

@Overrideprotected RequestConditiongetCustomMethodCondition(Method method) {

ApiVersion apiVersion= AnnotationUtils.findAnnotation(method, ApiVersion.class);returncreateCondition(apiVersion);

}private RequestConditioncreateCondition(ApiVersion apiVersion) {return apiVersion == null ? null : newApiVersionCondition(apiVersion.value());

}

}

#然后在WebConfig配置类中注入Beanimportcom.hello.config.CustomRequestMappingHandlerMapping;importcom.hello.filter.ApiInterceptor;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.SpringBootConfiguration;importorg.springframework.context.annotation.Bean;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;importorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;/*** 配置类

*@authorXIHONGLEI

* @date 2018-10-31*/@SpringBootConfigurationpublic class WebConfig extendsWebMvcConfigurationSupport {

@Overrideprotected voidaddInterceptors(InterceptorRegistry registry) {super.addInterceptors(registry);//将 ApiInterceptor 拦截器类添加进去

registry.addInterceptor(newApiInterceptor());

}

@Override

@BeanpublicRequestMappingHandlerMapping requestMappingHandlerMapping() {

RequestMappingHandlerMapping handlerMapping= newCustomRequestMappingHandlerMapping();

handlerMapping.setOrder(0);

handlerMapping.setInterceptors(getInterceptors());returnhandlerMapping;

}

}

#最后定义一个带版本控制的接口importcom.hello.WebConfig;importcom.hello.config.ApiVersion;importcom.hello.entity.ContractDetailDto;importcom.hello.service.CheckPositionService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.RestController;importjava.util.List;

@RestControllerpublic classHelloController {

@AutowiredprivateWebConfig webConfig;

@ApiVersion(1)

@RequestMapping("{version}/getName")publicString vGetName() {return "Hello World! version 1";

}

@ApiVersion(2)

@RequestMapping("{version}/getName")publicString getName() {return "Hello World! version 2";

}

}

查看效果:

2a0d894b62b7b217ebd84546fedc109e.png

fed4e19c2dcdb92ba2168fb70771b3e5.png

2.模板引擎

在传统的 SpringMVC 架构中,我们一般将 JSP、HTML 页面放到 webapps 目录下面,但是 Spring Boot 没有 webapps,更没有 web.xml,如果我们要写界面的话,该如何做呢?

Spring Boot 官方提供了几种模板引擎:FreeMarker、Velocity、Thymeleaf、Groovy、mustache、JSP。

这里以 FreeMarker 为例讲解 Spring Boot 的使用。

首先引入 FreeMarker 依赖:

org.springframework.boot

spring-boot-starter-freemarker

在 resources 下面建立两个目录:static 和 templates,如图所示:

5b83df744eee4ae94c32dc950c068578.png

其中 static 目录用于存放静态资源,譬如:CSS、JS、HTML 等,templates 目录存放模板引擎文件,我们可以在 templates 下面创建一个文件:index.ftl(freemarker 默认后缀为 .ftl),并添加内容:

Hello ${name}!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值