通过HttpUrlConnection上传多部分内容

时间:2015-07-17 04:50:24

标签: java php android httpurlconnection ioexception

我想从我的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文件中检查回声时,我发现参数和文件都没有被它接收...所以请帮助我知道这段代码中的错误。 提前致谢

2 个答案:

答案 0 :(得分: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());
    }
}

答案 1 :(得分:0)

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

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库。