1
0
mirror of synced 2026-02-08 03:37:49 +08:00

扩展CommonUploadParam支持额外表单字段并添加单元测试

Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-19 03:56:38 +00:00
parent 02e0874219
commit 5779ea64a3
8 changed files with 168 additions and 14 deletions

View File

@@ -10,6 +10,8 @@ import org.springframework.lang.Nullable;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 通用文件上传参数
@@ -34,6 +36,13 @@ public class CommonUploadParam implements Serializable {
@NotNull
private CommonUploadData data;
/**
* 额外的表单字段,用于在上传文件的同时提交其他表单数据
* 例如上传视频素材时需要提交description字段JSON格式的视频描述信息
*/
@Nullable
private Map<String, String> formFields;
/**
* 从文件构造
*
@@ -43,7 +52,7 @@ public class CommonUploadParam implements Serializable {
*/
@SneakyThrows
public static CommonUploadParam fromFile(String name, File file) {
return new CommonUploadParam(name, CommonUploadData.fromFile(file));
return new CommonUploadParam(name, CommonUploadData.fromFile(file), null);
}
/**
@@ -55,11 +64,26 @@ public class CommonUploadParam implements Serializable {
*/
@SneakyThrows
public static CommonUploadParam fromBytes(String name, @Nullable String fileName, byte[] bytes) {
return new CommonUploadParam(name, new CommonUploadData(fileName, new ByteArrayInputStream(bytes), bytes.length));
return new CommonUploadParam(name, new CommonUploadData(fileName, new ByteArrayInputStream(bytes), bytes.length), null);
}
/**
* 添加额外的表单字段
*
* @param fieldName 表单字段名
* @param fieldValue 表单字段值
* @return 当前对象,支持链式调用
*/
public CommonUploadParam addFormField(String fieldName, String fieldValue) {
if (this.formFields == null) {
this.formFields = new HashMap<>();
}
this.formFields.put(fieldName, fieldValue);
return this;
}
@Override
public String toString() {
return String.format("{name:%s, data:%s}", name, data);
return String.format("{name:%s, data:%s, formFields:%s}", name, data, formFields);
}
}

View File

@@ -44,11 +44,19 @@ public class CommonUploadRequestExecutorApacheImpl extends CommonUploadRequestEx
if (param != null) {
CommonUploadData data = param.getData();
InnerStreamBody part = new InnerStreamBody(data.getInputStream(), ContentType.DEFAULT_BINARY, data.getFileName(), data.getLength());
HttpEntity entity = MultipartEntityBuilder
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder
.create()
.addPart(param.getName(), part)
.setMode(HttpMultipartMode.RFC6532)
.build();
.setMode(HttpMultipartMode.RFC6532);
// 添加额外的表单字段
if (param.getFormFields() != null && !param.getFormFields().isEmpty()) {
for (java.util.Map.Entry<String, String> entry : param.getFormFields().entrySet()) {
entityBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.TEXT_PLAIN.withCharset("UTF-8"));
}
}
HttpEntity entity = entityBuilder.build();
httpPost.setEntity(entity);
}
String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);

View File

@@ -41,11 +41,19 @@ public class CommonUploadRequestExecutorHttpComponentsImpl extends CommonUploadR
if (param != null) {
CommonUploadData data = param.getData();
InnerStreamBody part = new InnerStreamBody(data.getInputStream(), ContentType.DEFAULT_BINARY, data.getFileName(), data.getLength());
HttpEntity entity = MultipartEntityBuilder
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder
.create()
.addPart(param.getName(), part)
.setMode(HttpMultipartMode.EXTENDED)
.build();
.setMode(HttpMultipartMode.EXTENDED);
// 添加额外的表单字段
if (param.getFormFields() != null && !param.getFormFields().isEmpty()) {
for (java.util.Map.Entry<String, String> entry : param.getFormFields().entrySet()) {
entityBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.TEXT_PLAIN.withCharset("UTF-8"));
}
}
HttpEntity entity = entityBuilder.build();
httpPost.setEntity(entity);
}
String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);

View File

@@ -39,6 +39,14 @@ public class CommonUploadRequestExecutorJoddHttpImpl extends CommonUploadRequest
}
request.withConnectionProvider(requestHttp.getRequestHttpClient());
request.form(param.getName(), new CommonUploadParamToUploadableAdapter(param.getData()));
// 添加额外的表单字段
if (param.getFormFields() != null && !param.getFormFields().isEmpty()) {
for (java.util.Map.Entry<String, String> entry : param.getFormFields().entrySet()) {
request.form(entry.getKey(), entry.getValue());
}
}
HttpResponse response = request.send();
response.charset(StandardCharsets.UTF_8.name());
String responseContent = response.bodyText();

View File

@@ -31,10 +31,18 @@ public class CommonUploadRequestExecutorOkHttpImpl extends CommonUploadRequestEx
@Override
public String execute(String uri, CommonUploadParam param, WxType wxType) throws WxErrorException, IOException {
RequestBody requestBody = new CommonUpdateDataToRequestBodyAdapter(param.getData());
RequestBody body = new MultipartBody.Builder()
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder()
.setType(MediaType.get("multipart/form-data"))
.addFormDataPart(param.getName(), param.getData().getFileName(), requestBody)
.build();
.addFormDataPart(param.getName(), param.getData().getFileName(), requestBody);
// 添加额外的表单字段
if (param.getFormFields() != null && !param.getFormFields().isEmpty()) {
for (java.util.Map.Entry<String, String> entry : param.getFormFields().entrySet()) {
bodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
}
}
RequestBody body = bodyBuilder.build();
Request request = new Request.Builder().url(uri).post(body).build();
try (Response response = requestHttp.getRequestHttpClient().newCall(request).execute()) {

View File

@@ -0,0 +1,98 @@
package me.chanjar.weixin.common.bean;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
/**
* CommonUploadParam 单元测试
*
* @author Binary Wang
*/
@Test
public class CommonUploadParamTest {
@Test
public void testFromFile() {
File file = new File("test.txt");
CommonUploadParam param = CommonUploadParam.fromFile("media", file);
Assert.assertNotNull(param);
Assert.assertEquals(param.getName(), "media");
Assert.assertNotNull(param.getData());
Assert.assertNull(param.getFormFields());
}
@Test
public void testFromBytes() {
byte[] bytes = "test content".getBytes();
CommonUploadParam param = CommonUploadParam.fromBytes("media", "test.txt", bytes);
Assert.assertNotNull(param);
Assert.assertEquals(param.getName(), "media");
Assert.assertNotNull(param.getData());
Assert.assertEquals(param.getData().getFileName(), "test.txt");
Assert.assertNull(param.getFormFields());
}
@Test
public void testAddFormField() {
File file = new File("test.txt");
CommonUploadParam param = CommonUploadParam.fromFile("media", file);
// 添加单个表单字段
param.addFormField("title", "测试标题");
Assert.assertNotNull(param.getFormFields());
Assert.assertEquals(param.getFormFields().size(), 1);
Assert.assertEquals(param.getFormFields().get("title"), "测试标题");
// 添加多个表单字段
param.addFormField("introduction", "测试介绍");
Assert.assertEquals(param.getFormFields().size(), 2);
Assert.assertEquals(param.getFormFields().get("introduction"), "测试介绍");
}
@Test
public void testAddFormFieldChaining() {
File file = new File("test.txt");
CommonUploadParam param = CommonUploadParam.fromFile("media", file)
.addFormField("title", "测试标题")
.addFormField("introduction", "测试介绍");
Assert.assertNotNull(param.getFormFields());
Assert.assertEquals(param.getFormFields().size(), 2);
Assert.assertEquals(param.getFormFields().get("title"), "测试标题");
Assert.assertEquals(param.getFormFields().get("introduction"), "测试介绍");
}
@Test
public void testConstructorWithFormFields() {
CommonUploadData data = new CommonUploadData("test.txt", null, 0);
Map<String, String> formFields = new HashMap<>();
formFields.put("title", "测试标题");
formFields.put("introduction", "测试介绍");
CommonUploadParam param = new CommonUploadParam("media", data, formFields);
Assert.assertNotNull(param.getFormFields());
Assert.assertEquals(param.getFormFields().size(), 2);
Assert.assertEquals(param.getFormFields().get("title"), "测试标题");
Assert.assertEquals(param.getFormFields().get("introduction"), "测试介绍");
}
@Test
public void testToString() {
File file = new File("test.txt");
CommonUploadParam param = CommonUploadParam.fromFile("media", file)
.addFormField("title", "测试标题");
String str = param.toString();
Assert.assertTrue(str.contains("name:media"));
Assert.assertTrue(str.contains("formFields:"));
}
}

View File

@@ -38,7 +38,7 @@ public class WxOpenMaAuthServiceImpl implements WxOpenMaAuthService {
@Override
public MaAuthUploadResult upload(CommonUploadData data) throws WxErrorException {
String response = wxMaService.upload(OPEN_MA_AUTH_UPLOAD, new CommonUploadParam("media", data));
String response = wxMaService.upload(OPEN_MA_AUTH_UPLOAD, new CommonUploadParam("media", data, null));
return WxMaGsonBuilder.create().fromJson(response, MaAuthUploadResult.class);
}

View File

@@ -57,7 +57,7 @@ public class WxOpenUploadIcpMediaParam implements Serializable {
CommonUploadMultiParam.NormalParam.builder().name("certificate_type").value(String.valueOf(certificateType)).build(),
CommonUploadMultiParam.NormalParam.builder().name("icp_order_field").value(icpOrderField).build()
))
.uploadParam(new CommonUploadParam("media", media))
.uploadParam(new CommonUploadParam("media", media, null))
.build();
}