基於Http的客戶端上傳 java SE 、 Android 通用

基於Http的客戶端上傳 java SE 、 Android 通用

首先必須明確上傳須要注意的幾個事情html

一、請求必須爲post請求java

二、提交編碼須要爲multipart/form-data;android

1、在web中,比較簡單web

<form action="upload.action" method="post" enctype="multipart/form-data">
    <input type="file" name="files" />
    <input type="file" name="files" />
    <button type="submit">上傳</button>
</form>

若是上傳不了注意
一、method設置爲post,由於默認是get,必須手動設置爲post。
二、注意enctype必須爲multipart/form-data,意思是表單將以二進制上傳
三、此處的name="files" 就是服務端的Action中的files屬性名緩存

2、服務端的寫法,是基於struts2寫的適用於多文件上傳,單文件也能夠服務器

class UploadAction extends ActionSupport{
    private File[] files;
    
    @Override
    public String execute() throws Expection{
        int i = 0;
        for(File file : files){
            //獲取項目文件目錄
            String data = ServletActionContext.getServletContext().getRealPath("/data");
            //構建存儲處
            File fi = new File(data+"/"+(i++)+".txt");          
            //文件路徑
            Path source = Paths.get(file.getPath());
            //把緩存區的文件複製到存儲處
            Files.copy(source, new FileOutputStream(fi));
        }       
        return super.execute();
    }
    public void setFile(File[] file) {
        this.files = file;
    }
}

這裏必定要注意的是,若是你是在eclipse中部署服務器並上傳的文件,則上傳的文件並不是在eclipse中的項目的WebContent目錄下,他會存到項目緩存區,好比個人項目存到了網絡

~\workSpace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\文件上傳\data

3、接下來是是客戶端的寫法app

1.首先來明確一下web端上傳究竟上傳了些什麼,在此我上傳了兩個txt文件,內容分別是dom

1.txt:eclipse

我是1

2.txt:

我是2

利用http攔截軟件獲得了以下的信息

POST http://127.0.0.1/wjsc/upload.action HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Referer: http://127.0.0.1/wjsc/index.action
Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,ja;q=0.6,en-US;q=0.4,en;q=0.2
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7df258a3609da
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 330
DNT: 1
Host: 127.0.0.1
Pragma: no-cache

-----------------------------7df258a3609da
Content-Disposition: form-data; name="file"; filename="1.txt"
Content-Type: text/plain

我是1
-----------------------------7df3962f3609da
Content-Disposition: form-data; name="file"; filename="2.txt"
Content-Type: text/plain

我是2
-----------------------------7df3962f3609da--

這就是使用網頁提交時候提交的內容,因此咱們要模仿他:

在java中使用模仿http請求便可

public void upload(List<File> files){
    String result = "上傳失敗";
        try {
            //生成一個uuid來充當隨機數
            String boundary = java.util.UUID.randomUUID().toString();
            String prefix = "--";
            String linend = "\r\n";
            String multipart = "multipart/form-data";
            String charset = "UTF-8";
            URL url = new URL("http://127.0.0.1/wjsc/upload.action");           
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setConnectTimeout(5*1000);
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setUseCaches(false);
            con.setRequestMethod("POST");
            con.setRequestProperty("connection", "Keep-Alive");
            con.setRequestProperty("charsert", "UTF-8");
            con.setRequestProperty("content-Type", multipart+";boundary=" + boundary);
            con.connect();
            
            /*--這裏是模擬上傳真正的文件前的字符串,總共四行--*/

            //  -----------------------------7df258a3609da  
            //*注:這裏兩個 -- 就能夠了   7df258a3609da爲隨機數,這裏用生成的UUID來充當
            String one = "--" + boundary + linend;

            //Content-Disposition: form-data; name="file"; filename="1.txt" 
            //*注:
            //一、這裏的"file"就是Action中的屬性名,
            //二、name="file"; filename="1.txt" 必須是雙引號,不能用單引號,因此須要藉助 \" 在java字符串中表示雙引號。
            String two = "Content-Disposition: form-data; name=\"file\"; filename=\"1.txt\""+ linend;

            //Content-Type: text/plain 
            //*注    這裏的text/plain就是上傳的文件類型,
            //若是是jpg圖片則爲 image/jpg png圖片爲 image/png 這裏由於上傳的txt文件,因此爲text/plain
            
            String three = "Content-Type: text/plain"+linend;
            // *注:這是一個空行,必須存在
            String four = linend;

            //把以上的字符串連接起來
            StringBuilder sb = new StringBuilder();
            sb.append(one);
            sb.append(two);
            sb.append(three);
            sb.append(four);
            String start = sb.toString();
            
            //數據輸出流,用於把文件或者字符串的二進制輸出到網絡上
            DataOutputStream dataOut = new DataOutputStream(
                    con.getOutputStream());
            

            /*---------------------------------------開始上傳---------------------------------------*/
            for(File file : files){
                // 輸出文件頭
                dataOut.write(start.getBytes());
    
                // 輸出文件
                InputStream is = new FileInputStream(file);
                int buffLength = 1024;
                byte[] buff = new byte[buffLength];
                int len = 0;
                while ((len = is.read(buff)) != -1) {
                    dataOut.write(buff, 0, len);
                }
                is.close();
                dataOut.write(linend.getBytes());
            }

            // 結束的換行標誌
            String overFlag = linend+"--" + boundary + "--"+linend;
            dataOut.write(overFlag.getBytes());
            /*--------------------------------------上傳結束--------------------------------------*/
            
            /*--一下是讀取服務器返回的信息,與上傳無關--*/
            BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String temp = "";
            while((temp = reader.readLine())!=null){
                result = temp + result +"\n";
            }
            result = result + con.getResponseCode();

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
}
相關文章
相關標籤/搜索