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

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";
        }
    }
}
问题根源
  1. Servlet映射优先级冲突:Tomcat 10默认配置中,JspServlet对*.jsp的扩展名匹配优先级高于DispatcherServlet的/路径匹配。访问/keepalive.jsp时,请求会被JspServlet优先处理,它会尝试在Web根目录寻找keepalive.jsp文件,但你的JSP实际存放在/WEB-INF/views/下,因此JspServlet找不到文件返回404。
  2. 命名空间不兼容: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:27:09