You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Test中404请求未重定向到Swagger页面的问题排查

问题分析与解决方案

问题根源

你遇到的测试失败确实和MockMvc的特性有关:MockMvc直接调用Spring MVC的DispatcherServlet,不会经过Servlet容器的错误处理流程,所以你配置的WebServerFactoryCustomizer中的容器级ErrorPage规则不会生效。从控制台输出也能看出,请求被ResourceHttpRequestHandler处理后直接返回404,没有触发重定向逻辑。

两种解决方案

方案1:启动真实Servlet容器测试

改用@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)启动真实的Servlet容器,此时容器级的ErrorPage配置会生效,用TestRestTemplate或WebTestClient替代MockMvc:

用TestRestTemplate的测试代码

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = { MyProjectContext.class })
class MyProjectErrorControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void errorEnpointShouldRedirectToSwaggerPage() {
        ResponseEntity<Void> response = restTemplate.getForEntity("/dfhdfth", Void.class);
        // 验证状态码为302重定向
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FOUND);
        // 验证重定向目标URL
        assertThat(response.getHeaders().getLocation().toString()).endsWith(Endpoints.SWAGGER);
    }
}

用WebTestClient的测试代码

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = { MyProjectContext.class })
class MyProjectErrorControllerTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void errorEnpointShouldRedirectToSwaggerPage() {
        webTestClient.get().uri("/dfhdfth")
                .exchange()
                .expectStatus().isFound()
                .expectHeader().location(Endpoints.SWAGGER);
    }
}

方案2:改用Spring MVC层面的ErrorController

移除容器级的ErrorPage配置,改用Spring MVC的ErrorController实现重定向逻辑,这样MockMvc可以直接识别并处理:

修改配置类

@Configuration
public class MyProjectContext implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController(Endpoints.NOT_FOUND)
                .setViewName("redirect:" + Endpoints.SWAGGER);
    }

    // 替换容器级ErrorPage为Spring MVC的ErrorController
    @Bean
    public ErrorController errorController(DefaultErrorAttributes errorAttributes) {
        return new BasicErrorController(errorAttributes) {
            @Override
            public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
                HttpStatus status = getStatus(request);
                if (status == HttpStatus.NOT_FOUND) {
                    // 返回302重定向到Swagger页面
                    return ResponseEntity.status(HttpStatus.FOUND)
                            .header(HttpHeaders.LOCATION, Endpoints.SWAGGER)
                            .build();
                }
                // 其他错误状态码沿用默认处理
                return super.error(request);
            }
        };
    }
}

修改后的MockMvc测试代码

此时原有的MockMvc测试可以正常运行,只需补充状态码验证:

@SpringBootTest
@ContextConfiguration(classes = { MyProjectContext.class })
@AutoConfigureMockMvc
class MyProjectErrorControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void errorEnpointShouldRedirectToSwaggerPage() throws Exception {
        mockMvc.perform(get("/dfhdfth"))
                .andExpect(status().isFound()) // 验证302状态码
                .andExpect(redirectedUrl(Endpoints.SWAGGER));
    }
}

总结

  • 若要验证容器级的错误页逻辑,必须启动真实Servlet容器,用TestRestTemplate/WebTestClient测试;
  • 若想继续用MockMvc,需将重定向逻辑转移到Spring MVC层面的ErrorController中。

内容的提问来源于stack exchange,提问作者Kira Resari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:41:07