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;
    }
}