项目需要对api区分内外,所以需要对不同的api拼接不同的前缀
比如对外的接口统一在前面拼接:/external
对内的接口统一拼接:/internal
先定义一个接口PathHandler
public interface PathHandler {
String getPackagePattern();
String getPrefix();
}
根据自己的要求写子类,这里是两个
@Component
public class ServicePathHandler implements PathHandler{
@Override
public String getPackagePattern() {
return "com.my.*.api.service.*";
}
@Override
public String getPrefix() {
return "/internal";
}
}
@Component
public class WebPathHandler implements PathHandler {
@Override
public String getPackagePattern() {
return "com.my.*.api.web.*";
}
@Override
public String getPrefix() {
return "/external";
}
}
然后再写一个handler
public class PathControlRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
protected Set 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管理
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class PathControlWebMvcConfiguration implements WebMvcRegistrations {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new PathControlRequestMappingHandlerMapping();
}
}
大功告成,至此就可以对不同包的api拼接不同的统一前缀



