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

从原生Spring MVC迁移到Spring Boot:目录索引请求处理问题

解决方案

方法1:自定义全局控制器处理未匹配请求

创建全局控制器,捕获所有未被业务接口处理的GET请求,自动检查目标路径下是否存在index.jsp,存在则转发至该页面:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import jakarta.servlet.ServletContext;

@Controller
@RequestMapping("/**")
public class DirectoryIndexController {

    private final ServletContext servletContext;

    public DirectoryIndexController(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @GetMapping
    public String handleDirectoryIndex(@PathVariable(required = false) String path) {
        String targetPath = (path == null) ? "/" : "/" + path;
        String indexPath = targetPath + "/index.jsp";
        
        if (servletContext.getResource(indexPath) != null) {
            return "forward:" + indexPath;
        }
        return "forward:/error";
    }
}

该控制器优先级低于业务接口,不会影响已有请求逻辑。

方法2:手动注册视图控制器(适合少量目录)

若目录数量有限,可通过WebMvcConfigurer手动配置每个目录的转发规则:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/test1").setViewName("forward:/test1/index.jsp");
        registry.addViewController("/test1/").setViewName("forward:/test1/index.jsp");
        registry.addViewController("/test2").setViewName("forward:/test2/index.jsp");
        registry.addViewController("/test2/").setViewName("forward:/test2/index.jsp");
        // 其他目录按此格式添加
    }
}

方法3:扩展请求映射处理器(动态批量匹配)

通过扩展RequestMappingHandlerMapping,实现请求匹配失败时自动检查目录下的index.jsp,无需手动配置每个目录:

1. 自定义请求映射处理器

import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;

public class DirectoryIndexRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

    private final ServletContext servletContext;

    public DirectoryIndexRequestMappingHandlerMapping(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    protected Object handleNoMatch(Object handler, String lookupPath, HttpServletRequest request) throws IOException {
        String indexPath = lookupPath + "/index.jsp";
        if (servletContext.getResource(indexPath) != null) {
            request.getRequestDispatcher(indexPath).forward(request, request.getResponse());
            return null;
        }
        return super.handleNoMatch(handler, lookupPath, request);
    }
}

2. 注册自定义处理器

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import jakarta.servlet.ServletContext;

@Configuration
public class WebMvcConfig {

    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping(ServletContext servletContext) {
        return new DirectoryIndexRequestMappingHandlerMapping(servletContext);
    }
}

关键配置确认

确保application.properties中的视图解析配置正确:

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

内容的提问来源于stack exchange,提问作者Jakub Królikowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:27:37