服务端上传文件到云存储分两步: 1、获取上传链接 2、上传文件 如官方说明所述https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html
我在第二步时遇到报错 The body of your POST request is not well-formed multipart/form-data. 请大侠支招!
代码如下
主文件
String fileName = path.getFileName().toString();
String cloudPath = "shenqitest/" + fileName;
WxCloudUploadFileResult uploadResult = cloudService.uploadFile(this.env, cloudPath);
System.out.println(uploadResult.toString());
Map<String, File> fileParams = new HashMap<>();
fileParams.put("file", path.toFile());
Map<String, String> otherParams = new HashMap<>();
otherParams.put("key", cloudPath);
otherParams.put("Signature", uploadResult.getAuthorization());
otherParams.put("x-cos-security-token", uploadResult.getToken());
otherParams.put("x-cos-meta-fileid", uploadResult.getCosFileId());
//
//Map<String, String> headerParams = new HashMap<>();
//headerParams.put("Content-Type", "multipart/form-data"); // 不加boundary会报错: The specified method is not allowed against this resource.
String resp = HTTPUtils.uploadFile(uploadResult.getUrl(), fileParams, otherParams, null);
工具文件
public static String uploadFile(String url, Map<String, File> fileParams, Map<String, String> otherParams, Map<String, String> headerParams) {
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = "";
try {
HttpPost httpPost = new HttpPost(url);
//设置请求头
if (headerParams != null && headerParams.size() > 0) {
for (Map.Entry<String, String> e : headerParams.entrySet()) {
String value = e.getValue();
String key = e.getKey();
if (StringUtils.isNotBlank(value)) {
httpPost.setHeader(key, value);
}
}
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(StandardCharsets.UTF_8);
//builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//加上此行代码解决返回中文乱码问题
// 文件传输http请求头(multipart/form-data)
if (fileParams != null && fileParams.size() > 0) {
for (Map.Entry<String, File> e : fileParams.entrySet()) {
String fileParamName = e.getKey();
File file = e.getValue();
if (file != null) {
//String fileName = URLEncoder.encode(file.getName(), StandardCharsets.UTF_8);
String fileName = file.getName();
//try (InputStream stream = new FileInputStream(file)) { // 请求时要用stream
builder.addBinaryBody(fileParamName, new FileInputStream(file), ContentType.APPLICATION_OCTET_STREAM, fileName);
//}
}
}
}
// 普通参数请求头(application/json)
ContentType contentType = ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), StandardCharsets.UTF_8);
if (otherParams != null && otherParams.size() > 0) {
for (Map.Entry<String, String> e : otherParams.entrySet()) {
String value = e.getValue();
if (StringUtils.isNotBlank(value)) {
builder.addTextBody(e.getKey(), value, contentType);
}
}
}
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
// 将响应内容转换为字符串
result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
要传的文件是jpeg,文件的ContentType试过APPLICATION_OCTET_STREAM、IMAGE_JPEG、MULTIPART_FORM_DATA、DEFAULT_BINARY,其它参数的ContentType试过DEFAULT_TEXT、MULTIPART_FORM_DATA、APPLICATION_JSON,都是一样的结果
换了一种访问方式,解决了
public static org.apache.http.HttpResponse sendMultiFormMixData(String url, Map<String, File> nameFiles, List<NameValuePair> otherParams, List<NameValuePair> headerParams) { HttpPost httpPost = new HttpPost(url); //设置请求头 if (headerParams != null && headerParams.size() > 0) { for (NameValuePair pair : headerParams) { String key = pair.getName(); String value = pair.getValue(); if (StringUtils.isNotBlank(value)) { httpPost.setHeader(key, value); } } } // 设置传输参数,设置编码。设置浏览器兼容模式,解决文件名乱码问题 MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532); // 解决中文字符?的问题 ContentType contentTypeText = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), StandardCharsets.UTF_8); for (NameValuePair pair : otherParams) { builder.addPart(pair.getName(), new StringBody(pair.getValue(), contentTypeText)); } // 解决中文文件名?的问题 ContentType contentTypeForm = ContentType.create(ContentType.MULTIPART_FORM_DATA.getMimeType(), StandardCharsets.UTF_8); for (Map.Entry<String, File> nameFile : nameFiles.entrySet()) { File file = nameFile.getValue(); if (file.exists()) { ContentBody fileBody = new FileBody(file, contentTypeForm); builder.addPart(nameFile.getKey(), fileBody); } else { log.warn("跳过不存在的文件: {}", file.getPath()); } } HttpEntity httpEntity = builder.build(); httpPost.setEntity(httpEntity); try (CloseableHttpClient client = HttpClientBuilder.create().build()) { return client.execute(httpPost); } catch (IOException e) { throw new RuntimeException(e); } }