Android通过MultipartEntity向服务器发送图像 - 设置Content-type?

9
我读了许多关于从Android应用程序向服务器发送图像的帖子,就内容类型而言,它们被分为三类:
a) 它们根本没有设置内容类型,但可能以某种方式工作。
b) 它们使用过时的方法。
c) 它们使用与我选择的完全不同的方法。
我想将文件发送到服务器并存储在文件夹中。
我的代码是一堆拼凑起来的东西,是我阅读了许多帖子和文章之后想出来的,这里是代码:
public void uploadImageToServer(String imagePath) throws Exception {

    try {

        // set the http handlers
        httpClient = new DefaultHttpClient();
        localContext = new BasicHttpContext(); // why do I need this?
        postRequest = new HttpPost("http://asd.com/asd.php"); 
        //postRequest.addHeader("Content-type", "image/jpeg"); // - this didnt work

        // deal with the file
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap = BitmapFactory.decodeFile(imagePath);
        bitmap.compress(CompressFormat.JPEG, 75, byteArrayOutputStream); 
        byte[] byteData = byteArrayOutputStream.toByteArray();
        //String strData = Base64.encodeToString(data, Base64.DEFAULT); // I have no idea why Im doing this
        ByteArrayBody byteArrayBody = new ByteArrayBody(byteData, "image"); // second parameter is the name of the image (//TODO HOW DO I MAKE IT USE THE IMAGE FILENAME?)

        // send the package
        multipartEntity = MultipartEntityBuilder.create();
        multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        multipartEntity.addPart("uploaded_file", byteArrayBody);

        postRequest.setEntity(multipartEntity.build());

        // get the response. we will deal with it in onPostExecute.
        response = httpClient.execute(postRequest, localContext);
        bitmap.recycle();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

错误提示信息为:

 FATAL EXCEPTION: AsyncTask #1
 java.lang.RuntimeException: An error occured while executing doInBackground()
android.os.AsyncTask$3.done(AsyncTask.java:200)
 java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
java.util.concurrent.FutureTask.setException(FutureTask.java:125)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
java.util.concurrent.FutureTask.run(FutureTask.java:138)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
 java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.NoClassDefFoundError: org.apache.http.entity.ContentType
 org.apache.http.entity.mime.content.ByteArrayBody.<init>(ByteArrayBody.java:67)
 org.apache.http.entity.mime.content.ByteArrayBody.<init>(ByteArrayBody.java:87)

请检查您的服务器端,确定图像是以 .png 还是 .jpg 格式存在? - Piyush
5个回答

5
使用这段代码上传图像文件。
HttpClient client = new DefaultHttpClient();
HttpPost postMethod = new HttpPost("http://localhost/Upload/index.php");
File file = new File(filePath);
MultipartEntity entity = new MultipartEntity();
FileBody contentFile = new FileBody(file);
entity.addPart("userfile",contentFile);
StringBody contentString = new StringBody("This is contentString");
entity.addPart("contentString",contentString);

postMethod.setEntity(entity);
client.execute(postMethod);

而在PHP中,使用以下代码接收

$uploads_dir = '/Library/WebServer/Documents/Upload/upload/'.$_FILES['userfile']['name'];
if(is_uploaded_file($_FILES['userfile']['tmp_name'])) {
    echo $_POST["contentString"]."\n";
    echo  "File path = ".$uploads_dir;
    move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $uploads_dir);
} else {
    echo "\n Upload Error";
    echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";
    print_r($_FILES);
}

你能帮我吗?http://stackoverflow.com/questions/30132225/sending-multiple-data-to-server-in-predefined-format? - Devendra Singh
我总是遇到这样的错误:java.lang.NoClassDefFoundError... 我无法解决它... - Sirop4ik

5

我正在使用一个库,它在/libs文件夹中。错误显示我没有设置Content-type。 - Kaloyan Roussev
2
不,错误显示未找到库的一部分Content-type:原因是:java.lang.NoClassDefFoundError:org.apache.http.entity.ContentType。 - Ezrou
哦,首先很抱歉我不同意你的观点。其次,我正在使用httpmime-4.3.jar,并且它在libs文件夹中,那么我该怎么做? - Kaloyan Roussev
请前往http://hc.apache.org/downloads.cgi下载httpmime、httpclient和httpcore,然后再尝试一次。 - Ezrou
2
哇,谢谢,那帮助解决了问题。你可以编辑你的答案并添加这些信息。我接受它。 - Kaloyan Roussev

1
使用此代码:--
public class HttpMultipartUpload {
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "AaB03x87yxdkjnxvi7";

    public String upload(URL url, File file, String fileParameterName,
            HashMap<String, String> parameters) throws IOException {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream dis = null;
        FileInputStream fileInputStream = null;

        byte[] buffer;
        int maxBufferSize = 20 * 1024;
        try {
            // ------------------ CLIENT REQUEST
            fileInputStream = new FileInputStream(file);

            // open a URL connection to the Servlet
            // Open a HTTP connection to the URL
            conn = (HttpURLConnection) url.openConnection();
            // Allow Inputs
            conn.setDoInput(true);
            // Allow Outputs
            conn.setDoOutput(true);
            // Don't use a cached copy.
            conn.setUseCaches(false);
            // Use a post method.
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);

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

            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\""
                    + fileParameterName + "\"; filename=\"" + mFileName
                    + ".jpg" + "\"" + lineEnd);
            dos.writeBytes("Content-Type:image/jpg" + lineEnd);
            dos.writeBytes(lineEnd);

            // create a buffer of maximum size
            buffer = new byte[Math.min((int) file.length(), maxBufferSize)];
            int length;
            // read file and write it into form...
            while ((length = fileInputStream.read(buffer)) != -1) {
                dos.write(buffer, 0, length);
            }

            for (String name : parameters.keySet()) {
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\""
                        + name + "\"" + lineEnd);
                dos.writeBytes(lineEnd);
                dos.writeBytes(parameters.get(name));
            }

            // send multipart form data necessary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            dos.flush();
        } finally {
            if (fileInputStream != null)
                fileInputStream.close();
            if (dos != null)
                dos.close();
        }

        // ------------------ read the SERVER RESPONSE
        try {
            dis = new DataInputStream(conn.getInputStream());
            StringBuilder response = new StringBuilder();

            String line;
            while ((line = dis.readLine()) != null) {
                response.append(line).append('\n');
            }

            System.out.println("Upload file responce:"
                    + response.toString());
            return response.toString();
        } finally {
            if (dis != null)
                dis.close();
        }
    }
}

我会等待并观察是否可能仅修改我的代码使其工作,因为我不想重新开始。这对我来说是非常陌生的领域。 - Kaloyan Roussev
是的,当然可以。它能够正常工作,因为我已经使用过这段代码并且运行良好。 - Kailash Dabhi
如果我的答案解决了你的问题,请接受答案,兄弟。 - Kailash Dabhi
如果这真的能够工作,那就非常好了。但是您能否解释一下 String fileParameterName、HashMap<String, String> parameters 和 mFileName 是什么?因为我无法理解。 - Sirop4ik
现在这是旧代码了,我认为我们不应该再这样做了。我们有非常好的库,比如OkHttp、Retrofit等,所以只需使用它们会非常有益,而且你会拥有干净的代码。 - Kailash Dabhi

0

0

阅读文件http的源代码。请检查以下解决方案:

  1. 调用新的MultipartEntity:

    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, Charset.forName("UTF-8"));

  2. 添加请求头

    heads.put("Content-Type", "image/png;charset=utf-8");


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接