使用HttpURLConnection的put或者post請求上傳檔案
阿新 • • 發佈:2019-01-04
HttpURLConnection為java本身提供的傳送http請求的工具,今天遇到需要用put請求上傳檔案的需求,記錄下:
首先分析下put請求的格式,使用postman的put請求傳送一個檔案,由於現在有springboot,實現一個接受put請求傳送檔案的伺服器很簡單,可以用來測試分析。
postman分析的請求如下:
首先上面一部分為請求頭的資料,裡面需要注意的點是Content-type,因為上傳檔案,所以型別為Multipart/form-data, 後面boundary為下面資料的分隔字串,隨機產生的。
然後分析下面資料,+表示字串拼接
首先是一個分割字串
格式為 – + boundary + \r\n
然後是Content-Disposition:form-data; + name=”file”; + filename=“檔名” + \r\n
這裡的name值是輸入框input的name,filename值為檔名,這兩個引數都是選填,但是不填的話會影響後臺引數的接收。
接下來是Content-Type: text/plain + \r\n
然後\r\n
接下來就是檔案資料部分,不多解釋,需要注意的是檔案寫入完了以後要加回車機\r\n
然後是請求資料結束分割線,格式為
\r\n + – + boundary + – + \r\n
下面完整寫一遍資料格式,指定boundary為wk-2519775
--wk-2519775\r\n
Content-Disposition:form-data; name="file"; filename=“test.txt” \r\n
Content-Type: text/plain\r\n
\r\n
資料部分......\r\n
\r\n--wk-2519775--\r\n
下面為實現程式碼:
public class HttpTool {
private static final String nextLine = "\r\n";
private static final String twoHyphens = "--";
//分割線 隨便寫一個
private static final String boundary = "wk_file_2519775";
/**
* 生成http連線
* @param method http請求方式
* @return httpURLConnection
* @throws IOException 連線生成失敗
*/
private static HttpURLConnection createConnection(String urlPath, String method) throws IOException {
URL url = new URL(urlPath);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod(method);
httpURLConnection.setRequestProperty("Charsert", "UTF-8");
return httpURLConnection;
}
/**
* 多檔案上傳
* @param files 檔案
*/
public static void uploadFiles(File[] files){
String url = "http://localhost:8080/file";
for (File file : files){
uploadFile(file, url);
}
}
/**
* 上傳檔案
* @param file 檔案
* @param url 請求路徑
*/
private static void uploadFile(File file, String url){
HttpURLConnection connection = null;
OutputStream outputStream = null;
FileInputStream inputStream = null;
try {
//獲取HTTPURLConnection連線
connection = createConnection(url, "PUT");
//執行寫入預設為false,置為true
connection.setDoOutput(true);
//禁用快取
connection.setUseCaches(false);
//設定接收編碼
connection.setRequestProperty("Accept-Charset", "utf-8");
//開啟長連線可以持續傳輸
connection.setRequestProperty("Connection", "keep-alive");
//設定請求引數格式以及boundary分割線
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
//設定接收返回值的格式
connection.setRequestProperty("Accept", "application/json");
//開啟連線
connection.connect();
//獲取http寫入流
outputStream = new DataOutputStream(connection.getOutputStream());
//分隔符頭部
String header = twoHyphens + boundary + nextLine;
//分隔符引數設定
header += "Content-Disposition: form-data;name=\"file\";" + "filename=\"" + file.getName() + "\"" + nextLine + nextLine;
//寫入輸出流
outputStream.write(header.getBytes());
//讀取檔案並寫入
inputStream = new FileInputStream(file);
byte[] bytes = new byte[1024];
int length;
while ((length = inputStream.read(bytes))!= -1){
outputStream.write(bytes, 0, length);
}
//檔案寫入完成後加回車
outputStream.write(nextLine.getBytes());
//寫入結束分隔符
String footer = nextLine + twoHyphens + boundary + twoHyphens + nextLine;
outputStream.write(footer.getBytes());
outputStream.flush();
//檔案上傳完成
InputStream response = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(response);
while (reader.read() != -1){
System.out.println(new String(bytes, "UTF-8"));
}
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
System.out.println(connection.getResponseMessage());
}else {
System.err.println("上傳失敗");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null){
outputStream.close();
}
if (inputStream != null){
inputStream.close();
}
if (connection != null){
connection.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
post請求上傳檔案也是一樣的,生成httpurlconnection連線時請求方式設為POST即可。
順便附上springboot的接收程式碼:
@SpringBootApplication
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class);
}
}
@RestController
public class PutController {
@PutMapping("/file")
public String getPutFile(MultipartFile file){
System.out.println(file.getOriginalFilename());
return "{\"name\" : 111 }";
}
@PostMapping("/file")
public String getPostFile(MultipartFile file){
System.out.println(file.getOriginalFilename());
return "{\"name\" : 111 }";
}
}