springboot中动态api如何设置
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的逻辑了,喜欢的可以走一下源码完善。在数据可视化这个方面这个用的还是蛮多。