Golang+Android文件上传(多文件上传、附带请求参数)

前端之家收集整理的这篇文章主要介绍了Golang+Android文件上传(多文件上传、附带请求参数)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文是上一篇文章Golang+Android(使用HttpURLConnection)实现文件上传升级版,实现多文件上传功能,并且附带http请求参数。

客户端代码

    /**
     * 使用HttpURLConnection通过POST方式提交请求,并上传文件。
     *
     * @param actionUrl  访问的url
     * @param textParams 文本类型的POST参数(key:value)
     * @param filePaths  文件路径的集合
     * @return 服务器返回的数据,出现异常时返回 null
     */
    public static String postWithFiles(String actionUrl,Map<String,String> textParams,List<String> filePaths) {
        try {
            final String BOUNDARY = UUID.randomUUID().toString();
            final String PREFIX = "--";
            final String LINE_END = "\r\n";

            final String MULTIPART_FROM_DATA = "multipart/form-data";
            final String CHARSET = "UTF-8";

            URL uri = new URL(actionUrl);
            HttpURLConnection conn = (HttpURLConnection) uri.openConnection();

            //缓存大小
            conn.setChunkedStreamingMode(1024 * 64);
            //超时
            conn.setReadTimeout(5 * 1000);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false); 
            conn.setRequestMethod("POST");

            conn.setRequestProperty("connection","keep-alive");
            conn.setRequestProperty("Charset","UTF-8");
            conn.setRequestProperty("Content-Type",MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);

            // 拼接文本类型的参数
            StringBuilder textSb = new StringBuilder();
            if (textParams != null) {
                for (Map.Entry<String,String> entry : textParams.entrySet()) {
                    textSb.append(PREFIX).append(BOUNDARY).append(LINE_END);
                    textSb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINE_END);
                    textSb.append("Content-Type: text/plain; charset=" + CHARSET + LINE_END);
                    textSb.append("Content-Transfer-Encoding: 8bit" + LINE_END);
                    textSb.append(LINE_END);
                    textSb.append(entry.getValue());
                    textSb.append(LINE_END);
                }
            }

            DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
            outStream.write(textSb.toString().getBytes());

            //参数POST方式
            //outStream.write("userId=1&cityId=26".getBytes());

            // 发送文件数据
            if (filePaths != null) {
                for (String file : filePaths) {
                    StringBuilder fileSb = new StringBuilder();
                    fileSb.append(PREFIX).append(BOUNDARY).append(LINE_END);
                    fileSb.append("Content-Disposition: form-data; name=\"file\"; filename=\"" +
                            file.substring(file.lastIndexOf("/") + 1) + "\"" + LINE_END);
                    fileSb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
                    fileSb.append(LINE_END);
                    outStream.write(fileSb.toString().getBytes());

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

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

            // 请求结束标志
            outStream.write((PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes());
            outStream.flush();

            // 得到响应码
            int responseCode = conn.getResponseCode();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),CHARSET));

            StringBuilder resultSb = null;
            String line;
            if (responseCode == 200) {
                resultSb = new StringBuilder();
                while ((line = br.readLine()) != null) {
                    resultSb.append(line).append("\n");
                }
            }

            br.close();
            outStream.close();
            conn.disconnect();

            return resultSb == null ? null : resultSb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
服务器端代码
//客户端上传多个文件,并带有请求参数
func handleUploadFile(w http.ResponseWriter,r *http.Request) {
	fmt.Println("client:",r.RemoteAddr,"method:",r.Method)

	r.ParseForm()
	r.ParseMultipartForm(32 << 20) //最大内存为32M

	//读取参数
	userId := r.FormValue("userId")
	cityId := r.FormValue("cityId")
	log.Println("userId=",userId,"cityId=",cityId)

	mp := r.MultipartForm
	if mp == nil {
		log.Println("not MultipartForm.")
		w.Write(([]byte)("不是MultipartForm格式"))
		return
	}

	fileHeaders,findFile := mp.File["file"]
	if !findFile || len(fileHeaders) == 0 {
		log.Println("file count == 0.")
		w.Write(([]byte)("没有上传文件"))
		return
	}

	for _,v := range fileHeaders {
		fileName := v.Filename
		file,err := v.Open()
		checkErrorV2(err,"Open file error."+fileName)
		defer file.Close()

		outputFilePath := "/home/admin/桌面/" + fileName
		writer,err := os.OpenFile(outputFilePath,os.O_WRONLY|os.O_CREATE,0666)
		checkErrorV2(err,"Open local file error")
		io.Copy(writer,file)
	}

	msg := fmt.Sprintf("成功上传了%d个文件",len(fileHeaders))
	w.Write(([]byte)(msg))
}
注:checkErrorV2是一个简单的检查错误函数 原文链接:https://www.f2er.com/go/190462.html

猜你在找的Go相关文章