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

如何移除Spring Boot MVC中已有映射?自定义404页面失效问题

问题描述

依赖库中存在如下配置:

@Bean
public WebMvcConfigurer webMvcConfigurerAdapter() {
   return new WebMvcConfigurer() {
      public void addViewControllers(ViewControllerRegistry registry) {
          registry.addViewController("/notFound").setViewName("forward:/index.html");
          ...
      }
   }
}

我希望为404错误创建独立的错误页面,目前除404外其他错误页面均可正常工作,但上述映射会将/notFound请求转发至index.html。尝试添加带有@Primary注解的配置类:

@Configuration
@Primary
public class SpringMvcConfiguration {

    @Bean
    @Primary
    public WebMvcConfigurer mywebMvcConfigurerAdapter() {
        return new WebMvcConfigurer() {
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/login").setViewName("login");
                registry.addViewController("/error").setViewName("error");
                registry.addViewController("/notFound").setViewName("notFound");
                registry.addViewController("/").setViewName("forward:/index.html");
            }
        };
    }
}

之后问题仍未解决,请求始终转发至index.html,请问该如何在应用中移除原有映射?

解决方案

@Primary注解在这里不生效,因为Spring会加载所有WebMvcConfigurer类型的Bean并逐一执行配置,不会因为你加了@Primary就忽略其他的。要覆盖原有/notFound的映射,可以用以下几种方式:

方式一:清空原有视图控制器后重新注册

创建配置类,在添加自己的视图控制器前,清空所有已注册的视图控制器映射:

@Configuration
public class OverrideMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 清空所有已注册的视图控制器
        registry.getViewControllerMappings().clear();
        
        // 重新注册需要的视图控制器
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/error").setViewName("error");
        registry.addViewController("/notFound").setViewName("notFound");
        registry.addViewController("/").setViewName("forward:/index.html");
    }
}

此方式会完全接管视图控制器配置,适合需要替换所有视图映射的场景。

方式二:按优先级执行并移除指定映射

给你的配置类设置更高优先级,在添加新映射前移除原有/notFound的映射:

@Configuration
@Order(1) // 优先级高于依赖库配置,数值越小优先级越高
public class SpringMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 移除原有/notFound的映射
        registry.getViewControllerMappings().removeIf(mapping -> "/notFound".equals(mapping.getUrlPath()));
        
        // 注册自定义视图控制器
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/error").setViewName("error");
        registry.addViewController("/notFound").setViewName("notFound");
        registry.addViewController("/").setViewName("forward:/index.html");
    }
}

这种方式只修改目标映射,保留其他依赖库的配置,更灵活。

方式三:直接自定义ErrorController处理404

如果核心需求是给404设置独立页面,无需修改视图控制器映射,直接自定义错误控制器:

@Controller
public class CustomErrorController implements ErrorController {

    @RequestMapping("/error")
    public String handleError(HttpServletRequest request) {
        Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        
        if (status != null) {
            Integer statusCode = Integer.valueOf(status.toString());
            
            if (statusCode == HttpStatus.NOT_FOUND.value()) {
                return "notFound";
            }
        }
        return "error";
    }
}

此方式绕开视图映射冲突,直接在错误处理逻辑中为404返回对应页面,更直接高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:15:40