devslab-kr/devslab-examples
GitHub: devslab-kr/devslab-examples
devslab-kr 系列 Spring Boot 库的可运行示例集合,涵盖分页、SSRF 防护、API 日志和平台 starter 等功能演示。
Stars: 0 | Forks: 0
# devslab-examples
**English** · [한국어](README.ko.md)
[devslab-kr](https://github.com/devslab-kr) Spring Boot starter 和库的可运行示例。
每个子目录都是一个**独立**的 Spring Boot 应用,包含各自的 Gradle 构建。选择其中一个,`cd` 进入该目录,然后运行 `./gradlew bootRun`。
## 示例
### easy-paging — Spring Boot 4 (`4.x` 系列)
最新的活跃版本系列。如果你的应用基于 Spring Boot 4+,请使用这些示例。
| 示例 | 展示内容 | Maven Central |
| --- | --- | --- |
| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | 使用 `@AutoPaginate` 的注解驱动 offset 分页 (Spring Boot 4 + MyBatis + H2) | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | 使用 `@KeysetPaginate` 的游标 (keyset) 分页 — 组合 `(time, id)` 键,在写入操作下保持稳定,无需 `OFFSET`/`COUNT(*)` | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | 针对**真实 PostgreSQL** 的同一 starter — 使用 Docker Compose 运行 `bootRun`,使用 Testcontainers + `@ServiceConnection` 进行测试,无需安装本地数据库 | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | 响应式技术栈 — 通过 `R2dbcOffsetPagingSupport` 使用 **WebFlux + R2DBC**。与 MVC 示例具有相同的 JSON 封装格式,以 `Mono>` 形式提供服务 | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |
### easy-paging — Spring Boot 3 维护版 (`3.x` 系列)
适用于仍在使用 Spring Boot 3.3–3.5 的应用。该 starter 的 [`3.x` 分支](https://github.com/devslab-kr/easy-paging-spring-boot-starter/tree/3.x) 会继续接收 SB3 的安全补丁;这些示例固定使用该版本系列。
| 示例 | 展示内容 | Maven Central |
| --- | --- | --- |
| [`easy-paging-demo`](easy-paging-demo/) | 使用 `@AutoPaginate` 的注解驱动 offset 分页 (Spring Boot 3 + MyBatis + H2) | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | 使用 `@KeysetPaginate` 的游标 (keyset) 分页 | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | 针对真实 PostgreSQL 的同一 starter | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | 响应式技术栈 — WebFlux + R2DBC | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |
### ssrf-guard
| 示例 | 展示内容 | Maven Central |
| --- | --- | --- |
| [`ssrf-guard-demo`](ssrf-guard-demo/) | 跨三个 Spring HTTP 客户端的 SSRF (服务端请求伪造) 防护 — 对所有客户端应用相同的 `UrlPolicy`。包含 15 种模式的攻击矩阵 endpoint,以及 Micrometer 指标。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) |
| [`ssrf-guard-springai-demo`](ssrf-guard-springai-demo/) | ⭐ **LLM agent SSRF 防御 (Spring AI)。** 包装每一个 Spring AI `ToolCallback`,以便在由 LLM 驱动的 `fetch_url` 运行前验证 URL 形式的工具参数。Fake-LLM 驱动程序使示例可以离线运行 (无需 API key)。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-springai) |
| [`ssrf-guard-langchain4j-demo`](ssrf-guard-langchain4j-demo/) | ⭐ **LLM agent SSRF 防御 (LangChain4j)。** 针对另一个主要 Java LLM 框架的相同实现 — 包装每个 `ToolExecutor` bean,并在 executor 运行前验证 `ToolExecutionRequest.arguments()` JSON。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-langchain4j) |
| [`ssrf-guard-feign-demo`](ssrf-guard-feign-demo/) | Spring Cloud OpenFeign `RequestInterceptor` — 对 `@FeignClient` 调用应用相同的 `UrlPolicy`。包含两个 `@FeignClient` 接口 (一个在白名单内,一个不在) 以展示拦截路径。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-feign) |
| [`ssrf-guard-jdkhttp-demo`](ssrf-guard-jdkhttp-demo/) | `java.net.http.HttpClient` (Java 11+) 包装器 — 该库不需要 Spring。在 `main()` 中只需三行代码即可完成配置。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-jdkhttp) |
| [`ssrf-guard-okhttp-demo`](ssrf-guard-okhttp-demo/) | OkHttp `Interceptor` + `Dns` 集成 — 同样不需要 Spring。在 `OkHttpClient.Builder` 上只需三行代码完成配置。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-okhttp) |
| [`ssrf-guard-httpclient5-demo`](ssrf-guard-httpclient5-demo/) | Apache HttpClient 5 — **DNS 阶段**的 SSRF 拦截 (`SafeDnsResolver`) + `SafeRedirectStrategy`。在 Spring 中无需配置代码 (模块自带自动配置);在 Spring 外部只需五行代码完成配置。消除 TOCTOU 问题的方案:在同一个 `InetAddress[]` 上进行验证和连接。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-httpclient5) |
| [`ssrf-guard-native-image-demo`](ssrf-guard-native-image-demo/) | ⚡ **GraalVM native-image** 验证。引入 `ssrf-guard:3.1.0`,应用 `org.graalvm.buildtools.native` 插件,演示 `nativeCompile` 如何生成一个可运行的 native binary,该二进制文件能像 JVM 构建一样拦截相同的 12 种模式的攻击矩阵。端到端验证 ssrf-guard 3.1.0 的 `RuntimeHintsRegistrar` 配置是否完整。 | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) |
### api-log
通过 [api-log](https://github.com/devslab-kr/api-log) starter 将异步 API 调用日志记录到 PostgreSQL JSONB 中 — 每个持久化后端对应一个示例。每个示例都使用**自回环** (self-loopback) 设计:同一个应用既暴露了一个 `/upstream/widgets` endpoint (即“被调用的服务”),又暴露了一个 `/client/widgets` endpoint,通过 api-log HTTP 客户端工具调用上游服务。第三个 `/api-log` endpoint 读取 `api_log` 表,因此你可以 curl 完整的生命周期 — INITIATED → SUCCESS / ERROR / RETRY_ERROR — 而无需离开示例环境。使用 Docker Compose 配置本地数据库;使用 Testcontainers + `@ServiceConnection` 进行集成测试。
| 示例 | 展示内容 | Maven Central |
| --- | --- | --- |
| [`api-log-jpa-demo`](api-log-jpa-demo/) | **JPA 后端** — Spring MVC + `RestApiClientUtil` (阻塞式) + `JpaApiLogWriter`。通过 `ApiLogRepository` (Spring Data JPA) 读取记录的行。这是 Servlet/JPA 应用最常用的即插即用方案。 | [](https://central.sonatype.com/artifact/kr.devslab/api-log-jpa) |
| [`api-log-mybatis-demo`](api-log-mybatis-demo/) | **MyBatis 后端** — Spring MVC + `RestApiClientUtil` + `MybatisApiLogWriter`。使用内置的 `ApiLogMapper` 进行按请求查找,并加上自定义的 `ApiLogQueryMapper` (xml) 执行 `recent` / `by-event` 查询。适用于已经在使用 MyBatis 且不想引入 JPA 的团队。 | [](https://central.sonatype.com/artifact/kr.devslab/api-log-mybatis) |
| [`api-log-r2dbc-demo`](api-log-r2dbc-demo/) | **R2DBC 后端 (响应式)** — WebFlux + `ReactiveApiClientUtil` (基于 `Mono`) + `R2dbcApiLogWriter`。读取端使用 `DatabaseClient` 进行流式 `Flux` 处理。整个 HTTP 路径均为非阻塞式;api-log 的写入也是非阻塞的。适用于请求路径中完全没有使用 JDBC 的 WebFlux 应用。 | [](https://central.sonatype.com/artifact/kr.devslab/api-log-r2dbc) |
### devslab-kit
Spring Boot 4 平台 starter — 包含认证、RBAC + groups + ABAC、多租户、动态菜单、审计日志以及管理员 REST API,全部通过自动配置实现。完整文档请访问 [devslab-kit.devslab.kr](https://devslab-kit.devslab.kr)。
| 示例 | 展示内容 | Maven Central |
| --- | --- | --- |
| [`devslab-kit-demo`](devslab-kit-demo/) | 一个**不包含任何平台自身代码**的普通消费者应用 — 添加该 starter 后即可启用认证、RBAC + ABAC、多租户、动态菜单、审计、首个管理员引导程序以及管理员 REST API。使用 PostgreSQL + Redis (分布式缓存);使用 Docker Compose 运行 `bootRun`,使用 Testcontainers + `@ServiceConnection` 进行测试。 | [](https://central.sonatype.com/artifact/kr.devslab/devslab-kit-spring-boot-starter) |
## 约定
- 每个示例都是一个**独立的 Gradle 项目** — 拥有各自的 `settings.gradle.kts`、`build.gradle.kts` 和 `gradlew`。示例之间不共享根构建,因此它们的依赖版本和 JDK 目标可以独立变化。
- 每个示例都依赖于其所展示的 starter 的**最新稳定版本** (在 `build.gradle.kts` 中固定版本号)。Dependabot 会在新版本发布时对其进行升级。
- 本仓库**不进行版本控制或打标签** — 示例不是已发布的 artifact。`main` 分支是唯一事实来源。
- 每个示例都有自己的 `README.md`,包含快速入门、前置条件以及该 starter 功能的详细介绍。
## 添加新示例
1. 在仓库根目录创建 `-demo/`。
2. 复制现有示例的目录结构 (例如 `easy-paging-demo/`) 作为模板。
3. 在上面的表格中添加一行,链接到该示例及其在 Maven Central 上的 starter。
4. CI 会根据 `build.gradle.kts` 文件的出现自动检测新示例 — 无需更改工作流。
## CI
Pull request 仅构建文件发生更改的示例。推送到 `main` 分支时会构建所有示例 (以捕捉 starter 版本升级带来的偏差)。
标签:JS文件枚举, Spring Boot, SSRF防护, Syscall, Web开发, 分页, 后台面板检测, 域名枚举, 搜索引擎查询, 测试用例, 版权保护, 示例项目