Code Bye

Android http post 上传图片不成功,求大神们指点

问题;
  客户端:Android,服务端:php
  我在 Android客户端写了几种上传文件的方法,都没上传成功,
   (1) 基于Android HttpClient的 Post方法

  

 /**
     * 用Post模式访问http,包括附件上传
     * @param url URL
     * @param nameValuePairs 参数信息
     * @return  返回的字符串
     */
    public static String post(String url, List<NameValuePair> nameValuePairs) {
        String strResult = "";
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);

        try {

            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
            for(int index = 0; index < nameValuePairs.size(); index++) {
                if(nameValuePairs.get(index).getName().equalsIgnoreCase("upload")) {
                    // If the key equals to "upload", we use FileBody to transfer the data
                    GiantLog.d("httpServerAccess","nameValuePair:name" + nameValuePairs.get(index).getName()  + nameValuePairs.get(index).getValue());
                    entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File (nameValuePairs.get(index).getValue())));
                } else {
                    // Normal string data
                    entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue()));
                }
            }

            httpPost.setEntity(entity);

            HttpResponse httpResponse = httpClient.execute(httpPost, localContext);
            if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 取出响应字符
               strResult = EntityUtils.toString(httpResponse.getEntity(),HTTP.UTF_8);
//                byte[] bytesResult = EntityUtils.toByteArray(httpResponse
//                        .getEntity());
//                if (bytesResult != null) {
//                    strResult = new String(bytesResult, "utf-8");
//                }

            }
        } catch (IOException e) {
            e.printStackTrace();
            strResult = "";

        }

        return  strResult;
    }

(2) 基于HttpUrlConnection,需要拼接Http头

package com.giant.android.utils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;


/**
 * 文件名称:UploadImage.java
 * 创建日期:2012-12-28
 * 实现图片文件上传
 */
public class UploadImage {
    String multipart_form_data = "multipart/form-data";
    String twoHyphens = "--";
    String boundary = "****************fD4fH3gL0hK7aI6";	// 数据分隔符
    String lineEnd = System.getProperty("line.separator");	// The value is "\r\n" in Windows.

    private final static String LINEND = "\r\n";
    private final static String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
    private final static String PREFIX = "--";
    private  static  final String TAG = "UploadImage";

    /*
      * 上传图片内容,格式参考HTTP 协议格式。
      * 格式如下所示:
      * --****************fD4fH3hK7aI6
      * Content-Disposition: form-data; name="upload_file"; filename="apple.jpg"
      * Content-Type: image/jpeg
      *
      * 这儿是文件的内容,二进制流的形式
      */
    private void addImageContent(Image[] files, DataOutputStream output) {
        for(Image file : files) {
            StringBuilder split = new StringBuilder();
            split.append(twoHyphens + boundary + lineEnd);
            split.append("Content-Disposition: form-data; name="" + file.getFormName() + ""; filename="" + file.getFileName() + """ + lineEnd);
            split.append("Content-Type: " + "image/jpg" + lineEnd);
            split.append(lineEnd);
            try {
                // 发送图片数据
                output.writeBytes(split.toString());
                GiantLog.d(TAG,"image formdata:" + split.toString() );
                output.write(file.getData(), 0, file.getData().length);
                GiantLog.d(TAG,"image data length:" +  file.getData().length );
                output.writeBytes(lineEnd);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /*
      * 构建表单字段内容,格式请参考HTTP 协议格式(用FireBug可以抓取到相关数据)。(以便上传表单相对应的参数值)
      * 格式如下所示:
      * --****************fD4fH3hK7aI6
      * Content-Disposition: form-data; name="action"
      * // 一空行,必须有
      * upload
      */
    private void addFormField(Map<String,String> params, DataOutputStream output) {
        StringBuilder sb = new StringBuilder();
        for(Map.Entry<String,String> entry : params.entrySet()) {
            sb.append(twoHyphens + boundary + lineEnd);
            sb.append("Content-Disposition: form-data; name="" + entry.getKey() + """ + lineEnd);
            sb.append(lineEnd);
            sb.append(entry.getValue() + lineEnd);
        }
        try {
            output.writeBytes(sb.toString());// 发送表单字段数据
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 封装表单文本数据
     * @param paramText
     * @return
     */
    private String bulidFormText(Map<String,String> paramText){
        if(paramText==null || paramText.isEmpty()) return "";
        StringBuffer sb = new StringBuffer("");
        for(Map.Entry<String,String> entry : paramText.entrySet()){
            sb.append(PREFIX).append(BOUNDARY).append(LINEND);
            sb.append("Content-Disposition:form-data;name=""
                    + entry.getKey() + """ + LINEND);
//			sb.append("Content-Type:text/plain;charset=" + CHARSET + LINEND);
            sb.append(LINEND);
            sb.append(entry.getValue());
            sb.append(LINEND);
        }
        return sb.toString();
    }


    /**
     * 直接通过 HTTP 协议提交数据到服务器,实现表单提交功能。
     * @param actionUrl 上传路径
     * @param params 请求参数key为参数名,value为参数值
     * @param files 上传文件信息
     * @return 返回请求结果
     */
    public String post(String actionUrl, Map<String,String> params, Image[] files) {
        HttpURLConnection conn = null;
        DataOutputStream dataOutputStream = null;
        BufferedReader input = null;
        try {
            URL url = new URL(actionUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(120000);
            conn.setDoInput(true);		// 允许输入
            conn.setDoOutput(true);		// 允许输出
            conn.setUseCaches(false);	// 不使用Cache
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("Content-Type", multipart_form_data + "; boundary=" + boundary);

            conn.connect();
            dataOutputStream = new DataOutputStream(conn.getOutputStream());

            addImageContent(files, dataOutputStream);	// 添加图片内容

            addFormField(params, dataOutputStream);	// 添加表单字段内容

            dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);// 数据结束标志
            dataOutputStream.flush();
//			output.close();

            int code = conn.getResponseCode();
            if(code != 200) {
                throw new RuntimeException("请求‘" + actionUrl +"’失败!");
            }

            input = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String oneLine;
            while((oneLine = input.readLine()) != null) {
                response.append(oneLine + lineEnd);
            }
//			input.close();

            return response.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // 统一释放资源
            try {
                if(dataOutputStream != null) {
                    dataOutputStream.close();
                }
                if(input != null) {
                    input.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            if(conn != null) {
                conn.disconnect();
            }
        }
    }



    public static void main(String[] args) {
        try {
            String response = "";

            BufferedReader in = new BufferedReader(new FileReader("config/actionUrl.properties"));
            String actionUrl = in.readLine();

            // 读取表单对应的字段名称及其值
            Properties formDataParams = new Properties();
            formDataParams.load(new FileInputStream(new File("config/formDataParams.properties")));
            Set<Map.Entry<Object,Object>> params = formDataParams.entrySet();

            // 读取图片所对应的表单字段名称及图片路径
            Properties imageParams = new Properties();
            imageParams.load(new FileInputStream(new File("config/imageParams.properties")));
            Set<Map.Entry<Object,Object>> images = imageParams.entrySet();
            Image[] files = new Image[images.size()];
            int i = 0;
            for(Map.Entry<Object,Object> image : images) {
                Image file = new Image(image.getValue().toString(), image.getKey().toString());
                files[i++] = file;
            }

//			Image file = new Image("images/apple.jpg", "upload_file");
//			Image[] files = new Image[0];
//			files[0] = file;


            //	response = new UploadImage().post(actionUrl, params, files);

            System.out.println("返回结果:" + response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

10分
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
去掉参数:HttpMultipartMode.BROWSER_COMPATIBLE 试试。我以前也碰到这样的问题过。

10分
建议压缩下。。。。

20分
public static String newPost(String actionUrl, Map<String, String> params,String imagepath) {
		String code = "0";
		Log.i("http", actionUrl);
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, 1000*30);
		HttpConnectionParams.setSoTimeout(httpParameters, 1000*30);
		HttpConnectionParams.setTcpNoDelay(httpParameters, true);

		HttpClient httpclient = new DefaultHttpClient(httpParameters);

		HttpPost httppost = new HttpPost(actionUrl);
		MultipartEntity mpEntity = new MultipartEntity();
		try {
			File imageFile = new File(imagepath);
			if(!imageFile.exists()) {
				Log.i("http", "999");
				code = "999";
			}
			for (Map.Entry<String, String> entry : params.entrySet()) {
				   String key = entry.getKey().toString();
				   String value = entry.getValue().toString();
				   Log.i("Http","KEY:" + key + ",Value:" + value );
				   mpEntity.addPart(key, new StringBody(value));
				  }
			FileBody file = new FileBody(imageFile);
			mpEntity.addPart("name", file);
			httppost.setEntity(mpEntity);
			HttpResponse response = httpclient.execute(httppost);
			if (response.getStatusLine().getStatusCode() == 200) {
				code = EntityUtils.toString(response.getEntity());  
                System.out.println("result:" + code);  
				Log.i("http", code);

			}
		} catch (Exception e) {
			return code;
		}
		return code;
	}
这个是我昨天刚写的,可用。

需要用到2个jar包,httpmime-4.0.jar,apache-mime4j-0.6.jar
还有一种是

public static String post(String actionUrl, Map<String, String> params,
			Map<String, File> files) throws IOException {
		StringBuilder sb2 = new StringBuilder();
		String BOUNDARY = java.util.UUID.randomUUID().toString();
		String PREFIX = "--", LINEND = "\r\n";
		String MULTIPART_FROM_DATA = "multipart/form-data";
		String CHARSET = "UTF-8";

		URL uri = new URL(actionUrl);
		HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
		conn.setReadTimeout(5 * 1000);
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		conn.setRequestMethod("POST");
		conn.setRequestProperty("connection", "keep-alive");
		conn.setRequestProperty("Charsert", "UTF-8");
		conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
				+ ";boundary=" + BOUNDARY);

		StringBuilder sb = new StringBuilder();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			sb.append(PREFIX);
			sb.append(BOUNDARY);
			sb.append(LINEND);
			sb.append("Content-Disposition: form-data; name=""
					+ entry.getKey() + """ + LINEND);
			sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
			sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
			sb.append(LINEND);
			sb.append(entry.getValue());
			sb.append(LINEND);
		}

		DataOutputStream outStream = new DataOutputStream(
				conn.getOutputStream());
		outStream.write(sb.toString().getBytes());
		if (files != null) {
			// int i = 0;
			for (Map.Entry<String, File> file : files.entrySet()) {
				StringBuilder sb1 = new StringBuilder();
				sb1.append(PREFIX);
				sb1.append(BOUNDARY);
				sb1.append(LINEND);
				// sb1.append("Content-Disposition: form-data; name="file"+(i++)+""; filename=""+file.getKey()+"""+LINEND);
				sb1.append("Content-Disposition: form-data; name="userupfile"; filename=""
						+ file.getKey() + """ + LINEND);
				sb1.append("Content-Type: application/octet-stream; charset="
						+ CHARSET + LINEND);
				sb1.append(LINEND);
				outStream.write(sb1.toString().getBytes());

				InputStream is = new FileInputStream(file.getValue());
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = is.read(buffer)) != -1) {
					outStream.write(buffer, 0, len);
				}

				is.close();
				outStream.write(LINEND.getBytes());
			}
		}

		byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
		outStream.write(end_data);
		outStream.flush();

		int res = conn.getResponseCode();
		InputStream in = null;
		if (res == 200) {
			in = conn.getInputStream();
			int ch;

			while ((ch = in.read()) != -1) {
				sb2.append((char) ch);
			}
			Log.i("CAMERA", sb2.toString());
		}

		return in == null ? null : sb2.toString();
	}

希望对你有用

谢谢各位的认真回复,问题已经解决,代码没问题,是调用的时候传的有一个参数是Json格式的参数,这个传的格式和服务器不符合,所以一直不成功!

你好!可以教教我这个怎么做吗?谢谢。加qq交流382867392
那个Image类是在哪里的?
楼主好人一声平安 T T
那个Image类是在哪里的? 可以实现多图片上传吗
Android https Request(加密通道传参数)

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Android http post 上传图片不成功,求大神们指点