【问题标题】:How to debug Spring MVC url mapping?如何调试 Spring MVC url 映射?
【发布时间】:2011-03-28 15:39:50
【问题描述】:

我正在使用 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 template syntax,我知道它正在被映射,因为在控制台中我看到:

 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'

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

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

【问题讨论】:

  • 快速检查:其他控制器是否工作?你确定这不是上下文路径、DispatcherServlet 的 url-pattern 等的问题吗?
  • 其他控制器正常工作,我们解决了这个特殊问题(我发现前端控制器有过滤器可以忽略除 *.bf 请求之外的所有请求)但我认为这个问题仍然有用,因为我希望将来能够调试这样的请求问题。

标签: java spring spring-mvc


【解决方案1】:

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

在此方法中,检查每个配置的 HandlerMapping 是否负责处理您的特定请求。如果您的请求到此为止,您可以确定这是 spring 上下文中的配置问题。

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

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

【讨论】:

【解决方案2】:

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

【讨论】:

  • 我没有在我的项目 log.properties 文件中看到,我看到类似的 - log4j2.properties 。而且没有标签,配置是这样写的:appender.console.type = Console。如果我像这样添加它应该工作:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=TRACE?
  • @Darius.V 我上面的例子是一个 logback 记录器。对于 Log4j2,上述内容的等效项将进入 log4j2.xml 文件的 部分。我正在使用文档来编写此内容,因此可能不准确。类似于: 记录器>
【解决方案3】:

Spring 4 和 Spring BOOT - 对我有帮助的是在 application.properties 中启用 DEBUG 日志记录。为此 - 只需添加:

logging.level.org.springframework.web=DEBUG

更新

对于最新 Spring boot 中的 Debug 模式添加:

debug=true

进入您的 application.properties 文件

【讨论】:

  • 嗨@Philip Rego。我更新了最新春靴的答案。
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

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

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

    然后我打开http://localhost:9001/actuator/mappings,仅此而已。

    【讨论】:

    • 在我的设置中,/actuator/mappings 不起作用,但 /mappings 确实很好用。谢谢。
    【解决方案6】:

    如果您将 Spring Boot 与 Actuator 一起使用,则映射端点将显示所有 @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 路径上)。

    【讨论】:

    • 如果你使用Spring Boot Actuator,那就是。许多“入门”依赖项不包含它。
    【解决方案7】:

    您可以在日志配置中为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
    

    【讨论】:

      【解决方案8】:

      您可以在 Intellij 运行视图中很好地显示 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
        

      【讨论】:

        【解决方案9】:

        如果您在 apache 上的 https 站点上托管,该站点正在重定向到后端,则缺少 appContext。它应该类似于

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

        【讨论】:

          【解决方案10】:

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

          【讨论】:

            【解决方案11】:

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

            【讨论】:

              猜你喜欢
              • 2018-09-24
              • 1970-01-01
              • 2019-11-01
              • 2012-09-14
              • 1970-01-01
              • 1970-01-01
              • 2012-08-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多