Androidのファイルアップロードの原理

5638 ワード

個人のホームページ:http://shiyiliang.cn
基本原理
私たちはブラウザでファイルをアップロードする時、このような(jsp)実現があると知っています.
 

フォームを指定する方法の種類が必要です.ここでは一般的にpostで、enctype属性はサーバに送信する前にどのようにフォームデータを符号化するべきかを規定しています.
  • appration/x-wn-form-urlencoded:送信前にすべての文字をエンコードする(デフォルト)
  • multiipad/form-data:文字コードではありません.ファイルアップロードコントロールを含むフォームを使用するには、この値が必要です.
  • text/plin:スペースは「+」のプラス記号に変換されますが、特殊文字コードではありません.
  • アップロードをクリックすると、ブラウザのネットワークデバッグが開けられます.要求体のデータは以下の通りです.
    ------WebKitFormBoundaryT1HoybnYeFOGFlBR
    Content-Disposition: form-data; name="token"
    
    xjjdke2m5hkjk3j3k43
    ------WebKitFormBoundaryT1HoybnYeFOGFlBR
    Content-Disposition: form-data; name="file"; filename="ss.jpg"
    Content-Type: image/jpeg
    
    ....jpg      ...
    ------WebKitFormBoundaryT1HoybnYeFOGFlBR--
    
    要求されたデータから、要求体には、すべてのデータがカプセル化され、------WebKitFormBoundaryT1HoybnYeFOGFlBRを用いて分離されており、異なるタイプであり、いくつかの指定されたパラメータも異なることがわかる.
  • 簡単なキーの場合は、Content-Disposition、つまりコンテンツの説明を指定する必要があり、名前と値、つまりnameの値とその対応する値(ここでtokenの値)
  • を指定します.
  • ファイルであれば、コンテンツの説明だけでなく、name値も指定し、ファイル名filename、コンテンツのタイプ(ここで伝えたピクチャタイプ)、ピクチャのバイナリデータ
  • も指定します.
    ブラウザは、これらのデータを固定されたフォーマットにカプセル化して、サービス端末に送信し、サービス端末は要求を受けた後、このBoundaryの値で転送された値を分割して取得し、処理する.
    Androidはどうやってファイルをアップロードしますか?
    私たちはAndroidが開発された時、ブラウザと違って、自動的にこれらのデータを組み立てることを知っていますが、既成のネットワーク要求フレームを使わないで、どうやってデータをアップロードしますか?答えははっきりしています.ブラウザの行動を真似して、ブラウザと同じように個人的にこれらのデータをカプセル化して、要求体に入れたら、正常にアップロードできます.多く言わないで~、直接に[lisdy 2の使うコード]の例をあげます.
    /**
     *       
     */
    public class FileUpLoadTest {
    
        //    
        private static final String BOUNDARY = "----WebKitFormBoundaryT1HoybnYeFOGFlBR";
    
    
        /**
         * HttpUrlConnection       
         * @param params     
         * @param fileFormName         
         * @param uploadFile      
         * @param newFileName         (          )
         * @param urlStr url
         * @throws IOException
         */
        public static void uploadForm(Map params, String fileFormName, File uploadFile, String newFileName,
                String urlStr) throws IOException {
    
            if (newFileName == null || newFileName.trim().equals("")) {
                newFileName = uploadFile.getName();
            }
            //      
            StringBuilder sb = new StringBuilder();
            /**
             *        
             */
            if (params != null) {
                for (String key : params.keySet()) {
                    sb.append("--" + BOUNDARY + "\r
    "); sb.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r
    "); sb.append("\r
    "); sb.append(params.get(key) + "\r
    "); } } /** * */ sb.append("--" + BOUNDARY + "\r
    "); sb.append("Content-Disposition: form-data; name=\"" + fileFormName + "\"; filename=\"" + newFileName + "\"" + "\r
    "); sb.append("Content-Type: image/jpeg" + "\r
    ");// , ContentType sb.append("\r
    "); byte[] headerInfo = sb.toString().getBytes("UTF-8"); byte[] endInfo = ("\r
    --" + BOUNDARY + "--\r
    ").getBytes("UTF-8"); URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); // , conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); conn.setRequestProperty("Content-Length", String.valueOf(headerInfo.length + uploadFile.length() + endInfo.length)); conn.setDoOutput(true); OutputStream out = conn.getOutputStream(); InputStream in = new FileInputStream(uploadFile); // ( , ) out.write(headerInfo); // byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } // out.write(endInfo); in.close(); out.close(); if (conn.getResponseCode() == 200) { System.out.println(" "); } } public static void main(String[] args) throws IOException { // File file = new File("ss.png"); // HashMap params = new HashMap<>(); params.put("user", "admin"); uploadForm(params, "file", file, "ss.jpg", "http://localhost:8080/Web/UploadFile"); } }
    上のコードはやはり比較的に簡単で、大部分の人を信じて、すべてわかることができます.その基本的な原理は順序によって、サーバーが認識できるフォーマット、つまり上記のフォーマットにデータをつづり合わせて、サーバーに伝達して、その解析処理をすればいいです.
    まとめて考える:アップロードのフレームワークやツール類を自分でカプセル化したいなら、普通はどんな仕事をしますか?上の例から見られますが、アップロードされたデータは主にキーペアとファイルの二つの種類に分けられています.もし一つのフレームにカプセル化すれば、外部からのキーの値対であるキーのペアnamevalueが外部に露出するだけです.ファイルであれば、ファイルのパス、ファイルの名前(filename)、ファイルのタイプ(Content-type)を指定してください.そして、私達はスティッチングの流れと要求の流れをカプセル化して、パッケージを完成させました.
    フレームがどのようにファイルをアップロードしているかを知りたいなら、「Retrofit学習のファイルアップロード」を見てもいいです.
    文章が何かの収穫を感じたら、注目してみてください.