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>