在 Feign 调用 中模拟 Swagger 请求
2026/7/25 18:06:32 网站建设 项目流程

Feign 调用中模拟 Swagger 请求,本质是:构建一个与 Swagger 请求体完全一致的 JSON 字符串,然后塞入 DTO 的data字段(类型为Object

下面用GsonHutool两种方式,给出完整代码示例。


一、Swagger 中的 JSON 请求体示例

假设你在 Swagger 中提交的 JSON 是:

json

{ "phone": "15921892280", "templateCode": "SMS_123456789", "templateParam": { "code": "1234", "extra": { "param": "test" } } }

注意:templateParam是一个嵌套 JSON 对象,不是字符串。


二、使用 Gson 构建相同的 JSON

1. 构建嵌套的JsonObject

java

import com.google.gson.JsonObject; // 构建内层 extra JsonObject extra = new JsonObject(); extra.addProperty("param", "test"); // 构建 templateParam JsonObject templateParam = new JsonObject(); templateParam.addProperty("code", "1234"); templateParam.add("extra", extra); // 嵌套对象 // 构建根对象 JsonObject root = new JsonObject(); root.addProperty("phone", "15921892280"); root.addProperty("templateCode", "SMS_123456789"); root.add("templateParam", templateParam);

2. 转为 JSON 字符串

java

String jsonString = root.toString(); System.out.println(jsonString); // 输出: {"phone":"15921892280","templateCode":"SMS_123456789","templateParam":{"code":"1234","extra":{"param":"test"}}}

3. 设置到 DTO 并调用 Feign

java

// DTO 中的 data 字段是 Object MessageSendReq req = new MessageSendReq(); req.setData(jsonString); // 传入 JSON 字符串 // Feign 调用 messageClient.sendMessage(req);

三、如果 Swagger 中的templateParam字符串而不是对象

有些接口要求templateParamJSON 字符串(如阿里云短信),此时 Swagger 请求体可能是:

json

{ "phone": "15921892280", "templateCode": "SMS_123456789", "templateParam": "{\"code\":\"1234\",\"extra\":{\"param\":\"test\"}}" }

这种情况下,你需要先构建内部 JSON,再转为字符串作为值

java

// 1. 构建内部对象 JsonObject inner = new JsonObject(); inner.addProperty("code", "1234"); JsonObject extra = new JsonObject(); extra.addProperty("param", "test"); inner.add("extra", extra); // 2. 将内部对象转为 JSON 字符串 String innerJson = inner.toString(); // {"code":"1234","extra":{"param":"test"}} // 3. 构建根对象 JsonObject root = new JsonObject(); root.addProperty("phone", "15921892280"); root.addProperty("templateCode", "SMS_123456789"); root.addProperty("templateParam", innerJson); // 注意:作为字符串传入 String finalJson = root.toString();

四、使用 Hutool(更简洁,推荐)

如果项目已引入 Hutool,可以更直观地构建:

java

import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; // 构建内层 JSONObject extra = JSONUtil.createObj() .put("param", "test"); JSONObject templateParam = JSONUtil.createObj() .put("code", "1234") .put("extra", extra); // 构建根对象 JSONObject root = JSONUtil.createObj() .put("phone", "15921892280") .put("templateCode", "SMS_123456789") .put("templateParam", templateParam); // 转为字符串 String jsonString = root.toString(); // 设置到 DTO req.setData(jsonString);

五、JsonObjectString的区别(关键点)

传入 DTO 的类型Jackson 序列化后的 HTTP BodySwagger 是否一致
JsonObject❌ 序列化失败(抛出异常)
Map<String, Object>{"data":{"code":"1234"}}✅ 如果 Swagger 是对象,则一致
String(JSON 字符串){"data":"{\"code\":\"1234\"}"}⚠️ 如果 Swagger 是对象,则多了引号

结论:你必须明确 Swagger 中data字段期望的是JSON 对象还是JSON 字符串

  • 如果期望JSON 对象,你应该传入Map或 POJO,而不是String

  • 如果期望JSON 字符串(如阿里云短信),则传入String


六、如何确认 Swagger 期望的类型?

查看 Swagger 的请求体示例:

  • 如果显示为{ "code": "1234" }→ 是JSON 对象

  • 如果显示为"{\"code\":\"1234\"}"→ 是JSON 字符串

根据你的情况,阿里云短信的TemplateParam字符串,所以用jsonObject.toString()是正确的。


七、完整调用示例(Gson 版)

java

public void sendSms() { // 1. 构建参数 JsonObject param = new JsonObject(); param.addProperty("code", "1234"); param.addProperty("phone", "15921892280"); // 如果有嵌套 JsonObject extra = new JsonObject(); extra.addProperty("type", "notification"); param.add("extra", extra); // 2. 转为 JSON 字符串(因为阿里云要求 TemplateParam 是字符串) String templateParamStr = param.toString(); // 3. 构建请求 DTO MessageSendReq req = new MessageSendReq(); req.setPhone("15921892280"); req.setTemplateCode("SMS_123456789"); req.setData(templateParamStr); // 传入字符串 // 4. Feign 调用 try { MessageSendResp resp = messageClient.sendMessage(req); System.out.println("发送成功: " + resp); } catch (Exception e) { System.err.println("发送失败: " + e.getMessage()); } }

八、总结

步骤操作
1使用 Gson / Hutool 构建与 Swagger 格式一致的 JSON 结构
2如果是阿里云短信,调用toString()转为 JSON 字符串
3将该字符串设置到 DTO 的data字段
4通过 Feign 发送

这样,Feign 发送的请求体就与 Swagger 完全一致,不会再有序列化错误。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询