在 Android 或 Java 應用中,若不想依賴第三方庫(如 OkHttp、Retrofit),可直接使用原生 Socket 實作 HTTP Multipart 檔案上傳。本文提供一個完整的 FormFile 類別,封裝檔案資料、參數名稱、Content-Type 等資訊,並實作 post() 方法直接對伺服器發送請求。
FormFile 支援兩種建構方式:
byte[] 直接傳入檔案內容File 物件讀取檔案流類別內部定義邊界字串 BOUNDARY,依照 RFC 2046 組裝 Multipart 實體,包含表單欄位與檔案兩部分。
public class FormFile {
private static final String LOGKEY = "FormFile";
private byte[] data;
private InputStream inStream;
private File file;
private String filname;
private String parameterName;
private String contentType = "application/octet-stream";
private String Opertype = null;
// 建構子略...
public boolean post(String path, Map<String, String> params) throws Exception {
final String BOUNDARY = "--------------7da2137580612";
final String endline = "--" + BOUNDARY + "--\r\n";
// 組裝檔案部分 Header
StringBuilder fileExplain = new StringBuilder();
fileExplain.append("--").append(BOUNDARY).append("\r\n");
fileExplain.append("Content-Disposition: form-data; name=\"")
.append(getParameterName()).append("\"; filename=\"")
.append(getFilname()).append("\"\r\n");
fileExplain.append("Content-Type: ").append(getContentType()).append("\r\n\r\n");
// 計算總長度、建立 Socket、發送 Request Header、Entity、Endline
// 完整邏輯請參考原始碼
}
}
File iconFile = new File("path/to/image.jpg");
String url = "https://192.168.1.101:8080/APP/initServlet";
Map<String, String> map = new HashMap<>();
map.put("name", "blog");
if (iconFile != null) {
FormFile uploadFile = new FormFile(
iconFile.getName(), iconFile, "iconfile", "image/jpeg");
uploadFile.setOper("action=insertusr"); // 附加在 URL 後
try {
boolean success = uploadFile.post(url, map);
// 處理結果
} catch (Exception e) {
e.printStackTrace();
}
}