# requester **Repository Path**: czy7z0ne/requester ## Basic Information - **Project Name**: requester - **Description**: 开发一个用于模拟postman的网络请求调用工具,并计划能将模拟的请求与响应生成前后端代码 生成代码的技术栈:前端Vue2+Node12系,后端Java8+Maven3.6.0 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-10-25 - **Last Updated**: 2026-11-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Requester — HTTP 接口调试 & 前后端代码生成工具 面向前后端项目的接口调用调试工具:先用 Postman 式界面调通外部接口,再一键生成可直接移植的前后端代码。 ## 核心特性 1. **接口模拟调用**:GET/POST/PUT/DELETE/HEAD/OPTIONS 方法(后端显式 `setRequestMethod`,方法真实生效);Params、Headers、Body(JSON / x-www-form-urlencoded / form-data 含文件 / 原始文本);响应展示(状态码、耗时、大小、响应头、JSON 美化、GBK/UTF-8 手动重读、超 5MB 截断提示)。 - **请求头快捷输入**:Header 名与值均为自绘组合框(可输入可下拉,聚焦展示全量候选、输入后过滤,自由输入不受限)。值候选带用途说明:Content-Type 14 项(application/json、charset 变体、x-www-form-urlencoded、multipart/form-data、text/xml、application/xml、SOAP、octet-stream 等)、Accept 9 项、Authorization(Bearer/Basic,选中自动带出 `Bearer ` 前缀)、X-Requested-With、Cache-Control;键名候选 14 个常用头。 - **Path / Query 分离**:Params 拆成两个子区——URL 里用 `{}` 标记的占位符在地址栏失焦时自动提取为 Path 区 key(键名只读、不能手工加行),Query 行单独维护;占位符未填值会拦截发送而不是带着 `{id}` 发出去。URL 下方实时预览「最终请求 URL」(占位符替换 → Query 拼接 → `#fragment` 归位),与真正发出去的报文逐字节一致。 - **Linux curl 报文生成**:`curl` 页签实时把当前配置拼成多行 curl 命令(`\` 续行、一键复制),URL 部分与界面预览共用同一套规则(`utils/urlBuilder.js`,与后端 `UrlBuilder` 的 R1~R7 等价),因此不会出现「预览一个样、curl 一个样」。其余细节严格对齐后端转发行为——丢弃 Host/Content-Length、`Accept-Encoding: identity`、Content-Type 按请求体类型覆盖并在不一致时提示、`Expect:` 防 100-continue、form 表单用 `--data-urlencode`/`--form-string`、文件字段以 `/tmp/<文件名>` 占位、HTTPS 可勾选 `-k`(同时作用于真实发送);PATCH/TRACE/CONNECT 等后端拒绝的方法给出明确错误提示。已用 `/echo/any` 接口对拍验证 curl 与工具转发结果一致。 2. **请求体类型支持**(每个字段均可选值类型,支持无限嵌套对象/数组): - 字段类型统一六种:**文本 / 整数 / 小数 / 布尔 / 对象 / 数组**,实时格式校验(红字提示); - form 表单字段选「对象」后**展开子键值对行逐项填写**、选「数组」后**展开元素行逐项添加**(元素类型同样可选,支持数组嵌套对象/数组,无限层级),发送时序列化为 JSON 串整体发送(如 `metadata={"source":"ACK"}`、`ids=[1,2,3]`,对应 curl 的 `--form '...'`); - JSON 请求体双模式:「JSON 文本」直接粘贴;「键值对构建(带类型)」中对象/数组字段同样展开子行编辑,自动处理引号与转义。 3. **代码自动生成**(两种模式可切换): - **通用模式**(默认):生成 `ExtApiInvokeController` + `ExtApiInvokeRequest` + `HttpInvokeUtil`(后端)与 `extApi.js`(前端)。一次移植全项目复用,调用时只传参数。 - **专用模式**:针对当前调试的接口生成具名方法,**参数带类型**——JSON body 按值类型推断(整数 Integer/Long、小数 Double、布尔 Boolean、字符串 String),对象/数组字段以 String(JSON 字符串)传参并原样内嵌(Service javadoc 与前端示例均标注用 `JSON.stringify({...})` 构造);Controller 示例含 Map→类型转换。 - 两种模式**返回结构完全一致**,切换模式时前端代码几乎不用改;前端示例会按最近一次调试的真实响应写出字段路径。 4. **未传参数不发送**(避免静默错数据):数值/布尔参数用包装类型,传 `null` 表示「本次不发送该字段」——JSON 请求体里不含该字段、Query 不拼接该参数、表单不提交该字段。不再用 `0` / `false` / 空串兜底,因此不会出现「用户没填,却被当成填了 0」这类不报错但结果错误的问题。 5. **使用说明页**(「注意事项」右侧页签):告诉需求方拿到生成的代码后**哪些能改、改了会怎样**—— - **入参表**:每个参数的类型、传 `null` 的效果、传入形态,并提示判断准则——哪些该由业务上下文提供(客户号/借据号/流水号),哪些该提为常量或配置(渠道号/系统标识); - **出参表**:`success / data / rawBody` 的判定口径,附最近一次调试响应里 `data` 的真实字段路径; - **可改常量表**:超时、URL、路由、包名、编码等移植时的调整点,逐条写明「改了会怎样」,易踩的坑整行高亮(如 `Boolean.valueOf("1")` 得 false、302 跟随后 `success=true` 但 `data` 为空); - **业务层调用示例**:按当前接口动态生成的一段可编译 Java 代码,演示业务上下文如何组装成入参、`data` 如何映射成自己的业务 DTO(示例已随生成器做过 JDK 8 编译验证)。 6. **架构约束适配**:生成代码遵循「前端 → 自己后端转发 → 目标接口」模式,适配前端网关约 20s 无响应即报错的限制。 ## 技术约束(与目标项目一致) - 前端生成代码:Vue2 + axios,兼容 Node 12/14 项目 - 后端生成代码:Java 8 + Maven 3.6.0,外部调用用 **JDK 原生 HttpURLConnection**,不依赖任何第三方 HTTP 库 - JSON 响应解析复用 **Spring Boot 自带的 Jackson**(jackson-databind),无需额外引入依赖。若目标环境是纯 JDK(无 Jackson),删掉 `HttpInvokeUtil.tryParseData` 及其调用处即可恢复完全零依赖,此时响应只保留 `rawBody` 原文 - 所有用户输入嵌入代码前经转义处理,保证「复制即编译」 ## 生成代码的响应结构 通用模式的 `HttpInvokeUtil.invoke()` 与专用模式的 `XxxService.xxx()` 返回**同一个结构**: | 字段 | 说明 | |---|---| | `success` | HTTP 状态码是否 2xx(不代表业务成功,业务错误码请自行判断) | | `httpStatus` | HTTP 状态码 | | `data` | **仅 JSON 响应时存在**,已解析好的对象/数组,前端可直接取字段 | | `rawBody` | 外部接口响应原文,任何响应都保留;非 JSON **文本**响应时请用它(文件响应见下) | | `bodyContentType` / `bodySizeBytes` / `bodyFileName` / `bodyBase64` | **仅文件/二进制响应**(PDF、Excel、图片、附件等)时存在,前端用 `bodyBase64` 拼 Blob 即可 `a.download` 下载;超过 5MB 只给元信息不转 Base64 | | `costMs` | 耗时毫秒 | | `errMsg` | 失败时的错误信息 | 判定是否需要解析:`Content-Type` 含 `json` 优先;缺失或以 `text/` 开头且响应体以 `{`/`[` 开头时兜底尝试。解析失败一律静默降级为只给 `rawBody`,绝不影响调用本身。 文件判定走 `Content-Type`(`text/*`、`json`、`xml`、`csv`、`form-urlencoded` 视为文本,其余视为文件),并用「字节里含 `0x00`」兜底那些用 `text/plain` 返回附件的服务——这类响应按文本读会变成乱码,所以必须保留原始字节。 专用模式遇到 4xx/5xx **不再抛 RuntimeException**(那会被 Spring 默认错误处理吞掉,只剩一个 500 页面),改为 `success=false` + `httpStatus` + `rawBody` 原文,排障时能直接看到外部接口返回了什么。 > 旧版本生成的字段名为 `body`,现已更名为 `rawBody`。 ## 参数空值语义 生成代码里「没传」和「传了 0」是两件事: | 场景 | 生成代码的行为 | |---|---| | 数值/布尔参数为 `null` | JSON 请求体不含该字段、Query 不拼接、表单不提交 | | 数值/布尔参数为空串(Controller 侧) | 同样按 `null` 处理(`toInteger("")` → `null`) | | 字符串参数为空串 | 原样透传(空串就是空串),需要「不发送」请传 `null` | | 前端生成函数未收到某字段 | 该字段传 `null`,后端据此省略 | 因此 JSON 请求体是**运行时逐字段拼装**的(`StringBuilder` + `firstField` 标记),不会产生 `"key":null` 这种占位。 生成前端示例时,工具会把**最近一次调试成功响应的 JSON 样本**一并提交,示例代码据此写出真实字段路径(如 `console.log(result.data.data.userName)`);未调试过则退化为占位写法。JSON 请求体示例也会按当前填写的真实内容生成 `JSON.stringify({...})` 字面量,而非 `{ ... }` 占位。 ## 超时预算(重要) | 层 | 默认值 | 说明 | |---|---|---| | 后端 connectTimeout | 5000ms | TCP 握手宽裕值,连接建不上早失败 | | 后端 readTimeout | 15000ms | 5s + 15s ≤ 前端 20s 限制 | | 前端 axios timeout | 18000ms | 保证后端结构化超时错误先于前端盲超时到达 | 目标接口耗时长时,按公式同步调整:connect + read + 网络余量 < 20s。 ## 使用 ```bat # 方式一:一键启动(需先 mvn package) requester.bat # 方式二:开发调试 mvn package java -jar target/requester-1.0.0.jar --server.port=18080 # 浏览器打开 http://127.0.0.1:18080 # 前端开发(修改 frontend/ 后重新构建) cd frontend && npm install && npm run build # 产物自动输出到后端 static ``` ## 工程结构 ``` pom.xml # Spring Boot 2.7.18 / Java 8 requester.bat # 一键启动 src/main/java/com/bank/requester/ controller/ ProxyController # POST /api/proxy 代理转发 CodeGenController # POST /api/codegen 代码生成、/api/format-json EchoController # 本地测试端点(/echo/ping、/echo/get、/echo/post、/echo/slow) GlobalExceptionHandler service/ HttpForwardService # HttpURLConnection 转发核心(multipart/GZIP/GBK/5MB 截断/超时) CodeGenService # 生成编排(JSON 字段提取、方法名推导、注意事项汇总) JavaBackendCodeGen # 后端 Java 代码模板(通用/专用) FrontendCodeGen # 前端 axios 代码模板 model/ HttpRequestConfig(三方共用模型)等 util/ MultipartBodyWriter / SslTrustUtil / CharsetDetectUtil / StrEscapeUtil frontend/ # vue-cli 工程(Vue 2.7 + @vue/cli-service 5,Node 12/14/22 均可构建) src/components/ RequestPanel / KeyValueEditor / BodyEditor / ResponsePanel / CodePanel ``` ## 离线环境说明 - Maven 依赖仅需:`spring-boot-starter-web`、`spring-boot-starter-test`(2.7.18),提前预下载到私服/本地仓库即可。 - npm 依赖见 `frontend/package.json`(@vue/cli-service 5 + vue 2.7 + axios 0.27),在联网机器 `npm install` 后可将 `node_modules` 整体拷贝到离线机。 - 生成的代码不依赖任何第三方 HTTP 库。 ## 注意事项(生成代码时界面也会提示) - **HTTPS 自签证书**:工具内可勾选信任所有证书调试;生成代码不含 trust-all,正式移植请用 `keytool -importcert` 将证书导入 JRE cacerts。 - **PATCH**:JDK HttpURLConnection 不支持,界面与生成结果均会提示。 - **form-data 文件上传**: - **专用模式**:生成的代码**包含文件 part**(`writeFilePart`,格式与工具内 `MultipartBodyWriter` 一致)。每个文件展开成 Service 的两个入参——`xxxBytes`(`byte[]`,内容)与 `xxxFileName`(`String`,文件名);`byte[]` 传 `null` 表示本次不带该文件。HTTP JSON 传不了 `byte[]`,所以 Controller 侧收 `xxxBase64` 字符串、由生成的 `toBytes()` 解码后交给 Service。 - **通用模式**:不支持 multipart,生成结果顶部会有醒目提示引导切换到专用模式(不会静默丢弃请求体而不告知)。 - **专用模式路由冲突**:映射为 `@PostMapping("/URL 末段小写")`,若同一后端包内两个接口末段相同(如 `/v1/user` 与 `/v2/user`),Spring 启动会因 Ambiguous mapping 失败,需手工改掉其中一个方法名与前端调用路径。