spring项目中获取所有请求URL路径
需求:项目开发中,总是需要在编写的控制添加请求路径,编写完成后,还需要在页面操作,添加权限基本维护,这样操作特别麻烦,为了使用过程中不用维护基础菜单权限,故思考是否有一种可以自动生成控制器方法路径,然后更新数据库中(有则更新,无则插入),这样每次添加新的控制器,只需要执行初始化方法就可以了,不用做基础维护(请求路径: server.servlet.context-path + 控制器路径 + 方法路径)
生成请求路径
由于本项目使用restfull风格,故请求方式有四种,get、post、put、delete四种情况,并且需要获取控制器请求映射,查看spring启动bean注入及方法注入发现 ,RequestMappingHandlerMapping 该类中已经封装启动加载的所有请求路径映射,故只需要根据该类获取请求路径,拼接在一起即可,然后根据数据的请求url比较,有则更新,无则插入即可,下面详细介绍使用过程。
示例如下:
import com.goo.commons.tools.utils.FastJsonUtils;
import com.goo.commons.tools.utils.WsHttpClient;
import io.swagger.annotations.ApiOperation;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.annotation.Annotation;
import java.util.*;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {DaisonBeaconServerApplication.class})
public class RequestMappintTests {
@Autowired
private RestTemplate restTemplate;
//请求映射处理映射器
//spring在启动时候将所有贴有请求映射标签:RequestMapper方法收集起来封装到该对象中
@Autowired
private RequestMappingHandlerMapping rmhm;
//系统根路径
@Value("${server.servlet.context-path}")
private String contextPath;
private String find_url = "http://localhost:8082/sys/resource/find";
private String save_url = "http://localhost:8082/sys/resource/saveOrUpdate";
@Test
public void reload() {
//获取所有控制器请求方法路径
List<Map<String, String>> sourceList = getResources();
//saveOrUpdate方法,从数据库中查询出所有权限表达式,然后对比,如果已经存在,则更新;不存在,则添加
String str = WsHttpClient.send2ws(save_url, sourceList);
System.out.println("保存结果:" + str);
}
/**
* 获取所有控制器请求方法路径
*
* @return
*/
private List<Map<String, String>> getResources() {
List<Map<String, String>> resList = new ArrayList<>();
//1:获取controller中所有带有@RequestMapper标签的方法
Map<RequestMappingInfo, HandlerMethod> handlerMethods = rmhm.getHandlerMethods();
for (RequestMappingInfo requestMappingInfo : handlerMethods.keySet()) {
System.out.println("requestMappingInfo: " + requestMappingInfo);//{[/beaconArea],methods=[PUT]}
//1、获取控制器请求路径
String controllMappingUrl = "";
String methodType = "";
PatternsRequestCondition patternsCondition = requestMappingInfo.getPatternsCondition();
Set<String> patterns = patternsCondition.getPatterns();
if (patterns != null && patterns.size() > 0) {
List<String> urls = new ArrayList<>(patterns);
controllMappingUrl = urls.get(0);
}
Set<RequestMethod> methods = requestMappingInfo.getMethodsCondition().getMethods();
if (methods != null && methods.size() > 0) {
List<RequestMethod> urls = new ArrayList<>(methods);
methodType = urls.get(0).name();
}
//2、获取方法请求路径
HandlerMethod handlerMethod = handlerMethods.get(requestMappingInfo);
System.out.println("handlerMethod: " + handlerMethod);
String methodName = handlerMethod.getMethod().getName();
String methodMappingUrl = "";
String methodDesc = "";
//获取方法所有注解
Annotation[] annotations = handlerMethod.getMethod().getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof GetMapping) {//get请求
String methodUrl = ((GetMapping) annotation).value()[0];
// methodMappingUrl = methodUrl.indexOf("/") != -1 ? methodUrl : "/" + methodUrl;
} else if (annotation instanceof PostMapping) {//post请求
// methodMappingUrl = "/" + methodName;
} else if (annotation instanceof PutMapping) {//put请求
// methodMappingUrl = "/" + methodName;
} else if (annotation instanceof DeleteMapping) {//delete请求
// methodMappingUrl = "/" + methodName;
} else if (annotation instanceof ApiOperation) {//swagger接口标注
methodDesc = ((ApiOperation) annotation).value();
}
}
//3.获取方法注解
String url = contextPath + controllMappingUrl + methodMappingUrl;
System.out.println("完整路径:" + url);
System.out.println("方法描述:" + methodDesc);
System.out.println("请求类型:" + methodType);
//判断数据库已经存在url是否包含该路径即可
Map map = new HashMap();
map.put("resourceUrl", url);
map.put("resourceName", methodDesc);
//请求方式(如:GET、POST、PUT、DELETE)
map.put("resourceMethod", methodType);
//菜单标识 0:非菜单资源 1:菜单资源
map.put("menuFlag", 1);
// 认证等级 0:权限认证 1:登录认证 2:无需认证
map.put("authLevel", 1);
resList.add(map);
}
return resList;
}
}