Spring6+Tomcat10下带.jsp后缀URL页面加载正常却返回404的解决问询
问题描述
使用Spring 6、Tomcat 10及Jakarta Servlet技术栈,访问/application-context/keepalive时请求正常返回HTTP 200状态码;但访问/application-context/keepalive.jsp时,页面虽能加载,却返回HTTP 404状态码,需让该URL返回200。
相关配置如下:
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <mvc:annotation-driven /> <context:component-scan base-package="com.jpmorgan.janussso" /> <context:property-placeholder location="file:E}/keepalive.properties" order="1" ignore-unresolvable="true" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp" /> </bean> </beans>
Controller代码
@Controller public class KeepAliveController { @RequestMapping(value = {"/","/keepalive","/keepalive.jsp","/error"}, method = RequestMethod.GET) public String validateHealthCheck(Model model, HttpServletRequest request, HttpServletResponse resp) { if (TaskScheduler.STATUS){ model.addAttribute("message", getTimeInFormat()); return "keepalive"; }else{ resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); model.addAttribute("errorMsg", "The server encountered an Internal Error and unable to complete your request. Please contact administrator. "); return "error"; } } }
问题根源
- Servlet映射优先级冲突:Tomcat 10默认配置中,
JspServlet对*.jsp的扩展名匹配优先级高于DispatcherServlet的/路径匹配。访问/keepalive.jsp时,请求会被JspServlet优先处理,它会尝试在Web根目录寻找keepalive.jsp文件,但你的JSP实际存放在/WEB-INF/views/下,因此JspServlet找不到文件返回404。 - 命名空间不兼容:web.xml使用的是Java EE旧命名空间,而Tomcat 10基于Jakarta Servlet规范,旧命名空间可能导致配置解析异常,影响请求处理逻辑。
解决方案
方案一:调整DispatcherServlet映射(推荐)
修改web.xml中DispatcherServlet的<url-pattern>为/*,让它优先处理所有请求(包括*.jsp后缀):
<servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
同时在dispatcher-servlet.xml中添加静态资源处理配置,避免静态资源无法访问:
<!-- 启用默认Servlet处理静态资源 --> <mvc:default-servlet-handler/> <!-- 或者指定静态资源路径映射 --> <!-- <mvc:resources mapping="/static/**" location="/static/"/> -->
方案二:限制JspServlet的处理范围
在web.xml中重新定义JspServlet,仅让它处理/WEB-INF/views/下的JSP文件,外部*.jsp请求将交由DispatcherServlet处理:
<!-- 覆盖Tomcat默认JspServlet配置 --> <servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>/WEB-INF/views/*.jsp</url-pattern> </servlet-mapping>
方案三:更新web.xml命名空间
将web.xml的命名空间替换为Jakarta EE标准,适配Tomcat 10环境:
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0" metadata-complete="true"> <!-- 原有配置内容 --> </web-app>
内容的提问来源于stack exchange,提问作者Viishwaas Sinha
相关产品推荐
相关产品推荐

