背景
由于项目的规范需要,需要统一的api接口形式,由于接口可能存在不同的api版本,所以一般是在api接口url上会跟上版本号,例如:
- /api/1.0/user/info
- /api/1.2/user/info
如果针对这种url,不加以规范,可能存在很多问题,比如说api前缀的长度,命名规范等问题。
所以可以针对SpringCloud微服务进行一些url规范。通过结合@RequestMapping 注解,可能新增一个@ApiVersion注解,在映射Url之前,根据规范添加前缀。
直接上代码:
WebMvcConfig:
package com.scio.core.config.web;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return new ApiVersionHandlerMapping();
}
}
ApiVersion:
package com.scio.core.config.web;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiVersion {
String value();
}
ApiVersionHandlerMapping:
package com.scio.core.config.web;
import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ApiVersionHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo requestMapping = super.getMappingForMethod(method, handlerType);
ApiVersion version = AnnotationUtils.findAnnotation(method, ApiVersion.class);
if (version != null) {
PatternsRequestCondition prc = requestMapping.getPatternsCondition();
final String v = version.value();
PatternsRequestCondition prefix = new PatternsRequestCondition(String.format("/api/%s", v));
if (log.isDebugEnabled()) {
log.debug("add api prefix for {}", prc.getPatterns());
}
prefix = prefix.combine(prc);
requestMapping = new RequestMappingInfo(prefix, requestMapping.getMethodsCondition(),
requestMapping.getParamsCondition(), requestMapping.getHeadersCondition(),
requestMapping.getConsumesCondition(), requestMapping.getProducesCondition(),
requestMapping.getCustomCondition());
}
return requestMapping;
}
}
TestController:
package com.scio.core.config.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@RequestMapping("/test")
@ApiVersion("1.0")
public void test() {
System.out.println("test");
}
}
网友评论