您好,登錄后才能下訂單哦!
這篇“Java發送form-data請求怎么實現文件上傳”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java發送form-data請求怎么實現文件上傳”文章吧。
封裝了以下工具類:
package com.leeyaonan.clinkz.common.util; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.util.EntityUtils; import org.springframework.util.CollectionUtils; /** * HttpUtils * * @author Rot * @date 2021/10/15 17:45 */ @Slf4j public class HttpUtils { /** * 從連接池中獲取連接的超時時間--10s */ private static int connectionRequestTimeout = 10000; /** * 客戶端和服務器建立連接的超時時間--握手連接時間--10s */ private static int connectTimeout = 60000; /** * 從對方服務接受響應流的時間 */ private static int socketTimeout = 60000; /** * 連接池最大連接數 */ private static int maxTotal = 800; /** * 每個主機的并發 */ private static int maxPerRoute = 20; private static PoolingHttpClientConnectionManager connectionManager = null; private static CloseableHttpClient httpClient; public static CloseableHttpClient getClient() { return httpClient; } static { log.info("初始化http connection 連接池 ..."); try { // 配置同時支持 HTTP 和 HTPPS SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build()); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslConnectionSocketFactory).build(); connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); } catch (Exception e) { log.error("初始化http 連接池異常", e); connectionManager = new PoolingHttpClientConnectionManager(); } //連接池統一配置 connectionManager.setMaxTotal(maxTotal); connectionManager.setDefaultMaxPerRoute(maxPerRoute); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout).build(); //不做重試功能 HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(0, false); httpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).setRetryHandler(retryHandler).build(); ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1); scheduledExecutorService.scheduleWithFixedDelay(() -> { connectionManager.closeExpiredConnections(); connectionManager.closeIdleConnections(20, TimeUnit.SECONDS); log.info("回收過期的http連接完成 status:{}", connectionManager.getTotalStats()); }, 30, 120, TimeUnit.SECONDS); Runtime.getRuntime().addShutdownHook(new Thread(() -> { log.info("關閉 httpClient 連接"); try { if (httpClient != null) { httpClient.close(); } } catch (IOException e) { log.error("關閉 httpClient 異常", e); } })); } /** * post請求提交form-data上傳文件 * * @param url * @param headers 請求頭 * @return */ public static String doPostUploadFile(String url, Map<String, String> headers, File file) { HttpPost httpPost = new HttpPost(url); packageHeader(headers, httpPost); String fileName = file.getName(); CloseableHttpResponse response = null; String respContent = null; long startTime = System.currentTimeMillis(); // 設置請求頭 boundary邊界不可重復,重復會導致提交失敗 String boundary = "-------------------------" + UUID.randomUUID().toString(); httpPost.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary); // 創建MultipartEntityBuilder MultipartEntityBuilder builder = MultipartEntityBuilder.create(); // 設置字符編碼 builder.setCharset(StandardCharsets.UTF_8); // 模擬瀏覽器 builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); // 設置邊界 builder.setBoundary(boundary); // 設置multipart/form-data流文件 builder.addPart("multipartFile", new FileBody(file)); // application/octet-stream代表不知道是什么格式的文件 builder.addBinaryBody("media", file, ContentType.create("application/octet-stream"), fileName); HttpEntity entity = builder.build(); httpPost.setEntity(entity); try { response = httpClient.execute(httpPost); if (response != null && response.getStatusLine() != null && response.getStatusLine().getStatusCode() < 400) { HttpEntity he = response.getEntity(); if (he != null) { respContent = EntityUtils.toString(he, "UTF-8"); } } else { log.error("對方響應的狀態碼不在符合的范圍內!"); throw new RuntimeException(); } return respContent; } catch (Exception e) { log.error("網絡訪問異常,請求url地址={},響應體={},error={}", url, response, e); throw new RuntimeException(); } finally { log.info("統一外網請求參數打印,post請求url地址={},響應={},耗時={}毫秒", url, respContent, (System.currentTimeMillis() - startTime)); try { if (response != null) { response.close(); } } catch (IOException e) { log.error("請求鏈接釋放異常", e); } } } /** * 封裝請求頭 * * @param paramsHeads * @param httpMethod */ private static void packageHeader(Map<String, String> paramsHeads, HttpRequestBase httpMethod) { if (!CollectionUtils.isEmpty(paramsHeads)) { Set<Map.Entry<String, String>> entrySet = paramsHeads.entrySet(); for (Map.Entry<String, String> entry : entrySet) { httpMethod.setHeader(entry.getKey(), entry.getValue()); } } } }
maven依賴:
<!--http--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.9</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.12</version> </dependency>
核心部分:
// 設置請求頭 boundary邊界不可重復,重復會導致提交失敗 String boundary = "-------------------------" + UUID.randomUUID().toString(); httpPost.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary); // 創建MultipartEntityBuilder MultipartEntityBuilder builder = MultipartEntityBuilder.create(); // 設置字符編碼 builder.setCharset(StandardCharsets.UTF_8); // 模擬瀏覽器 builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); // 設置邊界 builder.setBoundary(boundary); // 設置multipart/form-data流文件 builder.addPart("multipartFile", new FileBody(file)); // application/octet-stream代表不知道是什么格式的文件 builder.addBinaryBody("media", file, ContentType.create("application/octet-stream"), fileName); HttpEntity entity = builder.build(); httpPost.setEntity(entity);
注意:這里的builder.addPart("multipartFile", new FileBody(file));,multipartFile對應form表單的字段名稱,如果接口更改了字段名稱,這里也需要更改
比如我有一個接口是這樣定義的:
@PostMapping("/xxx") public void test(@RequestParam(value = "abc") MultipartFile file) { ... }
那么使用上述工具請求該接口的時候,就需要將
builder.addPart("multipartFile", new FileBody(file));
改為
builder.addPart("abc", new FileBody(file));
以上就是關于“Java發送form-data請求怎么實現文件上傳”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。