在SpringMVC/SpringBoot控制器中經過獲取文件輸入流方式上傳文件到go-fastdfs的幾種實現

這是轉載的文章,之因此轉載,是由於原做者漏了一個hutool的import,致使我浪費了5個小時,而原做者的文章不能評論,特此轉載+說明。前端

就是這行代碼坑了我5個小時:
import cn.hutool.core.io.resource.InputStreamResource;java

最近不少朋友在go-fastdfs的微信羣裏面問道,go-fastdfs何時支持流上傳?其實一直都支持的!爲何這樣子說呢?由於go-fastdfs自己就是基於http協議進行傳輸的,那麼若是有讀者對Java的HttpURLConnection的源碼研究過的話,會發現其內部也是能夠經過conn.getInputStream()和conn.getOutputStream()獲取其輸入輸出流,一般能夠直接往outputStream裏面寫入符合http協議的數據。那麼根據這個特色,在Java裏面,直接經過流的形式(一般是從MultipartFile裏面獲取InputStream)再上傳到go-fastdfs是沒問題的。跟http協議相關的知識點包括http協議報文格式和上傳二進制數據等若是不瞭解能夠先自行百度一下。這裏不會細講的哦。git

引起認爲go-fastdfs不能直接流上傳的緣由
通過本人的分析認爲,讓廣大讀者認爲不能直接使用流上傳的緣由應該是go-fastdfs的github的代碼示例形成一些誤會。不過官方的代碼示例並無錯誤,只是直接從本地讀取文件系統的文件,造成File對象進行上傳。針對使用Spring等框架接收前端上傳過來的文件再進行轉發上傳到go-fastdfs的用戶,就可能會有疑惑。由於獲取到的是MultipartFile,而非java.io.File。github

圖片描述

Hutool-http、HttpClient、OkHttp3多種方式流式文件上傳
因爲有很多人問到上面的問題,如今本人總結了一個經常使用的幾種http客戶端文件流式上傳的方式,至關於給本身作下記錄,同時也給有這方面疑問的朋友一個借鑑。廢話很少說,直接上代碼吧。代碼是基於springboot的maven工程。spring

Hutool-http方式
先在pom中添加hutool的依賴apache

<dependency>json

<groupId>cn.hutool</groupId>
 <artifactId>hutool-all</artifactId>
 <version>4.5.1</version>

</dependency>
接着在Controller中代碼示例springboot

import cn.hutool.core.io.resource.InputStreamResource;

@RequestMapping("/upload")
public String  upload(MultipartFile file) {
    String result = "";
    try {
        InputStreamResource isr = new InputStreamResource(file.getInputStream(),
                file.getOriginalFilename());

        Map<String, Object> params = new HashMap<>();
        params.put("file", isr);
        params.put("path", "86501729");
        params.put("output", "json");
        String resp = HttpUtil.post(UPLOAD_PATH, params);
        Console.log("resp: {}", resp);
        result = resp;
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    return result;
}

HttpClient方式
pom依賴微信

<dependency>併發

<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>

</dependency>
<dependency>

<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>

</dependency>
接着在Controller中代碼示例

@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上傳示例
pom文件依賴

<dependency>

<groupId>com.squareup.okhttp3</groupId>
 <artifactId>okhttp</artifactId>
 <version>3.9.1</version>

</dependency>
接着在Controller中代碼示例

@RequestMapping("/upload2")
public String upload2(MultipartFile file) {
    String result = "";
    try {
        OkHttpClient httpClient = new OkHttpClient();
        MultipartBody multipartBody = new MultipartBody.Builder().
                setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getOriginalFilename(),
                        RequestBody.create(MediaType.parse("multipart/form-data;charset=utf-8"),
                                file.getBytes()))
                .addFormDataPart("output", "json")
                .build();

        Request request = new Request.Builder()
                .url(UPLOAD_PATH)
                .post(multipartBody)
                .build();

        Response response = httpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            ResponseBody body = response.body();
            if (body != null) {
                result = body.string();
                System.out.println(result);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return result;
}

總結上面給出了幾個示例,是否是都挺簡單的?經過這種方式,就能夠在Controller中作中轉了,仍是挺方便的。順便提一下,上面幾種方式中,我我的以爲Hutool的是最簡單的,最方便的,對於HttpClient而言,概念比較多,顯得相對複雜,OkHttp也同樣,不過比HttpClient顯得優雅點。針對通常的併發量,我的以爲hutool的Http已經夠用了,底層是基於jdk的HttpUrlConnection實現的。若是對性能有特殊要求的,能夠考慮httpclient或者OKHttp,後二者相對而言,更推薦使用OkHttp。

相關文章
相關標籤/搜索