後端接收前端上傳的文件,構造post請求,調用上傳文件的外部接口

本文概述:
可能會存在一些需求,一些部署在內部的或者單獨一個環境的服務,提供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

clipboard.png

可能存在的坑:
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等內容)網絡

相關文章
相關標籤/搜索