本文记录在基于Spring(Boot)框架(使用Java语言)和Grails框架(使用Groovy语言)下,开发Controller接口,对不存在的URL请求,接口返回404 not found,而不是抛出NoHandlerFoundException异常的问题,以及排查过程。

对于Spring (Boot)框架,请参考Spring 。

本文带着对Grails的极大恶意,谨慎下翻。

Grails

对于Grails框架,使用Groovy开发的Controller接口,Postman请求不存在的index1接口,给出如下响应信息:

Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found_#开发语言

切换到Preview:

Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found_mvc_02

经过分析,Postman上看到的preview页面实际上是下图中的notFound.gsp文件:

Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found_spring_03

notFound.gsp文件如下:

<!doctype html>
<html>
	<head>
		<title>Page Not Found</title>
		<meta name="layout" content="main">
		<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
	</head>
	<body>
		<ul class="errors">
			<li>Error: Page Not Found (404)</li>
			<li>Path: ${request.forwardURI}</li>
		</ul>
	</body>
</html>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

gsp文件就是Grails下的JSP页面,实际上是XML文件。

console打印日志:WARN [nio-8895-exec-5] o.s.web.servlet.PageNotFound : No mapping for GET /index1

Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found_#开发语言_04

找不到这个类??

NoHandlerFoundException

添加配置:

spring:
  mvc:
    throw-exception-if-no-handler-found: true
  web: # 必须关闭静态资源的默认处理,否则 /health1 可能被静态资源处理器拦截或跳过
    resources:
      add-mappings: false # 谨慎使用,可能影响静态资源
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

报错:

Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found_#开发语言_05

Postman看到的还是上面的第二个图。

添加配置类:

package com.abcd

@Configuration
@EnableWebMvc
class NoHandlerConfig {
    @Bean
    ServletRegistrationBean<DispatcherServlet> dispatcherServlet() {
        DispatcherServlet dispatcher = new DispatcherServlet()
        dispatcher.setThrowExceptionIfNoHandlerFound(true)  // 关键设置

        ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(dispatcher, "/")
        registration.setName("dispatcherServlet")
        return registration
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

结果应用启动报错: