核心代碼
public class WeChatMediaUploader {
private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s";
public static String upload(String accessToken, String type, File file) throws Exception {
String url = String.format(UPLOAD_URL, accessToken, type); // type: image, voice, video, thumb
HttpsURLConnection conn = createTrustAllConnection(url);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
try (OutputStream out = conn.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"), true)) {
writer.append("--").append(boundary).append("\r\n");
writer.append("Content-Disposition: form-data; name=\"media\"; filename=\"").append(file.getName()).append("\"\r\n");
writer.append("Content-Type: ").append(Files.probeContentType(file.toPath())).append("\r\n\r\n");
writer.flush();
Files.copy(file.toPath(), out);
out.flush();
writer.append("\r\n").append("--").append(boundary).append("--\r\n");
writer.flush();
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) sb.append(line);
// 解析 JSON 回傳 media_id
return parseMediaId(sb.toString());
}
}
private static HttpsURLConnection createTrustAllConnection(String url) throws Exception {
TrustManager[] tm = { new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] c, String a) {}
public void checkServerTrusted(X509Certificate[] c, String a) {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
}};
SSLContext ssl = SSLContext.getInstance("TLS");
ssl.init(null, tm, new SecureRandom());
HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
conn.setSSLSocketFactory(ssl.getSocketFactory());
conn.setHostnameVerifier((h, s) -> true);
return conn;
}
}
注意
- 生產環境**不要**使用信任所有憑證,請正確載入微信 CA 憑證或使用預設信任庫。
access_token 需定期刷新(有效期 2 小時)。
- 檔案大小限制:圖片 10MB、語音 2MB、視頻 10MB、縮略圖 64KB。