@RequestMapping() 將controller注冊到容器中時需要加入路由地址,如果項目層數較深,地址會非常的長,並且有很多一樣的路由前綴,每寫一個controller都要重復一遍非常的麻煩,既然Spring這么強大,有沒有什么機制可以自動生成路由前綴?
思路:如何可以在@RequestMapping中不加URL前綴------>我們可以讓配置類自動加入前綴
既然用@RequestMapping()可以注冊路由,那肯定有一個對應的配置類可以修改路由地址。
RequestMappingHandlerMapping應運而生。我們需要寫一個配置類繼承RequestMappingHandlerMapping並重寫其中的getMappingForMethod方法。
public class AutoPrefixUrlMapping extends RequestMappingHandlerMapping {
//missyou.api-package = com.chauncy.missyou.api 寫在application.properties中
@Value("${missyou.api-package}")
private String apiPackagePath;
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
//我們所需的路由信息在handlerType中
RequestMappingInfo mappingForMethod = super.getMappingForMethod(method, handlerType);
if (mappingForMethod != null) {
String prefix = this.getPrefix(handlerType);
//這里prefix = "/v1"但遠遠不夠還要加上路由的自己設的地址
return RequestMappingInfo.paths(prefix).build().combine(mappingForMethod);
}
return null;
}
private String getPrefix(Class<?> handlerType) {
String packName = handlerType.getPackage().getName();
//為什么這么處理?因為我們只需要和入口文件同級的包名,packName為該路由的完整包名
//packname = com.chauncy.missyou.api.v1 而我們只需要v1這個前綴,
String newPackName = packName.replaceAll(this.apiPackagePath, "");
return newPackName.replace(".", "/");
}
}
注意事項:不能簡單的把這個配置類直接用Component注解加載到容器中
需要使用接口形式加載到容器中
@Component
public class AutoPrefixUrlMappingConfiguration implements WebMvcRegistrations {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new AutoPrefixUrlMapping();
}
}
為什么?因為是這個類設計的時候規定的
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return this.webFluxRegistrations != null && this.webFluxRegistrations.getRequestMappingHandlerMapping() != null ? this.webFluxRegistrations.getRequestMappingHandlerMapping() : super.createRequestMappingHandlerMapping();
}
如果getRequestMappingHandlerMapping()返回值為空,就新建一個不做后續處理。