Welcome 微信登录
编程资源 图片资源库

首页 / 软件开发 / JAVA / 在 Spring Boot 中如何实现伪静态

在 Spring Boot 中实现伪静态,核心是通过 URL 重写将动态路径(如 /user/123)伪装成静态文件路径(如 /user-123.html),本质上是让前端看到 “静态后缀”(.html/.htm 等),但后端仍按动态接口逻辑处理。 Spring Boot 支持两种主流实现方式:基于 Spring MVC 拦截器 / 路径匹配(推荐,无需额外依赖)和 基于 Tuckey URLRewriteFilter(功能更强,支持复杂规则)。 一、核心概念 伪静态的核心是: 前端请求:http://xxx.com/user-123.html(带静态后缀) 后端转发:内部将请求转发到 http://xxx.com/user/123(真实动态接口) 浏览器地址栏:保持显示 .html 后缀,不暴露真实接口路径 二、方式一:Spring MVC 原生实现(无依赖,简单场景) 利用 Spring MVC 的 @RequestMapping 路径匹配特性,直接接收带静态后缀的请求,或通过拦截器统一重写 URL。 场景 1:直接匹配静态后缀(最简单) 无需额外配置,直接在 Controller 中声明带 .html 后缀的路径,本质是 “接口路径本身就带静态后缀”,适合少量接口。 实现步骤: 编写 Controller,方法路径包含 .html:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StaticMockController {

    // 匹配请求:/user-123.html
    @GetMapping("/user-{id}.html")
    public String getUser(@PathVariable Long id) {
        return "查询用户ID:" + id; // 真实业务逻辑
    }

    // 匹配请求:/article/2025/01-01.html
    @GetMapping("/article/{year}/{month}-{day}.html")
    public String getArticle(
            @PathVariable Integer year,
            @PathVariable Integer month,
            @PathVariable Integer day) {
        return "查询 " + year + "年" + month + "月" + day + "日 文章";
    }
}
启动项目,直接访问: http://localhost:8080/user-123.html → 返回 查询用户ID:123 http://localhost:8080/article/2025/01-01.html → 正常返回文章信息 优点: 零配置、无依赖,适合少量固定格式的伪静态接口。 缺点: 接口路径与静态后缀强耦合,大量接口时维护麻烦。 场景 2:拦截器统一重写 URL(推荐,批量处理) 通过 Spring MVC 拦截器,将所有带 .html 后缀的请求,统一去掉后缀并转发到真实动态路径(如 /user-123.html → /user/123)。 实现步骤: 编写 URL 重写拦截器:
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 伪静态拦截器:将 .html 后缀的请求重写为动态路径
 */
public class StaticRewriteInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI(); // 原始请求路径:/user-123.html

        // 1. 只处理 .html 后缀的请求
        if (requestURI.endsWith(".html")) {
            // 2. 重写规则:将 "-" 替换为 "/",去掉 .html 后缀
            // 例:/user-123.html → /user/123
            String newUri = requestURI
                    .replace(".html", "") // 去掉后缀
                    .replaceFirst("-", "/"); // 将第一个 "-" 改为 "/"(可按需调整规则)

            // 3. 转发到新路径(服务器内部跳转,浏览器地址栏不变)
            request.getRequestDispatcher(newUri).forward(request, response);
            return false; // 拦截器处理完成,不再继续执行后续流程
        }

        // 非 .html 后缀请求,放行
        return true;
    }
}
注册拦截器(配置类):
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new StaticRewriteInterceptor())
                .addPathPatterns("/**") // 拦截所有请求
                .excludePathPatterns("/static/**"); // 排除静态资源(如 CSS/JS/图片)
    }
}
编写真实动态接口(无静态后缀):
@RestController
public class UserController {

    // 真实接口路径:/user/123(被转发后的请求会命中此方法)
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id) {
        return "查询用户ID:" + id;
    }
}
测试访问: 前端请求:http://localhost:8080/user-123.html 拦截器重写:/user-123.html → /user/123 后端响应:正常返回 查询用户ID:123,地址栏仍显示 .html 后缀。 自定义重写规则: 可根据需求修改 newUri 的生成逻辑,例如: 规则 1:/article-2025-01-01.html → /article/2025/01/01
String newUri = requestURI.replace(".html", "").replace("-", "/");
规则 2:/product-iphone15.html → /product?name=iphone15
String prefix = requestURI.split("-")[0].replace(".html", ""); // /product
String param = requestURI.split("-")[1].replace(".html", ""); // iphone15
String newUri = prefix + "?name=" + param;
三、方式二:Tuckey URLRewriteFilter(复杂场景) Tuckey URLRewriteFilter 是一个强大的 Java URL 重写工具,支持正则表达式、条件匹配等复杂规则,类似 Apache 的 mod_rewrite。 实现步骤: 引入依赖(Maven):
org.tuckeyurlrewritefilter4.0.3
在 src/main/resources 下创建配置文件 urlrewrite.xml(核心规则配置):

^/user-(\d+)\.html$/user/$1^/article-(\d{4})-(\d{2})-(\d{2})\.(html|htm)$/article/$1/$2/$3^/product-(\w+)\.html$/product?name=$1^/static/.*$
注册 URLRewriteFilter(配置类):
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter;

@Configuration
public class UrlRewriteConfig {

    @Bean
    public FilterRegistrationBeanurlRewriteFilter() {
        FilterRegistrationBeanregistration = new FilterRegistrationBean<>();
        registration.setFilter(new UrlRewriteFilter());
        registration.addUrlPatterns("/*"); // 拦截所有请求
        registration.addInitParameter("confPath", "classpath:urlrewrite.xml"); // 配置文件路径
        registration.setName("urlRewriteFilter");
        registration.setOrder(1); // 过滤器执行顺序(确保优先于其他过滤器)
        return registration;
    }
}
编写真实动态接口(与方式一相同):
@RestController
public class UserController {
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id) {
        return "查询用户ID:" + id;
    }
}
测试访问:
http://localhost:8080/user-456.html → 转发到 /user/456 → 正常响应 http://localhost:8080/article-2025-11-27.html → 转发到 /article/2025/11/27 优点:
规则集中管理,支持复杂正则、多后缀匹配(.html/.htm)、条件判断等。 与业务代码解耦,无需修改 Controller。 缺点:
需引入额外依赖,配置稍复杂。 四、关键注意事项
1. 排除静态资源
无论是拦截器还是 Tuckey 过滤器,都要排除真实静态资源(如 /static/css/、/static/js/、...
该文章为易网时代-编程资源站会员专属文章,请先登录后再进行查看。