【问题标题】:Uploading Multi part content through HttpUrlConnection通过 HttpUrlConnection 上传多部分内容
【发布时间】:2015-10-06 17:55:15
【问题描述】:

我想从我的 android 应用程序上传一个带有少量参数的 pdf 文件到我的服务器。我花了将近 2 天的时间来寻找答案,但是当我尝试解决方案时总是会出现新问题。目前,此代码没有错误,但文件仍未上传,数据库也未更改。请帮助纠正我的代码。 我目前的代码是这样的:

1) 上传功能:

public void upload_file(String file_dir, String user_id,String path){

        try {
            String hyphen="--";
        String boundary="Bound";
        String newline="\r\n";

        URL url = new URL("http://117.**.**.**.**:****/upload.php");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Content-Type", "mutlipart/form-data;boundary="+boundary);

        DataOutputStream oStream = new DataOutputStream(conn.getOutputStream());

        //First Send Parameters so that database can be changed
        oStream.writeBytes(hyphen+boundary+newline);
        oStream.writeBytes("Content-Type: text/plain\n");
        oStream.writeBytes("Content-Disposition: form-data;name=\"u_id\"" + "\r\n");
        oStream.writeBytes(user_id+newline);
        //oStream.flush();

        oStream.writeBytes(hyphen+boundary+newline);
        oStream.writeBytes("Content-Type: text/plain\n");
        oStream.writeBytes("Content-Disposition: form-data;name=\"path\"" + "\r\n");
        oStream.writeBytes(path+newline);
        //oStream.flush();

        oStream.writeBytes(hyphen+boundary+newline);
        oStream.writeBytes("Content-Type: application/pdf\n");
        oStream.writeBytes("Content-Disposition: post-data;name=\"file\";" +
                "filename=\"s1.pdf\"" + "\r\n");

        FileInputStream file = new FileInputStream(file_dir);
        int filesize=file.available();
        Log.d("size", "" + filesize);
        int buffersize = 1024*1024;
        byte buff[] = new byte[buffersize];

        int byteRead = file.read(buff, 0, buffersize);  

        while (byteRead > 0) {

          oStream.write(buff, 0, byteRead);
          byteRead = file.read(buff, 0, buffersize);   
         }

        oStream.writeBytes(newline);

        InputStream iStream = conn.getInputStream();
        char arry[] = new char[1000];
        Reader in = new InputStreamReader(iStream, "UTF-8");
        StringBuilder response = new StringBuilder();
        while(true){
            int rsz = in.read(arry, 0, 1000);
            if (rsz < 0)
                break;
            response.append(arry,0, rsz);
        }
        Log.d("String",response.toString());                                  

         Log.d("Response","Res.."+conn.getResponseCode());

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

2) 我服务器上的 php 文件:upload.php

<?php

    require_once 'db_connect.php';

    $obj = new DB_Connect();
    $conn = $obj->connect();

    if(!$conn){
        echo mysql_error();
    }

    var_dump($_POST);
    var_dump($_REQUEST);
    print_r($_FILES);

    $file_path = "Docs/";
    $u_id=$_POST["u_id"];
    $path=$_POST["path"];
    $file = $path."/".basename( $_FILES['file']['name']);

    $qrry = mysql_query("insert into file values('$file','$u_id',now(),'pdf')");
    if(!$qrry)
    echo "error";

    $file_path = $file_path . basename( $_FILES['file']['name']);
    if(move_uploaded_file($_FILES['file']['tmp_name'], $file_path)) {
        echo "success";
    } else{
        echo "fail";
    }
 ?>

当我从我的 php 文件中检查回声时,我发现它既没有接收到参数也没有接收到文件......所以请帮助我知道这段代码中的错误。 提前致谢

【问题讨论】:

标签: java php android httpurlconnection ioexception


【解决方案1】:

您可以使用最小的HTTPS Upload Library。尽管有这个名字,它也适用于 HTTP。它只有大约 20K,实际上只是 HttpURLConnection 的包装,所以我觉得它非常适合 Android。它使您不必了解分段上传、编码等。也可以从Maven Central 获得。

您的示例如下所示:

public static void main(String[] args) throws IOException {

    HttpsFileUploaderConfig config = 
         new HttpsFileUploaderConfig(new URL("http://myhost/upload.php"));

    Map<String,String> extraFields = new HashMap<>();
    extraFields.put("u_id", "foo");
    extraFields.put("path", "bar");

    HttpsFileUploaderResult result = HttpsFileUploader.upload(
            config,
            Collections.singletonList(new UploadItemFile(uFile)),  // your file
            extraFields, // your fields
            null);

    if (result.isError()) {
        throw new IOException("Error uploading to " + config.getURL() + ", " + result.getResponseTextNoHtml());
    }
}

【讨论】:

    【解决方案2】:

    您的程序生成的多部分消息是错误的:缺少主体,缺少边界声明...这是您应该生成的格式:

    Message-ID: <000000001>
    MIME-Version: 1.0
    Content-Type: multipart/mixed; 
        boundary="----=_Part_0_842618406.1437326651362"
    
    ------=_Part_0_842618406.1437326651362
    Content-Type: application/octet-stream; name=myfile.pdf
    Content-Transfer-Encoding: 7bit
    Content-Disposition: attachment; filename=myfile.pdf
    
    <...binary data...>
    ------=_Part_0_842618406.1437326651362--
    

    我真心建议您不要从头开始生成 MIME 消息;相反,您可以使用 Java Mail API 来省去麻烦,例如使用这个程序:

    public void createMultipartMessage(File[] files, OutputStream out)
        throws MessagingException,
        IOException
    {
        Session session=Session.getDefaultInstance(System.getProperties());
        MimeMessage mime=new MimeMessage(session);
        Multipart multipart=new MimeMultipart();
        BodyPart part;
    
        // Send form data (as for http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2):
        part=new MimeBodyPart();
        part.setDisposition("Content-Disposition: form-data; name=\"<name>\"");
        part.setContent("<value>");        
        multipart.addBodyPart(part);
    
        // Send binary files:
        for (File file : files)
        {
            part=new MimeBodyPart();
            part.setFileName(file.getName());
            DataHandler dh=new DataHandler(new FileDataSource(file));
            part.setDataHandler(dh);
            multipart.addBodyPart(part);
        }
        mime.setContent(multipart);
        mime.writeTo(out);
    }
    

    您必须在运行时中包含 mail-1.4.1.jar 和 activation-1.1.1.jar 库。

    【讨论】:

    • 我还可以通过在 for 循环之前创建一个新的 MimeBodyPart() 来使用邮件 API 发送参数...对吗?
    • 对。我在前面的示例中包含了一个块。
    猜你喜欢
    • 2018-10-15
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    相关资源
    最近更新 更多