当前位置: 首页 > news >正文

下集:一条打包到底的静态部署之路

在这里插入图片描述

说完坑,再来讲正经操作。

这次我决定写得明明白白,清清楚楚,把那条“Spring Boot 扛着 Next.js 上线”的路子掰碎了揉细了告诉你。

无废话、无迷信、无AI幻觉。

第一步:Next.js 静态导出

项目根目录下的 next.config.js 要写得很清楚,不要留一丝幻想:

/** @type {import('next').NextConfig} */
const nextConfig = {output: 'export',           // 重点!导出为纯静态trailingSlash: true,       // 每个路径带斜杠,方便生成 index.htmlimages: {unoptimized: true        // 否则图片优化会报错},
};module.exports = nextConfig;

然后直接命令:

npm run build
npx next export

这时候,会生成一个 out/ 文件夹,里面是你真正能用来部署的东西。

结构大概长这样:

out/
├── admin/
│   └── login/
│       └── index.html
├── register/
│   └── index.html
├── index.html
├── _next/static/chunks/...js
└── ...

注意,每个页面其实就是一个路径+index.html 文件结构,所以根本不用搞什么“SPA跳转”那一套逻辑!

第二步:复制到Spring Boot资源目录

假设你后端目录结构是标准的:

backend/
└── src/└── main/└── resources/└── static/

那么执行这条命令:

cp -r out/* ../backend/src/main/resources/static/

清空 static 目录再复制比较稳妥。

第三步:配置 Security —— 非 /api/** 一律放行

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.cors(cors -> cors.configurationSource(corsConfigurationSource())).csrf(AbstractHttpConfigurer::disable).sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)).authorizeHttpRequests(auth -> auth.requestMatchers("/api/admin/**").hasRole("ADMIN").requestMatchers("/api/**").authenticated().anyRequest().permitAll()).authenticationProvider(authenticationProvider()).addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);return http.build();
}

千万不要用 .anyRequest().authenticated(),那是开发环境用来封杀一切的,不适合你现在这个"一切靠静态"的部署场景。

第四步:配置 WebConfig —— 精准转发到 index.html

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/static/").resourceChain(true).addResolver(new PathResourceResolver() {@Overrideprotected Resource getResource(String resourcePath, Resource location) throws IOException {Resource requested = location.createRelative(resourcePath);if (requested.exists() && requested.isReadable()) {return requested;}// 对于非静态资源请求,尝试回退到 index.htmlif (resourcePath.contains(".")) {return null; // 明确要请求静态资源的,找不到就报404}if (resourcePath.startsWith("api/")) {return null; // 让Controller处理}return new ClassPathResource("/static/index.html");}});}
}

这个配置非常关键。它做到了:

  • 能访问的静态资源直接返回
  • 明确的 API 请求让 controller 去处理
  • 只有“没有扩展名”的页面路径,比如 /admin/login,才回退到 index.html

AI 给你那种“全都 forward 到 index.html” 的 Controller 方案,在这个结构下是没必要、也极其危险的。会白屏、跳错页,还极难调试。

第五步:打包运行!

用 Maven 构建:

mvn clean package -DskipTests

运行:

java -jar target/backend-0.0.1-SNAPSHOT.jar

然后你可以打开:http://localhost:8082/

  • / 首页会显示出来
  • /admin/login 会跳转到你静态导出的 admin/login/index.html
  • /register/?token=abc123 会正确加载 register 页并保留查询参数
  • /api/** 接口仍然走后端 Controller,毫无冲突

最终效果:

你得到了一个:

  • 单一jar包即可部署
  • 不需要Node环境
  • 支持多页访问和刷新
  • 前后端分工明确但部署合体
  • 操作简明、老板无感知的系统

结语:这条路走通了,我回头一看

  • AI教的套路,不一定错,但常常不适合你这种“野路子结合小团队现状”的打法
  • 静态部署这条线,只要搞清楚目录结构和路径映射,真的比你想的简单
  • Spring Boot 其实是个好平台,只要你别逼它理解前端的世界

这次,我们用文件系统打败了抽象逻辑。

前端静态导出 + 后端反向代理 + 安全放行策略,这三板斧下去,小项目不管你多么前后端分离,最终都能“一锅端”。

别再迷信什么服务拆分了,小项目,能合就合。

回头再看那些鼓吹“必须前后端分离”的架构课件……我只想笑着对他们说一句:

“你把前端扔进static再说这话。”

相关文章:

  • hadoop.proxyuser.代理用户.授信域 用来干什么的
  • jvm安全点(二)openjdk17 c++源码垃圾回收安全点信号函数处理线程阻塞
  • 免费代理IP服务有哪些隐患?如何安全使用?
  • 中国各省供水量、用水量相关数据(2003-2022年)-社科数据
  • (3)python爬虫--Xpath
  • Python爬虫之路(14)--playwright浏览器自动化
  • uniapp -- uCharts 仪表盘刻度显示 0.9999999 这样的值问题处理。
  • 卸载和安装JDK
  • 电商项目-品牌管理微服务开发
  • Jackson使用详解
  • 代码随想录算法训练营第四十二四十三天
  • 提示词工程框架:CoT、ToT、GoT、PoT( 链式提示)
  • 磁盘I/O子系统
  • Scrapy进阶实践指南:从脚本运行到分布式爬取
  • PyQt5基本窗口控件(QSlider(滑动条))
  • 深入解析:如何基于开源OpENer开发EtherNet/IP从站服务
  • 高频面试题(含笔试高频算法整理)基本总结回顾110
  • 使用Spring Boot和Spring Security构建安全的RESTful API
  • 密文搜索-map容器+substr
  • Python爬虫(29)Python爬虫高阶:动态页面处理与云原生部署全链路实践(Selenium、Scrapy、K8s)
  • 广药集团原董事长李楚源被“双开”:去年8月被查,曾多次发表争议言论
  • 全国游泳冠军赛:孙杨、潘展乐同进400自决赛,今晚将正面对决
  • 阿里上财年营收增6%,蒋凡:会积极投资,把更多淘宝用户转变成即时零售用户
  • 新片|《碟中谍8:最终清算》定档5月30日
  • 中拉互联网发展与合作论坛在西安开幕
  • 李强:把做强国内大循环作为推动经济行稳致远的战略之举