繁体   English   中英

如何调试 Spring MVC url 映射?

[英]How to debug Spring MVC url mapping?

我正在使用 Spring MVC 3 并且遇到了 URL 映射问题。 我有一个方法

 @Controller
 public class DocumentController {
      @RequestMapping( value="/docs/pupil/classes/{courseCategoryType}", method=RequestMethod.GET )
      public ModelAndView listClassesForPupil( @PathVariable("courseCategoryType") final String courseCategoryType ){
            System.err.print( "\n\n\n\t\t--- XXXXX ---\n\n\n" );
      }
 }

我正在尝试使用Spring URI 模板语法,我知道它正在被映射,因为在控制台中我看到:

 11:22:12,108  INFO DefaultAnnotationHandlerMapping:411 - Mapped URL path [/docs/pupil/classes/{courseCategoryType}] onto handler 'documentController'
 11:22:12,108  INFO DefaultAnnotationHandlerMapping:411 - Mapped URL path [/docs/pupil/classes/{courseCategoryType}.*] onto handler 'documentController'
 11:22:12,108  INFO DefaultAnnotationHandlerMapping:411 - Mapped URL path [/docs/pupil/classes/{courseCategoryType}/] onto handler 'documentController'

但是,当我在浏览器中输入 URL https://localhost/docs/pupil/classes/ACADEMIC ,我收到 404 错误并且在控制台中没有看到任何打印出来的内容。 我替换了只是抛出异常的打印输出代码,它似乎也没有被抛出。 一位同事建议应该有一种方法可以查看 URL 解析是如何完成的,但Google 搜索似乎没有出现任何结果。

关于如何调试这个的任何建议?

对于这样的问题,我觉得开始调试的最佳“入口点”是DispatcherServlet getHandler(HttpServletRequest request)方法。

在这个方法中,如果每个配置的HandlerMapping负责处理你的特定请求,它都会被检查。 如果您的请求做到了这一点,您可以非常确定这是 spring 上下文中的配置问题。

注意RequestMappingHandlerMapping类型的处理程序(或DefaultAnnotationHandlerMapping ,如果您使用的是旧版本的 Spring),这些通常是基于注解的控制器配置使用的HandlerMapping

在另一种情况下,确保DispatcherServlet过滤您的请求的“前面”没有任何东西(就像您的情况一样)

Daniele Torino 的帖子通过除了 DEBUG 之外还提到了 TRACE,让我走上了正确的道路。 除了日志框架之外,我认为您使用的 Spring 版本也很重要。 在我们最近移出的 Spring 3 中,我认为 DEBUG 就足够了。 但是,在 Spring 5 中,并未列出实际的映射。 我记得(在 Spring 3.x 中)我曾经通过设置来查看映射

<logger name="org.springframework.web" level="DEBUG" />

,但现在(在 Spring 5.x 中)只列出了映射的数量。

DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - 14 mappings in 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping'

在 Spring 5 中,直到我添加时才记录实际映射

<logger name="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" level="TRACE" /> 

到 log.properties 文件。 (我建议谨慎使用 TRACE。)有了这个,日志输出包括几行,如:

TRACE o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped 1 handler method(s) for class com.yourcompany.YourClass: {public org.springframework.web.servlet.ModelAndView com.yourcompany.YourClass.someMethod(<your parameters and models here>,javax.servlet.http.HttpServletRequest)={[/your-request-mapping-url],methods=[GET]}}

Spring 4 和 Spring BOOT 中- 在 application.properties 中启用调试日志对我有帮助。 要做到这一点 - 只需添加:

logging.level.org.springframework.web=调试

更新

对于最新 Spring Boot 中的调试模式,添加:

debug=true

进入您的 application.properties 文件

对此的确切答案取决于您使用的日志记录框架。

如果将org.springframework.web的日志级别设置为DEBUGTRACE spring mvc 将记录更详细的信息。

感谢 Bartosz Bilicki Actuator 的提示,这真的很棒。 我将以下配置添加到我的 appplicaton.yml。

management:
  server:
    port: 9001
    address: 127.0.0.1
  endpoints:
    enabled-by-default: true
    web:
      exposure:
        include: '*'

然后我打开http://localhost:9001/actuator/mappings ,就是这样。

如果您将 Spring Boot 与 Actuator 一起使用,mappings 端点将显示所有 @RequestMapping 路径的整理列表。

有关端点的更多详细信息,请参阅http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html

有关如何包含执行器模块的教程,请参阅https://spring.io/guides/gs/actuator-service/ 对于 Gradle,你只需要compile("org.springframework.boot:spring-boot-starter-actuator")

beans端点也很有用。 它将显示所有加载的 bean。 丢失 HTTP 端点的可能原因是没有加载相应的 bean(映射)(因为他不在 componentScan 路径上)。

您可以在日志配置中为CommonsRequestLoggingFilter添加一行(下面的 log4j 示例):

<logger name="org.springframework.web.filter.CommonsRequestLoggingFilter">
    <level value="DEBUG"/>
</logger>

它会在处理前后打印您的 URI,如下所示:

org.springframework.web.filter.CommonsRequestLoggingFilter - Before request [uri=/sendMail/D0000/14/en/?null]
org.springframework.web.filter.CommonsRequestLoggingFilter - After request [uri=/sendMail/D0000/14/en/?null;payload={"to":["somebody@somewhere"],"cc":[],"subject":"Test subject","body":null,"replacement":{"TITLE":"Test email","SERVER_NAME":"Whatever"},"attachments":{},"html":true}]

它真的很有用,虽然它不会显示对不存在资源的请求(比如你得到的 404)。

如果您使用 Spring Boot,获取所有请求的另一个选项是 Tomcat 的access.log 您可以在application.properties启用它,如下所示:

server.tomcat.accesslog.enabled = true

您可以在 Intellij Run 视图中很好地显示 MVC 映射:

智能视图

先决条件

  • 使用 Spring Boot
  • 按照@Bartosz 的描述激活映射执行器:
  1. 包含依赖

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
  2. 特性:

     management.endpoints.enabled-by-default=true management.endpoints.web.exposure.include=mappings

如果您在重定向到后端的 apache 上的 https 站点上托管,则缺少 appContext。 它应该是这样的

https://localhost:8443/ /docs/pupil/classes/ACADEMIC

我认为您可以从 Chrom 控制台/网络面板观看此内容,与您配置的网址进行比较

您的 URL(https://localhost/docs/pupil/classes/ACADEMIC) 缺少 appName 它应该是 URL(https://localhost/appName/docs/pupil/classes/ACADEMIC)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM