android+django交互数据(同时上传图片与文字)
16lz
2021-01-26
继上一个android与django交互之后,发现以前上传图片的逻辑有点不好,只能上传单个图片,不能附加别的文本类的消息,因此,再上一个基类的基础上,做了以下修改:
- 先附上原来的基类(一点都没变动):
package com.example.xieyipeng.demo.bean;import android.util.Log;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLConnection;public class GetPostUtil { private static String TAG = "GetPostUtil"; /** * 发送post请求 * * @param url 发送请求的 URL * @param data 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return json数据包 */ public static String sendPostRequest(String url, String data) { PrintWriter printWriter = null; StringBuilder result = null; BufferedReader bufferedReader = null; try { URL realUrl = new URL(url); URLConnection connection = realUrl.openConnection(); // TODO: 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // TODO: 发送POST请求必须设置如下两行 connection.setDoOutput(true); connection.setDoInput(true); // TODO: 获取URLConnection对象对应的输出流 printWriter = new PrintWriter(connection.getOutputStream()); // TODO: 发送请求参数 // TODO: flush输出流的缓冲 printWriter.print(data); printWriter.flush(); Log.e(TAG, "sendPostRequest: Post Request Successful"); // TODO: 定义BufferedReader输入流来读取URL的响应 result = new StringBuilder(); bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = bufferedReader.readLine()) != null) { result.append(line); } } catch (Exception e) { Log.e(TAG, "sendPostRequest: " + e.getMessage()); e.printStackTrace(); } finally { try { if (printWriter != null) { printWriter.close(); } if (bufferedReader != null) { bufferedReader.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result.toString(); } /** * 发送get请求 * * @param url eg: http://10.0.2.2:8000/get_test/ * @return 返回服务器的响应 */ public static String sendGetRequest(String url) { HttpURLConnection connection = null; BufferedReader bufferedReader = null; StringBuilder result = null; try { URL realUrl = new URL(url); //打开链接 connection = (HttpURLConnection) realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setRequestMethod("GET"); if (HttpURLConnection.HTTP_OK == connection.getResponseCode()) { //若链接正常(ResponseCode == 200) Log.e(TAG, "sendGetRequest: Get Request Successful"); InputStream inputStream = connection.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); result = new StringBuilder(); String line; while ((line = bufferedReader.readLine()) != null) { result.append(line); } } else { Log.e(TAG, "sendGetRequest: Get Request Failed"); } } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "sendGetRequest: error: " + e.getMessage() + " " + e.toString()); } finally { if (connection != null) { connection.disconnect(); } if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } return result.toString(); } /** * 发送post请求上传图片 * * @param actionUrl url * @param inputStream 图片的流 * @param fileName name * @return 服务器响应 */ public static String upLoadFiles(String actionUrl, InputStream inputStream, String fileName) { StringBuffer result = new StringBuffer(); OutputStream outputStream = null; DataInputStream dataInputStream = null; try { final String newLine = "\r\n"; // 换行符 final String boundaryPrefix = "--"; //边界前缀 final String boundary = String.format("=========%s", System.currentTimeMillis()); // 定义数据分隔线 // 连接 URL url = new URL(actionUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // 发送POST请求必须设置如下两行 connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); // 设置请求头参数 connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("Charsert", "UTF-8"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); // 获取输出流 outputStream = new DataOutputStream(connection.getOutputStream()); // 文件参数 // 参数头设置完以后需要两个换行,然后才是参数内容 outputStream.write(string_text.getBytes()); String stringBuilder = boundaryPrefix + boundary + newLine + "Content-Disposition: form-data;name=\"file\";filename=\"" + fileName + "\"" + newLine + "Content-Type:application/octet-stream" + newLine + newLine; // 将参数头的数据写入到输出流中 outputStream.write(stringBuilder.getBytes()); // 数据输入流,用于读取文件数据 dataInputStream = new DataInputStream(inputStream); byte[] bufferOut = new byte[1024]; int bytes = 0; // 每次读1KB数据,并且将文件数据写入到输出流中 while ((bytes = dataInputStream.read(bufferOut)) != -1) { outputStream.write(bufferOut, 0, bytes); } // 最后添加换行 outputStream.write(newLine.getBytes()); //关闭流 inputStream.close(); dataInputStream.close(); // 定义最后数据分隔线,即--加上boundary再加上--。 byte[] end_data = (newLine + boundaryPrefix + boundary + boundaryPrefix + newLine).getBytes(); // 写上结尾标识 outputStream.write(end_data); Log.e(TAG, "upLoadFiles: 1" ); outputStream.flush(); outputStream.close(); // 定义BufferedReader输入流来读取服务器的响应 BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = reader.readLine()) != null) { Log.e(TAG, "upLoadFiles: "+line ); result.append(line); } Log.e(TAG, "upLoadFiles: 响应: " + result.toString()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "uploadFiles: " + e.getMessage()+" "+e.toString()); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "upLoadFiles: " + e.getMessage()); } } if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { Log.e(TAG, "upLoadFiles: " + e.getMessage()); e.printStackTrace(); } } if (dataInputStream != null) { try { dataInputStream.close(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "upLoadFiles: " + e.getMessage()); } } } return result.toString(); }}
- 之后,在这位老哥的文章的提点下,决定搞明白http请求的报头,(左边一列是对之前请求的总结,右边的是对老哥代码的总结,基本算是理清http请求的报头吧):
[外链图片转存失败(img-94YGGtE8-1567394263912)(https://raw.githubusercontent.com/xieyipeng/MarkdownPic/master/note.jpg)]
理解完代码之后,肯定要贴出重新写的请求代码啦(持续更新中…):
/** * TODO: 一定确保inputStreams数组大小与fileNames数组大小一致 * * @param actionUrl url * @param map 上传数据的键值对 * @param inputStreams 上传图片的流数组 * @param fileNames 上传图片的文件名数组 * @return 服务器应答 */ public static String upLoadFiles(String actionUrl, Map<String, String> map, InputStream[] inputStreams, String[] fileNames) { StringBuffer result = new StringBuffer(); OutputStream outputStream = null; DataInputStream dataInputStream = null; StringBuilder dataBuilder; try { final String newLine = "\r\n"; // 换行符 final String boundaryPrefix = "--"; //边界前缀 final String boundary = String.format("=========%s", System.currentTimeMillis()); // 定义数据分隔线 // 连接 URL url = new URL(actionUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // 发送POST请求必须设置如下两行 connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); // 设置请求头参数 connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("Charsert", "UTF-8"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); // 获取输出流 outputStream = new DataOutputStream(connection.getOutputStream()); // 文件参数 // 参数头设置完以后需要两个换行,然后才是参数内容 // TODO: 先发送map里面的键值对 dataBuilder = new StringBuilder(); for (Map.Entry<String, String> var : map.entrySet()) { String temp = boundaryPrefix + boundary + newLine + "Content-Disposition: form-data;name=\"" + var.getKey() + "\"" + newLine + newLine + var.getValue() + newLine; dataBuilder.append(temp); } outputStream.write(dataBuilder.toString().getBytes()); // TODO: 后发送流数组里面的键值对 if (inputStreams != null) { if (inputStreams.length == fileNames.length) { for (int i = 0; i < inputStreams.length; i++) { Log.e(TAG, "upLoadFiles: 上传文件 - " + i); String temp = boundaryPrefix + boundary + newLine + "Content-Disposition: form-data;name=\"file\";filename=\"" + fileNames[i] + "\"" + newLine + "Content-Type:application/octet-stream" + newLine + newLine; // 将参数头的数据写入到输出流中 outputStream.write(temp.getBytes()); // 数据输入流,用于读取文件数据 if (inputStreams[i] != null) { dataInputStream = new DataInputStream(inputStreams[i]); byte[] bufferOut = new byte[1024]; int bytes = 0; // 每次读1KB数据,并且将文件数据写入到输出流中 while ((bytes = dataInputStream.read(bufferOut)) != -1) { Log.e(TAG, "upLoadFiles: " + Arrays.toString(bufferOut)); outputStream.write(bufferOut, 0, bytes); } // 最后添加换行 outputStream.write(newLine.getBytes()); // 关闭流 inputStreams[i].close(); } } } } if (dataInputStream != null) { dataInputStream.close(); } // 定义最后数据分隔线,即--加上boundary再加上--。 byte[] end_data = ( boundaryPrefix + boundary + boundaryPrefix + newLine).getBytes(); // 写上结尾标识 outputStream.write(end_data); outputStream.flush(); outputStream.close(); // 定义BufferedReader输入流来读取服务器的响应 BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = reader.readLine()) != null) { result.append(line); } Log.e(TAG, "upLoadFiles: 上传结果: " + result.toString()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "uploadFiles: message: " + e.getMessage() + " toString: " + e.toString()); } finally { if (inputStreams != null) { for (InputStream inputStream : inputStreams) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "upLoadFiles: inputStream: " + e.getMessage()); } } } if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { Log.e(TAG, "upLoadFiles: outputStream: " + e.getMessage()); e.printStackTrace(); } } if (dataInputStream != null) { try { dataInputStream.close(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "upLoadFiles: dataInputStream: " + e.getMessage()); } } } return result.toString(); }
- 最后举一个参数传递的例子:
// map Map<String, String> map = new HashMap<>(); map.put("username", MainActivity.userName); map.put("context", context); // stream && file_name InputStream[] inputStreams = null; String[] fileNames = null; if (inputStream != null) { inputStreams = new InputStream[N]; inputStreams[0] = inputStream; Date date = new Date(); @SuppressLint("SimpleDateFormat") SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss"); String time = format0.format(date.getTime());//这个就是把时间戳经过处理得到期望格式的时间 fileNames = new String[1]; fileNames[0] = "Dynamic-" + time; } // 请求 res = GetPostUtil.upLoadFiles(add_dynamic, map, inputStreams, fileNames);
更多相关文章
- 一句话锁定MySQL数据占用元凶
- 【android】数据库升级完整解决方案
- android mediaPlayer error (-38,0)
- Android入门:用HttpClient模拟HTTP的GET和POST请求
- XDebuggable&mprop代码分析
- Realm for Android(安卓)简单使用
- 蓝牙socket读取数据需读多次才读全
- Android车辆运动轨迹平滑移动(高仿滴滴打车)最佳实践
- Android中contentProvider的用途