1.不需要编写controller 等mvc层,通过接口动态生成api。
这个问题,其实很好解决,以前编写接口,是要写controller,需要有
@RestController
@RequestMapping("/test1")
public class xxxController{
@ApiOperation("测试预览")
    @PostMapping("/test2")
    public Object test(String name) throws Exception {
}
}
 
在这个总开关类里面dispacherServlet这个类里面是需要解析的,
 从doDispatch方法开始解析(只贴需要的代码)
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// Determine handler for the current request.
				//1.这个方法就是执行了寻找对应的类实例和方法名
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
				// 找不到会报错,就是常见的404,没有找到xxx/xxx方法映射,
					noHandlerFound(processedRequest, response);
					return;
				}
}
 
然后ctrl点进去
 mappedHandler = getHandler(processedRequest);
 这个方法
 来到:
@Nullable
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
		// 从这里便利找
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}
 
HandlerMapping 它就长这样子
 
 其中绿色的这个就是我们写的什么controller啥的地址啦还有对应得方法,在里面。
2.重点
从上图看 这个红色 就是我们要写的一个了,因为为什么呢,你要动态的,绿色代码里你都没写。是springboot你写了controller代码它自动扫描到的,所以你得自己配一个进去。这样子就能够实现动态解析了。
3.基于以上简单的介绍,那就可以开始了,说白了就是模范写一个进去,让springboot能够识别。他原生自带的不行,咱就给它
RequstMappingHandlerMapping 就是模仿这个类写一个。
先看这个类长啥样:
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
		implements MatchableHandlerMapping, EmbeddedValueResolverAware {
		
}
 
继承还挺多,完了我们也写一个,主要实现这个方法即可lookupHandlerMethod(),这个就是怎么找对应地址和方法的逻辑
@Component
public class CustomHandlerMapping extends RequestMappingInfoHandlerMapping
        implements MatchableHandlerMapping, Ordered {
    @Autowired
    private List<HandlerMethodArgumentResolver> argumentResolvers; // 注入Spring Boot自带的参数解析器
    @Override
    protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
        // 根据请求路径动态返回对应的处理器方法
        if (lookupPath.startsWith("/test")) {
            Object handler = getApplicationContext().getBean(CustomHandler.class);
            return new HandlerMethod(handler, "handleTestRequest", HttpServletRequest.class, HttpServletResponse.class);
        }
        return null;
    }
    @Override
    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
//        System.out.println(super.getAdaptedInterceptors());
//        chain.addInterceptor(new ApiInterceptor()); // 注册自定义拦截器
        List<HandlerInterceptor> interceptors = new ArrayList<>();
        return chain;
    }
    @Override
    protected boolean isHandler(Class<?> beanType) {
        return false;
    }
    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
        return null;
    }
    @Override
    public RequestMatchResult match(HttpServletRequest request, String pattern) {
        System.out.println(request);
        System.out.println(pattern);
        return null;
    }
    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}
 
还有一个具体的业务逻辑
@Component
@Slf4j
public class CustomHandler {
    public void handleTestRequest(HttpServletRequest request, HttpServletResponse response) {
        // 在这里编写处理特定请求的逻辑
        // 例如,可以根据请求参数、请求头等信息进行动态处理
        try {
            log.info("方法:"+request.getMethod());
            log.info("参数:"+request.getParameterMap().values());
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            // 跨域设置
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Headers", "Authorization");//这里很重要,要不然js header不能跨域携带  Authorization属性
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
            response.getWriter().write(JSON.toJSONString(ResultBody.ok().data("你好")));
        } catch (IOException e) {
            // 处理异常
        }
    }
}
 
以上就是一个动态api的逻辑了,喜欢的可以走一下源码完善。在数据可视化这个方面这个用的还是蛮多。




](https://img-blog.csdnimg.cn/img_convert/cfb68c87c97daaecc89dda2a9d3cfcc9.png)









![2023年中国位置服务(LBS)产业链及市场规模分析[图]](https://img-blog.csdnimg.cn/img_convert/1a5278362906cadc20091d18de6bd25b.png)




