本文概述:
可能會存在一些需求,一些部署在內部的或者單獨一個環境的服務,提供rest服務。由後端來發送http請求來調用這些接口。那在後端就須要構造http請求。本文要解決的場景以下:
前端multipartfile 上傳文件,後端接收後構造post請求,調用外部接口,傳送文件流及其餘參數
內容包括:
1.前端postman調用上傳接口
2.後端接收multipartfile文件
3.後端用httpclient構造post請求
4.調用外部接口後返回結果的處理前端
先上代碼:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;web
/** *前端上傳文件,後端接收後構造post請求,調用外部文件上傳接口 */ @PostMapping(value = "uploadImage") public void uploadImage(Model model, @RequestParam(value = "image") MultipartFile image, String label) { log.info("=============uploadImage start================="); log.info("圖像處理的標籤"+label); Map<String, Object> data = new HashMap<String, Object>(); log.info("開始post請求構造======"); String url ="http://ip:port/mytest/fileup";//服務端要調用的外部接口 Map<String, String> resultMap = new HashMap<String, String>(); //httpclients構造post請求 CloseableHttpClient httpClient = HttpClients.createDefault(); try { log.info("post請求的url"+url); HttpPost httpPost = new HttpPost(url); //HttpMultipartMode.RFC6532參數的設定是爲避免文件名爲中文時亂碼 MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532); String originFileName = null; originFileName = image.getOriginalFilename(); // File file1 = new File("/home/temp/下載/1200-560.jpg"); //測試外部接口直接上傳本地圖片 builder.addBinaryBody("image", image.getBytes(), ContentType.MULTIPART_FORM_DATA, originFileName);// 設置上傳文件流(須要是輸出流),設置contentType的類型 builder.addTextBody("label",label);//post請求中的其餘參數 // log.info("上傳圖的標籤label"+label); HttpEntity entity = builder.build(); httpPost.setEntity(entity); HttpResponse response = httpClient.execute(httpPost);// 執行提交 HttpEntity responseEntity = response.getEntity();//接收調用外部接口返回的內容 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){// String imageUrl = stringStringMap.get("data"); // data.put("path",imageUrl); // 返回的內容都在content中 InputStream content = responseEntity.getContent(); byte[] bytes = toByteArray(content); //將byte數組進行base64編碼,此例中調用外部接口返回的是圖片流 String encodeStr = Base64.getEncoder().encodeToString(bytes); model.addAttribute("data",encodeStr); } } catch (Exception e) { model.addAttribute("code", "錯誤碼"); model.addAttribute("message","錯誤的提示信息"); }finally {//處理結束後關閉httpclient的連接 try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } /** *將輸入流轉換爲輸出流,無需建立臨時文件 * @param input * @return * @throws IOException */ public byte[] toByteArray(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); copy(input, output); return output.toByteArray(); }
postman調用接口以下spring
可能存在的坑:
1.確保後端部署的網絡與所調用的外部接口網絡是通的
2.後端接收multipartfile文件後若不需處理就調用外部接口的話,可不用生成臨時文件。可直接使用multipartfile對象自帶的方法,獲取byte流
3.構造的post請求,若涉及到文件的上傳,要設置正確的contentType,如上文代碼中所示
4.構造的post請求中,addBinaryBody()中傳遞的能夠是一個file對象,也能夠是流。【如果流則需是輸出流】
5.byte數組轉換爲base64字符串,詳情見上文代碼備註部分
6.將輸入流轉換爲輸出流,不須要寫臨時文件,見上文代碼apache
multipartfile對象與file的區別:
multipartfile是個接口,一般所說的multipartfile是在springmvc中設置過的。是springmvc中用來傳遞文件對象而定義的。該接口包括以下方法後端
byte[] bytes = multipartFile.getBytes();//獲取multipartfile對象的byte數組,可轉換文件流等 String contentType = multipartFile.getContentType();//獲取multipartfile的頭類型 InputStream inputStream = multipartFile.getInputStream();//獲取輸入流 String name = multipartFile.getName();//獲取文件名 String originalFilename = multipartFile.getOriginalFilename();//獲取初始文件名 long size = multipartFile.getSize();//獲取文件大小 boolean empty = multipartFile.isEmpty();//判斷對象內容是不是空 multipartFile.transferTo(new File("文件路徑"));//指定一個文件路徑,可將multipartfile對象中的內容寫入文件。若須要轉換爲file對象,須要建立一個臨時文件
MultipartFile是個接口,file能夠經過設置CommonsMultipartFile對象的屬性來進行轉換。數組
springmvc中設置以下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600"/>
<property name="maxInMemorySize" value="4096"/>
</bean>springboot
springboot中設置上傳文件的大小:
spring.http.multipart.maxFileSize=50Mb //單個文件可上傳的最大size
spring.http.multipart.maxRequestSize=1000Mb //整個請求的最大size(還包括header等內容)網絡