Java

新手解决Whitelabel Error Page NoResourceFoundException: No static resource for request ‘/’报错的一则案例

一 报错重现和故障说明

在我自己动手实践「Spring in Action sixth edition」的第2个章节的过程中,编写了一个简单的Controller,然后用IDEA启动了Spring工程之后,浏览器访问 :http://localhost:8080/

遇到下述错误:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Jul 21 08:37:48 CST 2026
There was an unexpected error (type=Not Found, status=404).
No static resource .
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource  for request '/'.
	at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:527)
	at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:50)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:866)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1000)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:892)
	...

 

我的Controller代码如下:

package com.knockatdatabase.tacocloud;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(method = RequestMethod.GET,value = "/")
public class HomeController {

    public String home() {
        return "home";
    }
}

 

但是,当我把代码改写为:

//写法2
package com.knockatdatabase.tacocloud;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(method = RequestMethod.GET,value = "/")
public class HomeController {

    @GetMapping(value = "/")
    public String home() {
        return "home";
    }
}

 

或者

 

//写法3
package com.knockatdatabase.tacocloud;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping(value = "/")
    public String home() {
        return "home";
    }
}

 

 

 

程序都可以运行正常,不报错。

二 错误分析

对于新手而言,这可能需要花费一些时间。于是,把问题交给了Gemini,给出了一针见血的解释和说明:

造成问题的根源,是SpringMVC的注解解析机制,尤其是既有类级别「class-level」又有方法级别「method-level」混合使用作路由映射的场景时,容易出现一些和我们预期不一致的报错。

如果只把路由写在类上,方法上不写路由时,Spring是不会把这个方法识别为Web请求处理器的。就如同第一种写法。

1 第一种写法:只在类上写注解为啥会报错

SpringMVC的RequestMappingHandlerMapping在注册路由时,会先扫描带有@Controller的类,然后到该类中去找那些带有@RequestMapping或者@GetMapping的方法。此时,HomeController类上虽然有@Controller注解,但是该类中没有任何满足条件的方法,于是SpringMVC认为这是1个普普通通的方法,压根儿不会把它当做Web请求的接口。最终,请求的根路径/这个URL,没有绑定到任何控制器方法上。Spring认为这不是一个动态请求,而是查找一个静态资源,于是会到项目的静态路径static下去查找名为index.html或者是名为/的静态资源,结果呢,没有找到该资源,最终抛出了:

ue Jul 21 08:37:48 CST 2026
There was an unexpected error (type=Not Found, status=404).
No static resource .
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource  for request '/'.

 

再进一步,当我创建对应的文件 src/main/resources/static/index.html 时,程序则可以继续运行:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
我的路径在
<h1>欢迎来到 Taco Cloud!</h1>

<div style="background-color: #f0f0f0; padding: 15px; border-radius: 5px;">
  <p><strong>当前完整的 URL:</strong> <span id="full-url"></span></p>
  <p><strong>当前访问的相对路径:</strong> <span id="path-name"></span></p>
</div>

<script>
  // 获取浏览器当前地址并渲染到页面
  document.getElementById('full-url').innerText = window.location.href;
  document.getElementById('path-name').innerText = window.location.pathname;

  // 同时也在控制台打印一份
  console.log("网页绝对 URL: " + window.location.href);
  console.log("网页路径: " + window.location.pathname);
</script>

</body>
</html>

 

2 第2种写法:类和方法上都写注解,为啥不报错

当我们在类和方法上同时都写有注解时,SpringMVC在解析时,会拼接URL。类注解地址+方法注解地址。而本例中,类和方法上都写成了根路径,最后会拼接成http://localhost:8080//。SpringMVC在此时,会自动去掉一个根路径/的URL。home()方法被成功识别到,并直接返回了名为home的view。

3 第3种写法:只在方法上写注解,为啥也不报错

这是Spring开发中最推荐、最简洁的写法。类级别上不设置基准路径,直接由方法级别的@GetMapping(value=”/”)来统领全局。Spring识别到该方法并且绑定到根路径。

三 SpringMVC最佳实践小结

在编写SpringMVC控制器时,通常遵循这个铁律:方法上必须有路由注解,它才会被作为一个可达的Web接口。

  • 类级别的注解@RequestMapping:通常用于定义公共前缀。例如:处理订单的控制器,可以在类上写@RequestMapping(”/orders/”);
  • 方法上的注解,如则处理具体的动作,如@GetMapping(”/detail”),最终匹配成“/orders/detail”;
  • 对于类似查看主页这样的根路径,只需要直接写在方法注解上即可,@GetMapping(”/”),这样代码可读性好,简洁也不会引起歧义。

 

 

 

留言