获取已命中的URL模板

时间:2019-07-28 13:08:40

标签: java spring-boot

我有一个具有多个API的spring MVC控制器,我想获取从前端访问的API的URI

我有一个扩展了afterPerRequestFilter的过滤器,该过滤器拦截每个api调用,该过滤器具有接受HttpServletRequest,HttpServletResponse和filterChain的方法。 我可以使用request.getRequestURI()获取uri,但是如果uri具有模板路径变量,可以说uri ="q/v1/ruleset/{rulesetId}" 我正在获取最终的uri,例如API rulesetid=23被命中,我从request.getRequestURI()得到的uri是 "q/v1/ruleset/23",但我想要的是uri ="q/v1/ruleset/{rulesetId}", 有什么方法可以得到预期的结果,我知道,我总是可以通过一些操作来获得预期的结果,但是我想使这些事情通用,请帮助

我有包含API的控制器

    @RequestMapping(value = "/ruleset/{rulesetid}", method = 
              RequestMethod.GET)
    public RuleSet getRuleSet(@PathVariable(value = "rulesetid") 
    final Long ruleSetId) {
         return storeMixin.getRuleSet(ruleSetId);
    }

过滤器

    @Component
    @Order(1)
    public class CatalogFilter extends OncePerRequestFilter {


    @Override
    protected void doFilterInternal(HttpServletRequest request, 
    HttpServletResponse response,FilterChain filterChain) throws 
      IOException, ServletException {


         long startTime = System.currentTimeMillis();
         filterChain.doFilter(request, response);
         long elapsed = System.currentTimeMillis() - startTime;
         String name = request.getRequestURI();
         String requestType = request.getMethod();


         Integer httpCode = response.getStatus();

      }

    }

5 个答案:

答案 0 :(得分:0)

我怀疑您可以通过现有的API在过滤器中获取它。但是,您可以预扫描所有@RequestMapping批注,将其保留,然后在过滤器中匹配该模式以获得所需的结果。

答案 1 :(得分:0)

您将无法在过滤器中执行此操作,因为过滤器是在处理程序之前执行的。

您可以实现HandlerInterceptor并获得如下所示的路径映射

public class LogInterceptor implements HandlerInterceptor {

     @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
          String path = (String)request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
          System.out.println("path : " + path);
        return true;
      }
}

答案 2 :(得分:0)

Spring Boot Admin-易于与GUI一起使用

另一种方法是使用 Spring Boot Admin 。为此,我们必须配置客户端服务器。为避免该错误,请确保客户端-服务器依赖性的版本相同。我们可以从下拉列表中添加所需的指标,如图所示。

您可以将uri:/ user / getEmployee / {employeeId}的COUNT,TOTAL_TIME设为3,0.2264027

客户端:

pom.xml

<dependency>
     <groupId>de.codecentric</groupId>
     <artifactId>spring-boot-admin-starter-client</artifactId>
     <version>2.1.4</version>
</dependency>

application.properties

spring.boot.admin.api-path=/instances
spring.boot.admin.client.url=http://localhost:6699
management.endpoints.web.exposure.include=*

服务器端:

application.properties

server.port = 6699
spring.boot.admin.server.url=http://localhost:8889

pom.xml

 <dependency>
         <groupId>de.codecentric</groupId>
         <artifactId>spring-boot-admin-starter-server</artifactId>
         <version>2.1.4</version>
    </dependency>

添加@EnableAdminServer

import de.codecentric.boot.admin.server.config.EnableAdminServer;

@SpringBootApplication
@EnableAdminServer
public class AdminApplication {

    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class, args);
    }

}

GUI http://localhost:6699/#/applications enter image description here


以编程方式进行学习

如果要实现此目标如果要以编程方式实现此目标。在此给您一个提示,您可能会找到 All Details Here

@RequestMapping(path="/admin/count",method=RequestMethod.POST)
public JSONObject count(@RequestParam(name="url") final String url)//@PathVariable(name="url") final String url
{   
    String finalURL = "http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:" + url + "";
    return sendRequestToURL(finalURL);  
}

我们可以使用Spring Boot /actuator/metrics/http.server.requests来获取所有执行的端点,这些端点的计数,异常,结果,状态,总时间等如下。

如果您想查看特定端点的详细信息,则可以通过按以下方式调用请求来实现

localhost:8889/actuator/metrics/http.server.requests?tag=uri:<endPoint>
localhost:8889/actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets
localhost:8889/actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets&tag=status:200
  • 您将获得COUNT等于特定端点的访问次数 叫
  • 您将获得COUNT等于特定端点的访问次数
    特定状态
  • 调用
  • 要获取执行EndPoint的平均时间,您可以执行 TOTAL_TIME/COUNT适用于特定端点以及整个端点 应用

More Detailed Explanation

localhost:8889 / actuator / metrics / http.server.requests

{
    "name": "http.server.requests",
    "description": null,
    "baseUnit": "seconds",
    "measurements": [
        {
            "statistic": "COUNT",
            "value": 3
        },
        {
            "statistic": "TOTAL_TIME",
            "value": 0.21817219999999998
        },
        {
            "statistic": "MAX",
            "value": 0.1379249
        }
    ],
    "availableTags": [
        {
            "tag": "exception",
            "values": [
                "MethodArgumentTypeMismatchException",
                "None"
            ]
        },
        {
            "tag": "method",
            "values": [
                "GET"
            ]
        },
        {
            "tag": "uri",
            "values": [
                "/{id}.*",
                "/user/asset/getAsset/{assetId}",
                "/user/asset/getAllAssets"
            ]
        },
        {
            "tag": "outcome",
            "values": [
                "CLIENT_ERROR",
                "SUCCESS"
            ]
        },
        {
            "tag": "status",
            "values": [
                "400",
                "404",
                "200"
            ]
        }
    ]
}

答案 3 :(得分:0)

这样做

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            filterChain.doFilter(request, response);
        } finally {
            String patternMatch = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        }
    }

在尝试调用request.getAttribute之前,您需要先执行filterChain.doFilter,因为该属性直到请求生命周期中的稍后才会设置。

答案 4 :(得分:0)

您可以尝试以下方法:

String path = (String)request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);