Spring Boot应用出现Unexpected whitelabel error 404问题求助
排查Spring Boot应用404错误的步骤
从你描述的情况(master分支正常,test分支出现404,日志显示Resource not found)来看,核心问题是Spring没有识别到你的Controller请求映射,或者请求处理逻辑存在明显错误。下面是针对性的排查和修复建议:
1. 检查Controller类的核心注解
首先确认你的Controller类上是否标注了@Controller或@RestController注解:
- 如果你的方法是返回视图页面,用
@Controller;如果是直接返回JSON数据,推荐用@RestController(它包含了@Controller和@ResponseBody的功能)。 - 如果test分支里不小心移除了这个注解,Spring会把这个类当成普通Java类,不会注册请求映射,自然会返回404。
2. 修复方法返回类型的不兼容问题
你的方法声明返回ModelAndView,但实际返回的是Country对象和CovidExceptions对象,这明显类型不匹配,会导致Spring无法正确处理请求:
// 原方法存在类型错误 public ModelAndView returnCountry(@PathVariable("country_name") String name) { try { // ... 获取Country对象的逻辑 return country; // Country != ModelAndView } catch (JSONException exception) { return new CovidExceptions("API error"); // CovidExceptions != ModelAndView } // ... }
正确的写法分两种情况:
情况1:返回视图页面
@Controller @RequestMapping("/countries") public class CountryController { @RequestMapping("/{country_name}") public ModelAndView returnCountry(@PathVariable("country_name") String name) { try { // ... 获取Country对象的逻辑 ModelAndView mav = new ModelAndView("country-details"); // 指定视图名称 mav.addObject("country", country); // 将数据放入模型 return mav; } catch (Exception e) { ModelAndView errorMav = new ModelAndView("error-page"); errorMav.addObject("message", e.getMessage()); return errorMav; } } }
情况2:返回JSON数据
@RestController @RequestMapping("/countries") public class CountryController { @GetMapping("/{country_name}") // 推荐用更具体的@GetMapping代替@RequestMapping public ResponseEntity<Country> returnCountry(@PathVariable("country_name") String name) { try { // ... 获取Country对象的逻辑 return ResponseEntity.ok(country); } catch (JSONException e) { return ResponseEntity.internalServerError().body(null); } catch (NullPointerException e) { return ResponseEntity.notFound().build(); } catch (IOException e) { return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(null); } } // 用@ExceptionHandler统一处理异常更规范 @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception e) { if (e instanceof NullPointerException) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Country not found! Use English country code"); } else if (e instanceof IOException) { return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("Could not read from the API"); } else { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("API error"); } } }
3. 确认Spring组件扫描范围
检查你的Spring Boot启动类(带有@SpringBootApplication注解的类)所在的包:
@SpringBootApplication默认扫描启动类所在包及其所有子包下的组件。- 如果test分支里把Controller类移到了启动类包的外部,Spring无法扫描到它,需要手动指定扫描范围:
@SpringBootApplication(scanBasePackages = "de.fh.albsig") public class CovidTrackerApplication { public static void main(String[] args) { SpringApplication.run(CovidTrackerApplication.class, args); } }
4. 检查请求路径的正确性
- 确认你访问的URL是
http://localhost:8080/countries/{country_name},注意路径的拼写、大小写(Spring默认路径大小写敏感)。 - 比如访问
http://localhost:8080/countries/usa而不是http://localhost:8080/country/usa。
5. 排查依赖冲突问题
你的pom.xml中引入了Quarkus的测试依赖quarkus-junit5,但你用的是Spring Boot框架,这可能会导致测试环境或运行环境的依赖冲突:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <version>1.4.2.Final</version> <scope>test</scope> </dependency>
如果test分支新增了这个依赖,建议移除它,改用Spring Boot自带的spring-boot-starter-test即可满足测试需求。
6. 检查是否新增了拦截器/过滤器
如果test分支里新增了拦截器或过滤器,确认它们没有阻止请求到达Controller。可以临时禁用这些组件,看404问题是否消失。
最后验证步骤
- 启动应用后,查看日志中是否有类似
Mapped "{[/countries/{country_name}]}" onto public org.springframework.web.servlet.ModelAndView ...的日志,这说明请求映射已成功注册。 - 如果没有看到这条日志,说明Controller没有被Spring识别,回到前面的步骤排查注解和扫描范围。
内容的提问来源于stack exchange,提问作者SudoShutdown
相关产品推荐
相关产品推荐

