十一、get和post方式的请求

2019-06-20  本文已影响0人  浮生若梦OvO

一、 方式使用jdk中自带的api 实现发请求,并解析(重要):

image.png

服务器端还要做一个事儿, 要使用 这里 编码的 时候的 码表 进行解码

image.png image.png

经过以上分析, 发现 post 时 多了 两个请求头 , 并且 请求的方式 以及 参数 带过去的方式也是不一样的
a、在 客户端的代码中添加如下代码


image.png

b、在服务器端代码中 添加如下代码


image.png

二、开源框架实现发请求,并且解析(重要):

a、get方式

image.png

b、post方式

image.png

三、开源项目实现多线程下载(重点)

多线程下载的原理或步骤:

package com.itheima.download;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

/*
*  多线程 下载器 
*
*/
public class MultiThreadDownloader {

     // http://188.188.5.100:8080/test.txt

     static final String path ="http://188.188.5.100:8080/tt.exe";
     static final int threadCount=3; //下载的线程的数量

     static int runningThreadCount =3;

     public static void main(String[] args) {

          //1\. 连接 服务器, 在本地建一个同样 大小的空文件

          try {
               URL url = new URL(path);
               HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
               conn.setConnectTimeout(5000);
               conn.setRequestMethod("GET");

               //拿到 要下载的文件的长度
               int length = conn.getContentLength();

               //在本地建一个同样大小的空文件
               RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rws");
               raf.setLength(length);  // 设置一个 空文件的大小

               raf.close();

               System.out.println(length);

               //拿到 平均 每块 多大
               int blockSize = length/threadCount;

               //启动多条线程下载了
               for (int threadId = 0; threadId < threadCount; threadId++) {
                    //开始索引
                    int startIndex = threadId*blockSize;

                    //结束索引
                    int endIndex = (threadId+1)*blockSize-1;

                    //如果是最后一条线程, 那么 结束索引的 位置 是 length-1
                    if(threadId==threadCount-1){
                         endIndex=length-1;
                    }

                    new Downloader(threadId, startIndex, endIndex).start();
               }

          } catch (Exception e) {
               e.printStackTrace();
          }
     }

     public static String getFileName(String path){
          int index = path.lastIndexOf("/");
          return path.substring(index+1);
     }

     private static class Downloader extends Thread{

          private int threadId;
          private int startIndex;
          private int endIndex;
          private int currentPosition;  //默认的  实时位置 就是 开始 索引位置

          public Downloader(int threadId, int startIndex, int endIndex){
               this.threadId= threadId;
               this.startIndex= startIndex;
               this.endIndex= endIndex;
               this.currentPosition =startIndex;
          }

          @Override
          public void run() {

               //干 下载目标段的数据的事儿
               System.out.println("第 " + threadId +"号 线程, 下载 :" + startIndex+"~"+endIndex);

               //连网络, 要 目标段 的数据
               try {
                    URL url = new URL(path);
                    HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(5000);
                    conn.setRequestMethod("GET");

                    RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rws");

                    //先去判断 记录了位置的文件是否存在, 如果存在,就  是断点 续传, 否则, 就从 开始 位置下载.
                    File fll = new File(threadId+".position");
                    if(fll.exists()&&fll.length()>0){
                         //说明有 记录, 那么就 需要读取这个文件的 值,然后从这个值所在的位置 继续下载
                         BufferedReader br = new BufferedReader(new FileReader(fll));
                         String vl = br.readLine();
                         currentPosition = Integer.parseInt(vl);
                         br.close();
                         //指定要 目标段的数据
                         conn.setRequestProperty("range", "bytes="+currentPosition+"-"+endIndex);
                         raf.seek(currentPosition);

                    }else{
                         //告诉 从空文件的目标位置开始写
                         raf.seek(startIndex);
                         //从 startIndex开始

                         conn.setRequestProperty("range", "bytes="+startIndex+"-"+endIndex);
                    }

                    //要目标段的数据  -- 如何找服务器要目标段 的数据 ?
                    // 通过http的请求 头 来实现   --打开 http 协议的文档

                    // - The first 500 bytes (byte offsets 0-499, inclusive):  bytes=0-499
                    // range:bytes=0-499

                    // 如果访问 服务器, 服务器很好的处理了请求, 那么返回的状态码是 200 , 但是 注意, 这里
                    // 由于 只 找服务器 要 目标 段的数据(是整个文件的一部分的数据), 这个时候, 返回的状态码 不是 200 , 是 206 (Partial Content)
                    int code = conn.getResponseCode();
                    if(code==206){
                         System.out.println("====");

                         //获得服务器 给的那个 目标段的 流的数据, 然后 将这个目标段的数据写到 那个 空文件中去
                         InputStream in = conn.getInputStream();

                         int len=0;
                         byte[] buf= new byte[1024];
                         while((len=in.read(buf))>0){
                              raf.write(buf, 0, len);
                              currentPosition+=len;

                              //要把  currentPosition 给记录下 来 -- 写到 文件中去
                              File fl = new File(threadId+".position");
                              RandomAccessFile rf = new RandomAccessFile(fl, "rwd");
                              rf.write((currentPosition+"").getBytes());
                              rf.close();
                         }
                         raf.close();
                    }

                    //表示 那条 线程下载完成.
                    System.out.println(" 第 " + threadId +"号 线程下载结束 ");

                    //可以将 下载 过程中,生成的 用来保存 记录的文件给删除掉
                    File fl = new File(threadId+".position");

                    boolean b = fl.renameTo(new File(threadId+".position.finish"));
                    System.out.println(b+"+++++");
                    synchronized (MultiThreadDownloader.class) {
                         runningThreadCount--;

                         if(runningThreadCount<=0){
                              for (int threadId = 0; threadId < threadCount; threadId++) {

                                   //将 每个   .position.finish 给删掉
                                   File f = new File(threadId+".position.finish");
                                   f.delete();
                              }
                         }
                    }

               } catch (Exception e) {
                    e.printStackTrace();
               }

          }
     }

}
     代码:

     package com.itheima.xutils;

     import java.io.File;

     import android.app.Activity;
     import android.os.Bundle;
     import android.os.Environment;
     import android.view.View;
     import android.widget.TextView;
     import android.widget.Toast;

     import com.lidroid.xutils.HttpUtils;
     import com.lidroid.xutils.exception.HttpException;
     import com.lidroid.xutils.http.ResponseInfo;
     import com.lidroid.xutils.http.callback.RequestCallBack;

     public class MainActivity extends Activity {

     private TextView tv_start;

     private TextView tv_progress;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          tv_start = (TextView) findViewById(R.id.tv_start);
          tv_progress = (TextView) findViewById(R.id.tv_progress);
     }

     public void download(View view){
          HttpUtils http = new HttpUtils();
          String path = "http://192.168.1.254:8080/11.exe";

          http.download(path, Environment.getExternalStorageDirectory()+"/11.exe", true, new RequestCallBack<File>() {

               @Override
               public void onSuccess(ResponseInfo<File> response) {
                    Toast.makeText(MainActivity.this, "文件下载,保存在"+response.result.getPath(), 0).show();
               }

               @Override
               public void onFailure(HttpException e, String str) {
                    Toast.makeText(MainActivity.this, "文件失败", 0).show();
               }

               @Override
               public void onLoading(long total, long current, boolean isUploading) {
                    super.onLoading(total, current, isUploading);

                    tv_progress.setText(current+"/"+total);
               }

               @Override
               public void onStart() {

                    super.onStart();

                    tv_start.setText("开始下载...");
                 }
            });

        }

     }

四、开源项目实现多线程上传(重点)

public class MainActivity extends Activity {
     EditText ed_path;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          ed_path = (EditText) findViewById(R.id.ed_path);
    }

    //实现文件的上传
    public void upload(View v){
         String path = ed_path.getText().toString().trim();

         if(TextUtils.isEmpty(path)){
              Toast.makeText(this, "对不起, 路径不能为空", 0).show();
              return;
         }

         File file = new File(path);

         if(!file.exists()||file.length()<=0){
              Toast.makeText(this, "对不起,  不是有效的文件 ", 0).show();
              return;
         }

         // 使用 utils实现文件的上传
         RequestParams params = new RequestParams();
         params.addBodyParameter("file", file);

         HttpUtils utils = new HttpUtils();

         // 上传的路径
         String url = "http://188.188.5.100:8080/day11_upload/upload";
         utils.send(HttpRequest.HttpMethod.POST, url, params,new RequestCallBack<String>(){

              //成功
               @Override
               public void onSuccess(ResponseInfo responseInfo) {
                    Toast.makeText(MainActivity.this, "上传成功", 0).show();
                    System.out.println("====== 上传成功   ");
               }

               @Override
               public void onStart() {
                    System.out.println("======开始 ");
                    super.onStart();
               }

               @Override
               public void onLoading(long total, long current, boolean isUploading) {
                    // TODO Auto-generated method stub
                    System.out.println("======正在进行中  ");
                    System.out.println("======正在进行中  ");
                    super.onLoading(total, current, isUploading);
               }

               //失败
               @Override
               public void onFailure(HttpException error, String msg) {
                    System.out.println("====== 上传 失败   ");
                    Toast.makeText(MainActivity.this, "上传失败", 0).show();

               }});

    }

}
上一篇 下一篇

猜你喜欢

热点阅读