【问题标题】:Influencing order of RequestMapping processing影响RequestMapping处理的顺序
【发布时间】:2019-12-29 22:42:33
【问题描述】:

简而言之,这就是我要搜索的内容:我想创建一个 RequestMapping 来捕获 所有 URL 除了一个我不想捕获的小列表。 排除的最小值是 /webjars/ 以下的所有内容,我还想排除其他 URL,例如 /actuator/ 甚至更多。

背景信息

我们需要更换具有数以千计不同 URL 的旧 CMS。需要检测所有 URL 并根据数据库进行检查,然后应向用户显示登录页面,然后此登录页面会将用户重定向到新的 CMS 目标 URL。 需要应用的逻辑对于某些 Apache / nginx 魔术来说太复杂了,因此我编写了一个 Spring Boot 应用程序可以完成此操作。

我创建了一个 @RequestMapping(value = "**", method = RequestMethod.GET) 来捕获所有 GET 请求(这些是我想要抓取并做出反应的请求)和一个 @RequestMapping(value = "**") 用于其他 http 动词,例如 POSTDELETE我只是通过发送一个 http 错误状态代码来中止。 这工作正常,(简化的)代码如下所示:

@RequestMapping(value = "**", method = RequestMethod.GET)
public String catchAccepted(HttpServletRequest request, HttpServletResponse httpServletResponse, Model model) {
    model.addAttribute("targetUrl", ua.deriveNewUrl(request));

    return "redirect";
}

@RequestMapping(value = "**")
@ResponseBody
public ResponseEntity<Object> catchDenied(HttpServletRequest request, HttpServletResponse httpServletResponse) {
    return new ResponseEntity<Object>(HttpStatus.I_AM_A_TEAPOT);
}

为所有 GET 请求显示的页面基于 Thymeleaf 模板,该模板使用 Bootstrap 来完成布局工作。 为了包含 Bootstrap,我使用了 webjars-locatororg.webjars.bootstrap,通过在 redirect.html Thymeleaf 模板中指定 &lt;script src="/webjars/bootstrap/js/bootstrap.min.js"&gt;&lt;/script&gt; 来包含资源。

问题

问题是,我在 GET 上的 ** 映射也被应用于 /webjars/... 调用,而不是所需的 js 代码,我得到了我的重定向模板返回的任何内容。 我没有办法告诉 Spring Boot 所需的顺序。

首先我想让 Spring Boot 处理 webjars 映射,然后我的另一个映射。

目前的尝试

我检查了 SO 上的 other 帖子,但它们仅在我可以访问进行映射的源代码时才有效。而且我无权访问 webjars 定位器/认为仅仅为了解决这个问题而更改它没有任何意义。

我还尝试像这样设置“与 webjars 无关的任何内容”映射:

@RequestMapping(value = "^(?!webjars$|actuator$).*", method = RequestMethod.GET)

但这并没有达到预期的效果,因为 RequestMapping 似乎只支持 ant-stlye 路径,它不支持否定,因为 Ant(与 Spring Boot 相比)有一个包含和排除字段:https://ant.apache.org/manual/dirtasks.html

否定映射似乎只适用于参数,而不适用于路径:Change @RequestMapping order

【问题讨论】:

  • 遇到stackoverflow.com/q/1234298/5757893 有什么好运气吗?
  • 您在baeldung.com/spring-requestmapping 中尝试过生产/消费吗?也许您可以只定位 html 源而忽略其他源?
  • @mohkamfer 至于您的第一个建议:我想避免直接“弄乱”Servlet 设置,我想坚持使用新样式声明,而不是诉诸 xml 样式。但如果我找不到其他方法,这可能是最后的选择,谢谢
  • @mohkamfer 关于您的第二个建议:这可能是一种解决方法,但到目前为止,我并不完全确定我需要支持哪些其他 mimetypes。例如,我在 CMS 中看到了 .svg,为了采用您建议的方法,我需要更深入地了解存储在 CMS 中的内容

标签: spring-boot request-mapping


【解决方案1】:

如果其他映射来自我无法包含的代码,我还没有找到影响顺序的方法。

但是我找到了一种配置“捕获所有except of ...”的方法:

@RequestMapping(value = { "", "/", "{url:(?!webjars$|actuator$).*}/**" }, method = RequestMethod.GET)

这配置了三个映射。前两个用于处理对网络服务器根目录的调用。第三个配置了一个路径pariable,我也可以将它放入@PathVariable,但在我的场景中,这个值并不重要。如果你配置一个路径变量,你需要给它一个默认值,因为模式只会根据你的 URL 的值来满足。

正则表达式告诉 Spring Boot 仅在 url 不包含 webjarsactuator 时做出反应。正则表达式本身最好使用 regex101 来解释:

【讨论】:

    猜你喜欢
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多