实例说明:该实例重写 RequestMappingHandlerMapping 类的部分方法,达到给指定包下的所有控制器(Controller/Handler)设置统一的请求前缀。 这里以在接口前加版本号为例:/uri —>> /v2/uri
自定义前缀控制器处理器
接口,可以实现不同前缀的控制器处理器
/**
* @author zsy
* @Date 2022/7/4 11:52
*/
public interface TypeMappingHandler {
/**
* 处理的控制器所处的包名
*
* @return handler package
*/
String getPackageName();
/**
* 处理的控制器所处的包名数组
*
* @return handler packages
*/
String[] getPackageNames();
/**
* 要添加的前缀
*
* @return prefix
*/
String getPrefix();
/**
* 是否匹配
*
* @param handlerType 控制器类型
* @return 控制器类的包名与要处理的包名是否一致
*/
boolean isPattern(Class<?> handlerType);
/**
* 修改默认 RequestMappingInfo
*
* @param original springmvc构造的RequestMapping信息
* @return 添加完前缀的RequestMappingInfo(如果包名匹配)
*/
RequestMappingInfo combineRequestMappingInfo(RequestMappingInfo original);
}
实现类
@Slf4j
@Component
public class InternalTypeMappingHandler implements TypeMappingHandler {
@Override
public String getPackageName() {
return "com.tyros.v2.controller";
}
@Override
public String[] getPackageNames() {
// 支持多包名
return new String[0];
}
@Override
public String getPrefix() {
return "v2";
}
@Override
public boolean isPattern(Class<?> handlerType) {
boolean flag = false;
if (ArrayUtil.isNotEmpty(getPackageNames()) && Objects.nonNull(handlerType)) {
for (String packageName : getPackageNames()) {
flag = handlerType.getPackage().getName().startsWith(packageName);
if (flag) {
break;
}
}
} else if (Objects.nonNull(handlerType)) {
flag = handlerType.getPackage().getName().startsWith(getPackageName());
}
return flag;
}
@Override
public RequestMappingInfo combineRequestMappingInfo(RequestMappingInfo original) {
RequestMappingInfo target = RequestMappingInfo.paths(getPrefix()).build().combine(original);
if (log.isInfoEnabled()) {
log.info("Build RequestMapping Success, {} -->> {}", original, target);
}
return target;
}
}
实现 RequestMappingHandlerMapping
public class TypeControlRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
/**
* 类型控制器
*/
protected Set<TypeMappingHandler> typeMappingHandlers;
/**
* 当前是否拥有类型控制器
*/
protected boolean hasTypeHandler = false;
@Override
public void afterPropertiesSet() {
// 初始化类型控制器类型集合
initVersionHandlers();
super.afterPropertiesSet();
}
@Override
@Nullable
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo info = super.getMappingForMethod(method, handlerType);
if (Objects.nonNull(info)) {
for (TypeMappingHandler typeMappingHandler : typeMappingHandlers) {
if (typeMappingHandler.isPattern(handlerType)) {
return typeMappingHandler.combineRequestMappingInfo(info);
}
}
}
return info;
}
/**
* 初始化版本控制器集合
*/
protected void initVersionHandlers() {
typeMappingHandlers = new HashSet<>(obtainApplicationContext().getBeansOfType(TypeMappingHandler.class).values());
hasTypeHandler = !CollectionUtils.isEmpty(typeMappingHandlers);
}
}
注册映射处理器
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class TypeControlWebMvcRegistrations implements WebMvcRegistrations {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new TypeControlRequestMappingHandlerMapping();
}
}