HTTP
一. http协议介绍:
二.请求协议和响应协议
请求协议:
①请求首行:
②请求头信息:客户端告诉服务器我这边的信息
③空行
④请求体:get请求是没有请求体的
响应协议:
①响应首行:HTTP/1.1 200 OK
②响应头信息:Content-Length 服务器返回数据的总大小
③空行
④响应体:服务器返回的数据
七.代码:文件的上传和下载(重点)
package com.example.post;
import android.Manifest;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class MainActivity extends AppCompatActivity {
private Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},100);
btn1 = (Button) findViewById(R.id.btn1);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode==100&&grantResults[0] == PackageManager.PERMISSION_GRANTED){
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run() {
super.run();
upLoad();
}
}.start();
}
});
}
}
private void upLoad() {
String start="--";
String bound="****"+System.currentTimeMillis();
String end="\r\n";
//mnt/she/sdcard/e...0/http.text
String filename= Environment.getExternalStorageDirectory()+"/http.txt";
try {
URL url = new URL("http://172.20.10.2:8080/test/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Content-Type","multipart/form-data"+":boundary="+bound);
DataOutputStream outputStream=new DataOutputStream(connection.getOutputStream());
// OutputStream outputStream = connection.getOutputStream();
/**
* 設置請求頭請求體
* */
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(start+bound+end);
stringBuffer.append("Content-Disposition:form-data:name=\"file\":filename=\""+filename+"\""+end);
stringBuffer.append("Content-Type:multipart/form-data"+end);
stringBuffer.append(end);
outputStream.write(stringBuffer.toString().getBytes());
FileInputStream fileInputStream = new FileInputStream(new File(filename));
int len=0;
byte[] bytes=new byte[1024];
while ((len=fileInputStream.read(bytes))!=-1){
outputStream.write(new String(bytes,0,len).getBytes());
}
outputStream.write(end.getBytes());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码:文件的上传activity代码
package com.example.day001;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class Main3Activity extends AppCompatActivity {
private Button buttonid;
private static final String TAG = "Main3Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
buttonid = (Button) findViewById(R.id.buttonid);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},101);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode==101&&grantResults[0]== PackageManager.PERMISSION_GRANTED){
click(buttonid);
}
}
//上传
private void upload() {
String start="--";//起始
String boundary="*****";//分割
String end="\r\n";//结束
String filename = "/mnt/sdcard/uri.txt";
Log.i(TAG, "upload: "+Environment.getExternalStorageDirectory());
try {
URL url = new URL("http://169.254.152.180/test/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
//设置请求头
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("Content-Type","multipart/form-data;boundary"+boundary);
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
OutputStream outputStream = connection.getOutputStream();
//设置请求头 请求体
StringBuffer sb = new StringBuffer();
sb.append(start+boundary+end);
sb.append("Content-Disposition:form-data;name=\"file\";filename=\""+filename+"\""+end);//文件地址
sb.append("Content-Type:multipart/form-data/"+end);
sb.append(end);//空行
outputStream.write(sb.toString().getBytes());
//写内容
FileInputStream fileInputStream = new FileInputStream(new File(filename));//读那个文件
int len=0;
byte[] b=new byte[1024];
while ((len=fileInputStream.read(b))!=-1){
outputStream.write(new String(b,0,len).getBytes());
}
fileInputStream.close();
//
outputStream.write(end.getBytes());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void click(View view) {
new Thread(){
@Override
public void run() {
super.run();
upload();
}
}.start();
}
}
上传的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main3Activity">
<Button
android:id="@+id/buttonid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上传"
android:onClick="click"
/>
</LinearLayout>
文件的下载
下载成功后打开的效果
Activity中的代码
package com.example.day001;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class Main4Activity extends AppCompatActivity {
private ProgressBar pro;
private Button start;
private Button stop;
private int end=0;//结束
private static final String TAG = "Main4Activity";
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==100){
Toast.makeText(Main4Activity.this, "下载完毕", Toast.LENGTH_SHORT).show();
}else if (msg.what==101){
pro.setMax(msg.arg1);//设置进度条最大值的
Log.i(TAG, "handleMessage: "+msg.arg1);
}else if (msg.what==102){
pro.setProgress(msg.arg1);//更新进度
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
pro = (ProgressBar) findViewById(R.id.pro);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run() {
super.run();
getLength("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4");
download("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4");
}
}.start();
}
});
}
//获得文件总长度
public void getLength(String url){
try {
URL url1 = new URL(url);
HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
if (connection.getResponseCode()==200){
end = connection.getContentLength();//这个是文件最大值
//是为了给进度条来设置
Message message = new Message();
message.what=101;
message.arg1=end;
handler.sendMessage(message);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//断点下载-更新进度-分批保存
public void download(String url){
int start=0;//开始
int sum=0;//累积长度
try {
URL url1 = new URL(url);
//真实长度是len,1024
String filepath="/mnt/sdcard"+"/a1705";
Log.i(TAG, "download: "+filepath);
//Fileoutputstream不能分批次写入文件
RandomAccessFile file=new RandomAccessFile(filepath,"rw");
file.seek(start);//0开始
HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Range","bytes="+start+"-"+end);//0-1024下载的范围
if (connection.getResponseCode()==206){//断点下载的正常ok响应码206 普通是200
InputStream inputStream=connection.getInputStream();
int len=0;
byte[] b=new byte[2048];
while ((len=inputStream.read(b))!=-1){
file.write(b,0,len);//写文件内容
sum+=len;//记录是否完成更新进度
Message message = new Message();
message.what=102;
message.arg1=sum;
handler.sendMessage(message);
if (sum==end){
handler.sendEmptyMessage(100);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件下载的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Main4Activity">
<ProgressBar
android:id="@+id/pro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
/>
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂停"
/>
</LinearLayout>