项目需要对api区分内外,所以需要对不同的api拼接不同的前缀
比如对外的接口统一在前面拼接:/external
对内的接口统一拼接:/internal
先定义一个接口PathHandler
/**
* @author zhouqx
* @date 2021/11/3 10:17
*/
public interface PathHandler {
/**
* 需要处理的控制器所处的包名
*/
String getPackagePattern();
/**
* 需要添加的前缀
*/
String getPrefix();
}
根据自己的要求写子类,这里是两个
/**
* 面向内部用户接口前缀处理器
*
* @author zhouqx
* @date 2021/11/3 10:19
*/
@Component
public class ServicePathHandler implements PathHandler{
@Override
public String getPackagePattern() {
return "com.my.*.api.service.*";
}
@Override
public String getPrefix() {
return "/internal";
}
}
/**
* 面向外部用户接口前缀处理器
*
* @author zhouqx
* @date 2021/11/3 10:37
*/
@Component
public class WebPathHandler implements PathHandler {
@Override
public String getPackagePattern() {
return "com.my.*.api.web.*";
}
@Override
public String getPrefix() {
return "/external";
}
}
然后再写一个handler
/**
* 统一前缀追加
* 面向内部:/internal
* 面向外部:/extrnal
*
* @author zhouqx
* @date 2021/11/3 10:21
*/
public class PathControlRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
protected Set<PathHandler> pathHandlers;
protected boolean hasPathHandler = false;
protected AntPathMatcher pathMatcher = new AntPathMatcher();
@Override
public void afterPropertiesSet() {
// 初始化版本控制器类型集合
initVersionHandlers();
super.afterPropertiesSet();
}
@Override
protected void initHandlerMethods() {
super.initHandlerMethods();
}
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo info = super.getMappingForMethod(method, handlerType);
if (info != null) {
final String packageName = handlerType.getPackage().getName();
// 根据包名拼接前缀
for (PathHandler pathHandler : pathHandlers) {
if(pathMatcher.match(pathHandler.getPackagePattern(), packageName)){
RequestMappingInfo pathInfo = buildRequestMappingInfo(pathHandler.getPrefix());
info = pathInfo.combine(info);
return info;
}
}
}
return info;
}
protected void initVersionHandlers() {
pathHandlers = new HashSet<>(obtainApplicationContext().getBeansOfType(PathHandler.class).values());
hasPathHandler = !CollectionUtils.isEmpty(pathHandlers);
}
protected RequestMappingInfo buildRequestMappingInfo(String path) {
return RequestMappingInfo.paths(path).build();
}
}
最后再交由spring管理
/**
* 统一前缀追加
* 面向内部:/internal
* 面向外部:/external
*
* @author zhouqx
* @date 2021/11/3 10:30
*/
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class PathControlWebMvcConfiguration implements WebMvcRegistrations {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new PathControlRequestMappingHandlerMapping();
}
}
大功告成,至此就可以对不同包的api拼接不同的统一前缀