|
| 1 | +# CommonUploadParam 额外表单字段功能使用示例 |
| 2 | + |
| 3 | +## 背景 |
| 4 | + |
| 5 | +微信公众号在上传永久视频素材时,需要在POST请求中同时提交文件和一个名为`description`的表单字段,该字段包含视频的描述信息(JSON格式)。 |
| 6 | + |
| 7 | +根据微信公众号文档: |
| 8 | +> 在上传视频素材时需要POST另一个表单,id为description,包含素材的描述信息,内容格式为JSON,格式如下: |
| 9 | +> ```json |
| 10 | +> { |
| 11 | +> "title": "VIDEO_TITLE", |
| 12 | +> "introduction": "INTRODUCTION" |
| 13 | +> } |
| 14 | +> ``` |
| 15 | +
|
| 16 | +## 解决方案 |
| 17 | +
|
| 18 | +`CommonUploadParam` 类已经扩展支持额外的表单字段,可以在上传文件的同时提交其他表单数据。 |
| 19 | +
|
| 20 | +## 使用示例 |
| 21 | +
|
| 22 | +### 1. 基本用法 - 上传永久视频素材 |
| 23 | +
|
| 24 | +```java |
| 25 | +import me.chanjar.weixin.common.bean.CommonUploadParam; |
| 26 | +import me.chanjar.weixin.common.util.json.WxGsonBuilder; |
| 27 | +import me.chanjar.weixin.mp.api.WxMpService; |
| 28 | +
|
| 29 | +import java.io.File; |
| 30 | +import java.util.HashMap; |
| 31 | +import java.util.Map; |
| 32 | +
|
| 33 | +public class VideoMaterialUploadExample { |
| 34 | + |
| 35 | + public void uploadVideoMaterial(WxMpService wxMpService) throws Exception { |
| 36 | + // 准备视频文件 |
| 37 | + File videoFile = new File("/path/to/video.mp4"); |
| 38 | + |
| 39 | + // 创建上传参数 |
| 40 | + CommonUploadParam uploadParam = CommonUploadParam.fromFile("media", videoFile); |
| 41 | + |
| 42 | + // 准备视频描述信息(JSON格式) |
| 43 | + Map<String, String> description = new HashMap<>(); |
| 44 | + description.put("title", "我的视频标题"); |
| 45 | + description.put("introduction", "这是一个精彩的视频介绍"); |
| 46 | + String descriptionJson = WxGsonBuilder.create().toJson(description); |
| 47 | + |
| 48 | + // 添加description表单字段 |
| 49 | + uploadParam.addFormField("description", descriptionJson); |
| 50 | + |
| 51 | + // 调用微信API上传 |
| 52 | + String url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=video"; |
| 53 | + String response = wxMpService.upload(url, uploadParam); |
| 54 | + |
| 55 | + System.out.println("上传成功:" + response); |
| 56 | + } |
| 57 | +} |
| 58 | +``` |
| 59 | +
|
| 60 | +### 2. 链式调用风格 |
| 61 | + |
| 62 | +```java |
| 63 | +import me.chanjar.weixin.common.bean.CommonUploadParam; |
| 64 | +import com.google.gson.JsonObject; |
| 65 | + |
| 66 | +public class ChainStyleExample { |
| 67 | + |
| 68 | + public void uploadWithChainStyle(WxMpService wxMpService) throws Exception { |
| 69 | + File videoFile = new File("/path/to/video.mp4"); |
| 70 | + |
| 71 | + // 准备描述信息 |
| 72 | + JsonObject description = new JsonObject(); |
| 73 | + description.addProperty("title", "视频标题"); |
| 74 | + description.addProperty("introduction", "视频介绍"); |
| 75 | + |
| 76 | + // 使用链式调用 |
| 77 | + String response = wxMpService.upload( |
| 78 | + "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=video", |
| 79 | + CommonUploadParam.fromFile("media", videoFile) |
| 80 | + .addFormField("description", description.toString()) |
| 81 | + ); |
| 82 | + |
| 83 | + System.out.println("上传成功:" + response); |
| 84 | + } |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +### 3. 多个额外表单字段 |
| 89 | + |
| 90 | +```java |
| 91 | +import me.chanjar.weixin.common.bean.CommonUploadParam; |
| 92 | + |
| 93 | +public class MultipleFormFieldsExample { |
| 94 | + |
| 95 | + public void uploadWithMultipleFields(WxMpService wxMpService) throws Exception { |
| 96 | + File file = new File("/path/to/file.jpg"); |
| 97 | + |
| 98 | + // 可以添加多个表单字段 |
| 99 | + CommonUploadParam uploadParam = CommonUploadParam.fromFile("media", file) |
| 100 | + .addFormField("field1", "value1") |
| 101 | + .addFormField("field2", "value2") |
| 102 | + .addFormField("field3", "value3"); |
| 103 | + |
| 104 | + String response = wxMpService.upload("https://api.weixin.qq.com/some/upload/url", uploadParam); |
| 105 | + |
| 106 | + System.out.println("上传成功:" + response); |
| 107 | + } |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +### 4. 从字节数组上传并添加表单字段 |
| 112 | + |
| 113 | +```java |
| 114 | +import me.chanjar.weixin.common.bean.CommonUploadParam; |
| 115 | + |
| 116 | +public class ByteArrayUploadExample { |
| 117 | + |
| 118 | + public void uploadFromBytes(WxMpService wxMpService) throws Exception { |
| 119 | + // 从字节数组创建上传参数 |
| 120 | + byte[] fileBytes = getFileBytes(); |
| 121 | + |
| 122 | + CommonUploadParam uploadParam = CommonUploadParam |
| 123 | + .fromBytes("media", "video.mp4", fileBytes) |
| 124 | + .addFormField("description", "{\"title\":\"标题\",\"introduction\":\"介绍\"}"); |
| 125 | + |
| 126 | + String response = wxMpService.upload( |
| 127 | + "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=video", |
| 128 | + uploadParam |
| 129 | + ); |
| 130 | + |
| 131 | + System.out.println("上传成功:" + response); |
| 132 | + } |
| 133 | + |
| 134 | + private byte[] getFileBytes() { |
| 135 | + // 获取文件字节数组的逻辑 |
| 136 | + return new byte[0]; |
| 137 | + } |
| 138 | +} |
| 139 | +``` |
| 140 | + |
| 141 | +## API 说明 |
| 142 | + |
| 143 | +### CommonUploadParam 类 |
| 144 | + |
| 145 | +#### 构造方法 |
| 146 | +- `fromFile(String name, File file)` - 从文件创建上传参数 |
| 147 | +- `fromBytes(String name, String fileName, byte[] bytes)` - 从字节数组创建上传参数 |
| 148 | + |
| 149 | +#### 方法 |
| 150 | +- `addFormField(String fieldName, String fieldValue)` - 添加额外的表单字段,返回当前对象支持链式调用 |
| 151 | +- `getFormFields()` - 获取所有额外的表单字段(Map类型) |
| 152 | +- `setFormFields(Map<String, String> formFields)` - 设置额外的表单字段 |
| 153 | + |
| 154 | +#### 属性 |
| 155 | +- `name` - 文件对应的接口参数名称(如:media) |
| 156 | +- `data` - 上传数据(CommonUploadData对象) |
| 157 | +- `formFields` - 额外的表单字段(可选,Map<String, String>类型) |
| 158 | + |
| 159 | +## 注意事项 |
| 160 | + |
| 161 | +1. **表单字段是可选的**:如果不需要额外的表单字段,可以不调用`addFormField`方法 |
| 162 | +2. **JSON格式**:对于需要JSON格式的表单字段(如description),需要先将对象转换为JSON字符串 |
| 163 | +3. **编码**:表单字段值会使用UTF-8编码 |
| 164 | +4. **所有HTTP客户端支持**:该功能在所有HTTP客户端实现中都得到支持(OkHttp、Apache HttpClient、HttpComponents、JoddHttp) |
| 165 | + |
| 166 | +## 兼容性 |
| 167 | + |
| 168 | +- 对于通过 `fromFile`、`fromBytes` 等工厂方法创建 `CommonUploadParam` 的代码,本功能在行为层面是向后兼容的,现有代码无需修改即可继续工作。 |
| 169 | +- 如果之前直接使用构造函数(例如 `new CommonUploadParam(name, data)`)创建对象,由于新增了 `formFields` 字段,构造函数签名可能发生变化,升级后需要改为使用上述工厂方法或根据新构造函数签名调整代码。 |
0 commit comments