Maven项目Eclipse运行正常,部署至Tomcat出现404、405错误如何解决?
问题根因分析
- 上下文路径不匹配:本地执行
spring-boot:run时应用默认部署在根路径/,而手动部署war包到Tomcat时,默认会以war包名称作为上下文路径(比如war包名为web-demo.war,访问路径前缀就是/web-demo)。如果前端请求路径写死为/xxx的绝对路径,会直接请求到Tomcat根路径下的对应地址,而非应用路径下的接口,就会出现404;如果请求的地址命中了Tomcat默认的拦截规则,还会返回405方法不允许错误。 - 启动类初始化配置缺失:你当前的启动类继承了
SpringBootServletInitializer但没有重写configure方法,虽然能正常启动应用,但部分Servlet上下文的映射规则不会完全生效,会导致接口、静态资源的路由异常。 - 多模块打包依赖缺失:该项目是多模块结构,如果web模块打包为war时没有正确引入api模块的依赖,会导致api模块的接口类没有被打包到war包中,访问对应接口时返回404。
- 前端路径配置硬编码:项目使用JSF作为视图层,如果页面内的表单提交、请求路径写死了根路径前缀,没有适配Tomcat部署的上下文路径,也会导致请求地址错误。
解决方案
- 修正上下文路径配置
最简单的适配方式是将导出的war包重命名为ROOT.war,放到Tomcat的webapps目录下,Tomcat会自动将该包部署在根路径/,和本地运行的环境完全一致,无需修改任何项目代码。如果要保留自定义上下文路径,需要修改所有前端请求路径,添加上下文前缀,比如JSP页面中使用${pageContext.request.contextPath}作为路径前缀。 - 补全启动类配置
在WebApplication类中添加configure方法重写,完整启动类代码如下:/** * since basePackage includes com.apiDemo.* and api module is imported, api components will also be invoked. */ @Configuration @ComponentScan(basePackages = "com.*") @SpringBootApplication public class WebApplication extends SpringBootServletInitializer { public static void main(String[] args) throws Exception { SpringApplication.run(WebApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(WebApplication.class); } @Override public void onStartup(ServletContext servletContext) throws ServletException { servletContext.setInitParameter("com.sun.faces.expressionFactory", "org.apache.el.ExpressionFactoryImpl"); } } - 校验打包依赖配置
检查web模块的pom.xml中是否已经正确引入api模块的依赖,打包完成后解压war包,确认WEB-INF/lib目录下存在api模块对应的jar包,避免接口类缺失。 - 排查405错误
出现405错误时首先核对前端请求的HTTP方法和后端接口注解声明的方法是否一致,同时检查项目是否配置了跨域拦截,放行OPTIONS预检请求,避免非简单请求被拦截导致方法不允许。
内容的提问来源于stack exchange,提问作者user630702
相关产品推荐
相关产品推荐

