本文共 3928 字,大约阅读时间需要 13 分钟。
前言:
为何要继承夫类的@RequestMapping并追加到当前Controller的path前呢?因为我希望有个夫controller的RequestMapping值为/api/v1统一管理api的前缀。
如:夫@RequestMapping("/api/v1"),当前Controller继承夫Controller,并且当前controller为@RequestMapping("/test"),我希望当前controller的path为:/api/v1/test。
本代码允许无限制继承,也就是父类可以有@RequestMapping,父类的父类也可以有,并且都会追加到前面。
完整的类源码,避免有的人(比如我)看片段费劲,复制粘贴也不方便(哈哈)。
如果有其他需求也可以通过本示例来改造完成,因为封装RequestMappingInfo时的方法有Method和类的class,可以自己写一些自己的注解扩展注册mapping的功能。
废话不多说直接上代码:
1:继承RequestMappingHandlerMapping,看注释理解啊,虽然不多但是很明白了。
package org.mountcloud.mvc.common.handler;import java.lang.reflect.Method;import org.mountcloud.cfgver.common.util.LoggerUtil;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.mvc.method.RequestMappingInfo;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;/** * @author zhanghaishan * @version V1.0 * org.mountcloud.mvc.common.handler * TODO: * 2020年1月6日. */public class ControllerApiRequestMappingHandlerMapping extends RequestMappingHandlerMapping { /** * 是否打印mapping */ private boolean logMappingPath = true; public ControllerApiRequestMappingHandlerMapping(boolean logMappingPath) { this.logMappingPath = logMappingPath; } @Override protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { RequestMappingInfo mappingInfo = super.getMappingForMethod(method, handlerType); Class superClass = handlerType.getSuperclass(); mappingInfo = appendParentRequestMapping(superClass,mappingInfo); logMapping(mappingInfo); return mappingInfo; } /** * 添加夫类的mapping * @param handlerType * @param mappingInfo * @return */ protected RequestMappingInfo appendParentRequestMapping(Class handlerType,RequestMappingInfo mappingInfo) { if(handlerType==null) { return mappingInfo; } RequestMapping parentRequestMapping = handlerType.getAnnotation(RequestMapping.class); if(parentRequestMapping!=null&&parentRequestMapping.value().length>0) { //使用path工具向前追加夫类的path mappingInfo = RequestMappingInfo.paths(parentRequestMapping.value()).build().combine(mappingInfo); } return appendParentRequestMapping(handlerType.getSuperclass(),mappingInfo); } /** * 由于spring boot2不打印mapping了,不习惯,就自己打印一下,但是有些系统mapping也不打印,有空再研究怎么打印 * @param info */ private void logMapping(RequestMappingInfo info) { if(!logMappingPath||info==null) { return; } //此处等价Logger.info LoggerUtil.getLogger(ControllerApiRequestMappingHandlerMapping.class).info("mapping path:"+info.toString()); }}
2:实现WebMvcRegistrations,将刚刚重写的RequestMappingHandlerMapping作用到系统
package org.mountcloud.mvc.common.config;import org.mountcloud.mvc.common.handler.ControllerApiRequestMappingHandlerMapping;import org.springframework.beans.factory.annotation.Value;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;/** * @author zhanghaishan * @version V1.0 * org.mountcloud.mvc.common.config * TODO: * 2020年1月6日. */@Configuration//这个注解很重要啊,不写不生效@Order(Ordered.HIGHEST_PRECEDENCE)public class WebMvcConfiguration implements WebMvcRegistrations{ //是否打印mapping?2.0不自己打印了,可以通过mapping.showpath配置控制 @Value("${mapping.showpath:true}") private boolean showMappingPath; @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new ControllerApiRequestMappingHandlerMapping(showMappingPath); }}
到此就完毕了,复制粘贴直接用,除了log工具是我自己图省事封装了一下,等价于Log.info,其他的直接复制就能用同胞们。
为了防止有人不知道父类是咋写昂,我也贴出来我自己的父类Controller。
package org.mountcloud.mvc.common.controller;import org.springframework.web.bind.annotation.RequestMapping;/** * @author zhanghaishan * @version V1.0 * org.mountcloud.mvc.common.controller * TODO: * 2020年1月6日. */@RequestMapping("/api/v1")public class ApiController{}
转载地址:https://blog.csdn.net/zhanghaishan/article/details/103863258 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!