問題情境:
在工作中經常出現調用第三方接口的方式,這次需求中有需要調用阿里雲的接口上傳文件,順便對調用方式都做了下整理,方便后續查看。
一.Hutool-http方式(詳情參考:https://www.hutool.cn/)
1.1 pom中添加hutool的依賴
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.0</version>
</dependency>
<!-- json依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
1.2 代碼示例,
1.2.1上傳文件第一種就是map的值是轉成InputStreamResource,如下兩種列舉
1 import cn.hutool.core.io.resource.InputStreamResource; 2 3 @RequestMapping("/fileupload") 4 public String upload(MultipartFile file) { 5 String result = ""; 6 try { 7 InputStreamResource isr = new InputStreamResource(file.getInputStream(), 8 file.getOriginalFilename()); 9 10 Map<String, Object> params = new HashMap<>(); 11 params.put("file", isr); 12 params.put("path", "86501729"); 13 params.put("output", "json"); 14 String resp = HttpUtil.post(url, params); 15 Console.log("resp: {}", resp); 16 result = resp; 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } 20 21 return result; 22 }
1 /** 2 * 3 * @param url 阿里雲文件上傳接口 4 * @param img 添加水印后的圖片 5 * @param newname 新圖片名稱 6 * @return 7 */ 8 public String fileHutool(String url,BufferedImage img,String newname) { 9 try { 10 Map<String, Object> param =new HashMap(); 11 //1.圖片壓縮且轉成byte[]數組 12 byte[] bytes=bufferedImageTobytes(img, 1); 13 //2.數組轉輸入流 14 InputStream buffin = new ByteArrayInputStream(bytes); 15 //3.輸入流轉MultipartFile對象, 16 MultipartFile file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), buffin); 17 18 //4.把MultipartFile這個對象轉成輸入流資源(InputStreamResource) 19 InputStreamResource isr = new InputStreamResource(file.getInputStream(), 20 file.getOriginalFilename()); 21 /*5.把條件組成map傳給hutool,已測過的hutool文件上傳 22 * 第一種是map的值是一個File, 23 * 第二種就是map的值是轉成InputStreamResource 24 */ 25 param.put("myfile",isr); 26 param.put("token", "1_grand"); 27 param.put("name",newname); 28 /** 29 * 接口會返回一個json格式的數據 30 * {"code":0,"msg":"success","data":{"url":"http://grandpic.oss-cn-shanghai.aliyuncs.com/pics/isr.jpg"}} 31 */ 32 String post=HttpUtil.post(url,param); 33 JSONObject josn=JSON.parseObject(post); 34 //獲取data下的接口返回路徑 35 JSONObject jurl=JSON.parseObject(josn.get("data").toString()); 36 37 return jurl.get("url").toString().length()>0?jurl.get("url").toString():null; 38 } catch (IOException e) { 39 e.printStackTrace(); 40 return null; 41 } 42 43 }
1.2.2 上傳傳文件第二種是map的值是一個File類型,一下兩種列
1 @RequestMapping("/order") 2 public String getgeneOrder1(@Value("${system.fileUpload}")String url) throws IOException { 3 Map<String, Object> param =new HashMap(); 4 File file=new File("D:\\文件表\\test2.jpg"); 5 param.put("myfile",file); 6 param.put("token", "1_grand"); 7 param.put("name", "isr.jpg"); 8 String post=HttpUtil.post(url,param); 9 JSONObject josn=JSON.parseObject(post); 10 JSONObject jurl=JSON.parseObject(josn.get("data").toString()); 11 System.out.println(jurl.get("url")); 12 return post; 13 }
二.HttpClient方式
2.1 pom中添加httpclient依賴
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.3</version>
</dependency>
2.2 代碼案列
1 @PostMapping("/order") 2 public String getgeneOrder(@Value("${system.fileUpload}")String url) throws IOException { 3 //1:創建一個httpclient對象 4 HttpClient httpclient = new DefaultHttpClient(); 5 Charset charset = Charset.forName("UTF-8");//設置編碼 6 7 //2:創建http的發送方式對象,是GET還是post 8 HttpPost httppost = new HttpPost(url); 9 10 //3:創建要發送的實體,就是key-value的這種結構,借助於這個類,可以實現文件和參數同時上傳 11 MultipartEntity reqEntity = new MultipartEntity(); 12 File myfile=new File("D:\\文件表\\test3.jpg"); 13 FileBody fileContent = new FileBody(myfile); 14 15 reqEntity.addPart("myfile",fileContent); 16 StringBody content = new StringBody("test.jpg",charset); 17 reqEntity.addPart("name",content); 18 StringBody contenttoken = new StringBody("1_grand",charset); 19 reqEntity.addPart("token",contenttoken); 20 21 httppost.setEntity(reqEntity); 22 //4:執行httppost對象,從而獲得信息 23 HttpResponse response = httpclient.execute(httppost); 24 HttpEntity resEntity = response.getEntity(); 25 26 String resString = EntityUtils.toString(resEntity); 27 return resString; 28 }
這一部分參考這個地址:https://segmentfault.com/a/1190000020158062
@RequestMapping("/upload1") public String upload1(MultipartFile file) { String result = ""; try { CloseableHttpClient httpClient = HttpClientBuilder.create().build(); CloseableHttpResponse httpResponse = null; RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(200000) .setSocketTimeout(2000000) .build(); HttpPost httpPost = new HttpPost(UPLOAD_PATH); httpPost.setConfig(requestConfig); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create() .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) .setCharset(Charset.forName("UTF-8")) .addTextBody("output", "json") .addBinaryBody("file", file.getInputStream(), ContentType.DEFAULT_BINARY, file.getOriginalFilename()); httpPost.setEntity(multipartEntityBuilder.build()); httpResponse = httpClient.execute(httpPost); if (httpResponse.getStatusLine().getStatusCode() == 200) { String respStr = EntityUtils.toString(httpResponse.getEntity()); System.out.println(respStr); result = respStr; } httpClient.close(); httpResponse.close(); } catch (Exception e) { e.printStackTrace(); } return result; }
三.OkHttp3方式
3.1 OkHttp3引入pom依賴
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.1</version>
</dependency>
3.2.參考案列
1 @RequestMapping("/fileorder") 2 public String upload2(MultipartFile file) { 3 String result = ""; 4 try { 5 OkHttpClient httpClient = new OkHttpClient(); 6 MultipartBody multipartBody = new MultipartBody.Builder(). 7 setType(MultipartBody.FORM) 8 .addFormDataPart("file", file.getOriginalFilename(), 9 RequestBody.create(MediaType.parse("multipart/form-data;charset=utf-8"), 10 file.getBytes())) 11 .addFormDataPart("output", "json") 12 .build(); 13 14 Request request = new Request.Builder() 15 .url(UPLOAD_PATH) 16 .post(multipartBody) 17 .build(); 18 19 Response response = httpClient.newCall(request).execute(); 20 if (response.isSuccessful()) { 21 ResponseBody body = response.body(); 22 if (body != null) { 23 result = body.string(); 24 System.out.println(result); 25 } 26 } 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 31 return result; 32 }
總結:
個人覺得Hutool的是最簡單的,最方便的,Hutool是gethub上的一個開源項目,還有很多其他的工具,個人覺得還可以,參考文檔地址:https://www.hutool.cn/
個人覺得hutool的Http已經夠用了,底層是基於jdk的HttpUrlConnection實現的。
如果對性能有特殊要求的,可以考慮httpclient或者OKHttp,后兩者相對而言,更推薦使用OkHttp。
排名結果就是:hutool<<OKHttp<<httpclient
