说明
本文主要讲述spring如何获取项目中所有controller的接口信息。主要是依赖于RequestMappingHandlerMapping类。
可先了解RequestMappingHandlerMapping的属性和内容。
spring执行流程
代码
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.condition.*;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
/**
* 获取项目中的全部接口地址
*/
@Controller
@RequestMapping("/appRest")
public class APIRestService {
@ResponseBody
@RequestMapping("projectApi")
public String index() throws IOException {
WebApplicationContext wac = (WebApplicationContext) ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);
Map<String, HandlerMapping> requestMappings = BeanFactoryUtils.beansOfTypeIncludingAncestors(wac, HandlerMapping.class, true, false);
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
StringBuffer sb = new StringBuffer();
for (HandlerMapping handlerMapping : requestMappings.values()) {
if (handlerMapping instanceof RequestMappingHandlerMapping) {
RequestMappingHandlerMapping rmhm = (RequestMappingHandlerMapping) handlerMapping;
Map<RequestMappingInfo, HandlerMethod> handlerMethods = rmhm.getHandlerMethods();
for (RequestMappingInfo rmi : handlerMethods.keySet()) {
PatternsRequestCondition prc = rmi.getPatternsCondition();
RequestMethodsRequestCondition methodsCondition = rmi.getMethodsCondition();
Set<String> patterns = prc.getPatterns();
List<RequestMethod> methods = methodsCondition.getMethods().stream().toList();
String s = methods.size()>0 ? methods.get(0).toString() : "RequestMapping";
HandlerMethod hm = handlerMethods.get(rmi);
String beanTypeName = hm.getBeanType().getName();
sb.append(beanTypeName).append("\t").append(s).append("\t");
for (String url : patterns) {
if (url.equals("/app/projectApi")) {
continue;
}
Class<?> clazz = hm.getBeanType();
Method method = hm.getMethod();
//获取到该方法的参数们
String[] params = u.getParameterNames(method);
String clazzStr = clazz.getName();
String methodAll = method.toString();
String methodWithParam = methodAll.substring(methodAll.indexOf(clazzStr) + clazzStr.length() + 1);
String methodSimpleName = methodWithParam.substring(0, methodWithParam.indexOf("("));
String methodParamsClazz = methodWithParam.substring(methodWithParam.indexOf("(") + 1, methodWithParam.indexOf(")")).replace(")", "");
// 判断返回数据
boolean isPage = method.getReturnType().equals(String.class) || method.getReturnType().equals(ModelAndView.class);
boolean isJosn = method.isAnnotationPresent(ResponseBody.class);
boolean isController = (!hm.getBeanType().isAnnotationPresent(RestController.class) && hm.getBeanType().isAnnotationPresent(Controller.class));
String line = (isPage && !isJosn && isController ? "页面" : "数据") + "\t" + url + "\t" + clazzStr + "\t" + method.getReturnType().getName() + "\t" + methodSimpleName + "\t";
if (params.length > 0) {
String[] split = methodParamsClazz.split(",");
for (int i = 0; i < params.length; i++) {
line += split[i] + " " + params[i] + ",";
}
line = line.substring(0, line.length() - 1);
}
line += "\r\n";
sb.append(line);
}
}
}
}
FileUtils.writeStringToFile(new File("e:/output/projectdoc"), sb.toString());
return sb.toString();
}
}