- 开发项目过程中有个需求是业务Controller的@RequestMapping上都有"/api/v1"这种共有的Path,以后也有可能变成"/api/v2"、"/api/vn"等。所以想写个BaseController,在BaseController上标注"/api/v1",业务Controller继承BaseController,项目启动时自动把BaseController上的Path追加到业务Controller的Path前面。
- 实现过程,重写RequestMappingHandlerMapping的getMappingForMethod方法,将BaseController上的Path追加上去。实现WebMvcRegistrations接口将自己的RequestMappingHandlerMapping注册。直接上代码
-
import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.lang.Nullable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; /** * @Descp RequestMappingHandlerMapping 包装类,实现controller继承拼接父类上的path * @Author shiqiang * @Date 2022/5/16 16:18 * @Version 0.1 **/ public class RequestMappingHandlerMappingWrapping extends RequestMappingHandlerMapping { @Override protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo mappingInfo = super.getMappingForMethod(method, handlerType); Class<?> superClass = handlerType.getSuperclass(); mappingInfo = appendSuperRequestMapping(superClass,mappingInfo); return mappingInfo; } /** * 添加父类的mapping * @param handlerType * @param mappingInfo * @return */ protected RequestMappingInfo appendSuperRequestMapping(Class<?> handlerType,RequestMappingInfo mappingInfo) { if(handlerType == null || mappingInfo == null) { return mappingInfo; } RequestMapping superRequestMapping = handlerType.getAnnotation(RequestMapping.class); if(superRequestMapping != null && superRequestMapping.value().length > 0) { RequestMappingInfo typeInfo = this.createRequestMappingInfo(handlerType); if (typeInfo != null) { mappingInfo = typeInfo.combine(mappingInfo); } } return appendSuperRequestMapping(handlerType.getSuperclass(),mappingInfo); } @Nullable private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) { RequestMapping requestMapping = (RequestMapping) AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class); RequestCondition<?> condition = element instanceof Class ? this.getCustomTypeCondition((Class)element) : this.getCustomMethodCondition((Method)element); return requestMapping != null ? this.createRequestMappingInfo(requestMapping, condition) : null; } }
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; /** * @Descp 注册包装后的RequestMappingHandlerMapping * @Author shiqiang * @Date 2022/5/16 16:25 * @Version 0.1 **/ @Configuration @Order(Ordered.HIGHEST_PRECEDENCE) public class WebMvcConfiguration implements WebMvcRegistrations { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new RequestMappingHandlerMappingWrapping(); } }
Controller的@RequestMapping拼接父类Controller@RequestMapping的Path
于 2022-05-17 11:48:49 首次发布