- 程序之美
若要实现上传必须要使用Http Post 请求,因为Get 请求无法传输大文件。其中http协议中采用请求head定义表单的格式,请求body中填充传输数据。
在请求头中,参数Content-Type和Content-Length,分别表示传输的类型和传输的大小。
Content-Type:multipart/form-data; boundary=+自定义的字符串
Content-Length:请求body的数据大小
请求体中数据格式的定义
Content-Disposition: form-data; name=“file”; filename=“ss.jpg”
Content-Type: application/octet-stream; charset=UTF-8
我们按照如上的方式构造结构发送就可以了。
实现如下:
public void uploadFile(final File file, final String url){
new Thread(new Runnable() {
@Override
public void run() {
String BOUNDARY = UUID.randomUUID().toString(); //边界标识 随机生成
String PREFIX = "--" , LINE_END = "rn";
String CONTENT_TYPE = "multipart/form-data"; //内容类型
try {
URL httpUrl = new URL(url);
conn = (HttpURLConnection) httpUrl.openConnection();
if (conn != null){
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
conn.setDoInput(true); //允许输入流
conn.setDoOutput(true); //允许输出流
conn.setUseCaches(false); //不允许使用缓存
conn.setRequestMethod("POST"); //请求方式
conn.setRequestProperty("Charset", "UTF-8");
//设置编码
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
if(file != null) {
outputSteam = conn.getOutputStream();
if (outputSteam != null){
dos = new DataOutputStream(outputSteam);
if (dos != null){
StringBuffer sb = new StringBuffer();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);
sb.append("Content-Disposition: form-data; name="file"; filename="" + file.getName()+""" + LINE_END);
sb.append("Content-Type: application/octet-stream; charset="+ "UTF-8" + LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());
is = new FileInputStream(file);
if (is != null){
byte[] bytes = new byte[1024];
int len = 0;
while((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
is.close();
is = null;
dos.write(LINE_END.getBytes());
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
dos.write(end_data);
dos.flush();
int res = conn.getResponseCode();
// Log.e(TAG, "response code:"+res);
if(res == 200){
Log.e(TAG, "获取响应码 200=成功");
}
}
}
}
}
}
} catch (MalformedURLException e)
{ e.printStackTrace(); }
catch (IOException e)
{ e.printStackTrace(); }
finally {
if (is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
is = null;
}
if (outputSteam != null){
try {
outputSteam.close();
} catch (IOException e) {
e.printStackTrace();
}
outputSteam = null;
}
if (dos != null){
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
dos = null;
}
if (conn != null){
conn.disconnect();
conn = null;
}
}
return;
}
}).start();
}
在此函数中,请求头的参数通过conn.setRequestProperty进行时设定,Content-Disposition和Content-Type通过dos.write的方式进行填充。
HttpUrlConnection 请求完成后 根据状态码的不同获取不同的相应体,如下:
200状态码:connection.getInputStream();
非200状态码:connection.getErrorStream();
简单的调用流程为:
String path = Environment.getExternalStorageDirectory() + "/files/OfflineUser/recording/2021-09-07/15"; File file = new File(path + "/3b8ec959-cf4b-4db4-ab9a-cc4f34868170"); String requestURL = "http://192.168.1.190:1110/upload"; uploadFile(file, requestURL);
同样在此调用过程中为了防止内存泄露和句柄泄露,同样要把请求的连接进行关闭,因为牵扯到流传输,故而流输入与输出同样需要关闭。
至此,完毕!希望对你能有说帮助!



