Android的网络请求方式总结以及文件上传方式

本文导读
  1. 使用URL访问网络资源:下载图片
  2. 使用URLConnection进行网络请求:GET&POST
  3. 使用HttpURLConnection进行网络请求:GET&POST
  4. OKHTTP进行网络请求:GET&POST(同步和异步)
  5. OKHTTP进行文件上传。


使用URL访问网络资源
  • URL对象代表统一资源定位器,指向互联网资源的指针,由协议名,主机,端口和资源组成。
  • URI代表统一资源标识符,不能用于定位资源,唯一的作用就是解析。
  • URL则包含一个可打开该资源书入输入流,因此可以说URL是URI的特例。



URL实现图片下载
private Bitmap bitmap;
    Handler handler = new Handler()
    { @Override
    public void handleMessage(Message msg) {
        if (msg.what == 0x123) {
        //使用ImageView显示图片
            ivUrl.setImageBitmap(bitmap);
        }
    }
    };
    new Thread() {
        @Override
        public void run() {
            try {
                URL url = new URL("网络地址");//URl对象,指向本地服务器的一张图片
         InputStream is = url.openStream();//打开输入流
         bitmap = BitmapFactory.decodeStream(is);//解析成bitmap对象

       handler.sendEmptyMessage(0x123);//handler机制UI显示图片
       OutputStream os = openFileOutput("demon.png", MODE_PRIVATE);//打开一个文件对应的输入流
         byte[] bytes = new byte[1024];
  int has;    
       while ((has = is.read(bytes)) > 0) {
      os.write(bytes, 0, has);//将URL对应的图片下载到本地
        }
   is.close();//关闭流
      os.close();//关闭流
  } catch (Exception e) {
    e.printStackTrace();
  }  }}.start();


private Bitmap bitmap;Handler handler = new Handler() { @Override public void handleMessage(Message msg) {   if (msg.what == 0x123) {               //使用ImageView显示图片               ivUrl.setImageBitmap(bitmap);            }         }      };      new Thread() {       @Override       public void run() {         try {           URL url = new URL("网络地址");//URl对象,指向本地服务器的一张图片           InputStream is = url.openStream();//打开输入流           bitmap = BitmapFactory.decodeStream(is);//解析成bitmap对象           handler.sendEmptyMessage(0x123);//handler机制UI显示图片           OutputStream os = openFileOutput("demon.png", MODE_PRIVATE);//打开一个文件对应的输入流           byte[] bytes = new byte[1024];           int has;           while ((has = is.read(bytes)) > 0) {             os.write(bytes, 0, has);//将URL对应的图片下载到本地          }          is.close();//关闭流          os.close();//关闭流       } catch (Exception e) {        e.printStackTrace();     }  }}.start();



使用URLConnection进行网络请求
URL的openConnection返回一个URLConnection对象,表示与该URL建议通信连接。通过该对象,可以发送请求,读取资源。
创建URL连接,发生请求,读取资源步骤如下:
  1. 使用openConnection创建一个URLConnection对象
  2. 设置URLConnection的参数和普通请求属性
  3. GET请求,使用connect方法建立连接即可;POST请求,则需要获取URLConnection实例的输出流发送请求参数
  4. 访问资源的输入流读取数据
PS:必须先使用输出流发送请求参数,再使用输入流获取数据
public class GetPostUrl {
    public static GetPostUrl getPost = new GetPostUrl();//单例

    public static GetPostUrl getGetPost() {
        return getPost;
    }

    /**
     * 发送get请求
     *
     * @param url
     * @return
     */
    public static String get(final String url) {
        final StringBuilder sb = new StringBuilder();
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public String call() throws Exception {
                BufferedReader br = null;
                InputStreamReader isr = null;
                URLConnection conn;
                try {
                    URL geturl = new URL(url);
                    conn = geturl.openConnection();//创建连接
                    conn.connect();//get连接
                    InputStreamReader isr = new InputStreamReader(conn.getInputStream());//输入流
                    br = new BufferedReader(isr);
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        sb.append(line);//获取输入流数据
                    }
                    System.out.println(sb.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {//执行流的关闭
                    if (br != null) {
                        try {
                            if (br != null) {
                                br.close();
                            }
                            if (isr != null) {
                                isr.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } }}
                return sb.toString();
            }
        });
        new Thread(task).start();
        String s = null;
        try {
            s = task.get();//异步获取返回值
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
    /**
     * POST请求
     *
     * @param url url
     * @param map 请求参数的map集合形式
     * @return
     */
    public static String post(final String url, final Map map) {
        final StringBuilder sb = new StringBuilder();
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public String call() throws Exception {
                DataOutputStream out = null;
                BufferedReader br = null;
                URLConnection conn;
                URL posturl = new URL(url);
                try {
                    conn = posturl.openConnection();//创建连接
                    conn.setDoInput(true);//post请求必须设置
                    conn.setDoOutput(true);//post请求必须设置
                    out = new DataOutputStream(conn
                            .getOutputStream());//输出流
                    StringBuilder request = new StringBuilder();
                    for (String key : map.keySet()) {
                        request.append(key + "=" + URLEncoder.encode(map.get(key), "UTF-8") + "&");
                    }//连接请求参数
                    out.writeBytes(request.toString());//输出流写入请求参数
                    out.flush();
                    out.close();
                    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));//获取输入流
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line);
                    }
                    System.out.println(sb.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {//执行流的关闭
                    if (br != null) {
                        br.close();
                    }
                    if (out != null) {
                        out.close();
                    } }
                return sb.toString(); }
        });
        String s = null;
        new Thread(task).start();
        try {
            s = task.get();//异步获取返回值
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
}


public class GetPostUrl { public static GetPostUrl getPost = new GetPostUrl();//单例 public static GetPostUrl getGetPost() { return getPost; } /** * 发送get请求 * * @param url * @return */ public static String get(final String url) { final StringBuilder sb = new StringBuilder(); FutureTask task = new FutureTask(new Callable() { @Override public String call() throws Exception { BufferedReader br = null; InputStreamReader isr = null; URLConnection conn; try { URL geturl = new URL(url); conn = geturl.openConnection();//创建连接 conn.connect();//get连接 InputStreamReader isr = new InputStreamReader(conn.getInputStream());//输入流 br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { sb.append(line);//获取输入流数据 } System.out.println(sb.toString()); } catch (Exception e) { e.printStackTrace(); } finally {//执行流的关闭 if (br != null) { try { if (br != null) { br.close(); } if (isr != null) { isr.close(); } } catch (IOException e) { e.printStackTrace(); } }} return sb.toString(); } }); new Thread(task).start(); String s = null; try { s = task.get();//异步获取返回值 } catch (Exception e) { e.printStackTrace(); } return s; } /** * POST请求 * * @param url url * @param map 请求参数的map集合形式 * @return */ public static String post(final String url, final Map map) { final StringBuilder sb = new StringBuilder(); FutureTask task = new FutureTask(new Callable() { @Override public String call() throws Exception { DataOutputStream out = null; BufferedReader br = null; URLConnection conn; URL posturl = new URL(url); try { conn = posturl.openConnection();//创建连接 conn.setDoInput(true);//post请求必须设置 conn.setDoOutput(true);//post请求必须设置 out = new DataOutputStream(conn .getOutputStream());//输出流 StringBuilder request = new StringBuilder(); for (String key : map.keySet()) { request.append(key + "=" + URLEncoder.encode(map.get(key), "UTF-8") + "&"); }//连接请求参数 out.writeBytes(request.toString());//输出流写入请求参数 out.flush(); out.close(); br = new BufferedReader(new InputStreamReader(conn.getInputStream()));//获取输入流 String line; while ((line = br.readLine()) != null) { sb.append(line); } System.out.println(sb.toString()); } catch (Exception e) { e.printStackTrace(); } finally {//执行流的关闭 if (br != null) { br.close(); } if (out != null) { out.close(); } } return sb.toString(); } }); String s = null; new Thread(task).start(); try { s = task.get();//异步获取返回值 } catch (Exception e) { e.printStackTrace(); } return s; }}




使用HttpURLConnection进行网络请求
HttpURLConnection是URLConnection的子类,在URLConnection的基础上进一步改进增加了操作HTTP资源的便捷方法。
创建URL连接,发生请求,读取资源步骤与URLConnection基本一致。
区别
  1. 使用setRequestMethod()方法设置请求方式”GET”或者”POST”
  2. 使用getResponseCode()获取响应码,判断请求是否成功
  3. 可以使用disconnect()断开请求连接
public class HttpConnectionUtil {
    public static HttpConnectionUtil http = new HttpConnectionUtil();

    public static HttpConnectionUtil getHttp() {
        return http;
    }

    public String getRequset(final String url) {
        final StringBuilder sb = new StringBuilder();
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public String call() throws Exception {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL requestUrl = new URL(url);
                    connection = (HttpURLConnection) requestUrl.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    if (connection.getResponseCode() == 200) {
                        InputStream in = connection.getInputStream();
                        reader = new BufferedReader(new InputStreamReader(in));
                        String line;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line);
                        }
                        System.out.println(sb);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (reader != null) {
                        reader.close();
                    }
                    if (connection != null) {
                        connection.disconnect();//断开连接,释放资源
                    }
                }
                return sb.toString();
            }
        });
        new Thread(task).start();
        String s = null;
        try {
            s = task.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    public String postRequset(final String url, final Map map) {
        final StringBuilder sb = new StringBuilder();
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public String call() throws Exception {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL requestUrl = new URL(url);
                    connection = (HttpURLConnection) requestUrl.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(8000);//链接超时
                    connection.setReadTimeout(8000);//读取超时
                    //发送post请求必须设置
                    connection.setDoOutput(true);
                    connection.setDoInput(true);
                    connection.setUseCaches(false);
                    connection.setInstanceFollowRedirects(true);
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    DataOutputStream out = new DataOutputStream(connection
                            .getOutputStream());
                    StringBuilder request = new StringBuilder();
                    for (String key : map.keySet()) {
                        request.append(key + "=" + URLEncoder.encode(map.get(key), "UTF-8") + "&");
                    }
                    out.writeBytes(request.toString());//写入请求参数
                    out.flush();
                    out.close();
                    if (connection.getResponseCode() == 200) {
                        InputStream in = connection.getInputStream();
                        reader = new BufferedReader(new InputStreamReader(in));
                        String line;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line);
                        }
                        System.out.println(sb);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (reader != null) {
                        reader.close();//关闭流
                    }
                    if (connection != null) {
                        connection.disconnect();//断开连接,释放资源
                    }
                }
                return sb.toString();
            }
        });
        new Thread(task).start();
        String s = null;
        try {
            s = task.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

}





一,get请求的使用方法
使用OKHttp进行网络请求支持两种方式,一种是 同步请求,一种是异步请求 。下面分情况进行介绍。
1,get的同步请求
对于同步请求在请求时需要开启子线程,请求成功后需要跳转到UI线程修改UI。 
使用示例如下:
public void getDatasync(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象
                Request request = new Request.Builder()
                        .url("http://www.baidu.com")//请求接口。如果需要传参拼接到接口后面。
                        .build();//创建Request 对象
                Response response = null;
                response = client.newCall(request).execute();//得到Response 对象
                if (response.isSuccessful()) {
                Log.d("kwwl","response.code()=="+response.code());
                Log.d("kwwl","response.message()=="+response.message());
                Log.d("kwwl","res=="+response.body().string());
                //此时的代码执行在子线程,修改UI的操作请使用handler跳转到UI线程。
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();
}




此时打印结果如下: 
response.code()==200; 
response.message()==OK; 
res=={“code”:200,”message”:success};
注意事项: 
1,Response.code是http响应行中的code,如果访问成功则返回200.这个不是服务器设置的,而是http协议中自带的。res中的code才是服务器设置的。注意二者的区别。 
2,response.body().string()本质是输入流的读操作,所以它还是网络请求的一部分,所以这行代码必须放在子线程。 
3,response.body().string()只能调用一次,在第一次时有返回值,第二次再调用时将会返回null。原因是:response.body().string()的本质是输入流的读操作,必须有服务器的输出流的写操作时客户端的读操作才能得到数据。而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,第二次将返回null


2,get的异步请求
这种方式不用再次开启子线程,但回调方法是执行在子线程中,所以在更新UI时还要跳转到UI线程中。 
使用示例如下:
private void getDataAsync() {
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
            .url("http://www.baidu.com")
            .build();
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if(response.isSuccessful()){//回调的方法执行在子线程。
                Log.d("kwwl","获取数据成功了");
                Log.d("kwwl","response.code()=="+response.code());
                Log.d("kwwl","response.body().string()=="+response.body().string());
            }
        }
    });
}




异步请求的打印结果与注意事项与同步请求时相同。最大的不同点就是异步请求不需要开启子线程,enqueue方法会自动将网络请求部分放入子线程中执行。
注意事项: 
1,回调接口的onFailure方法和onResponse执行在子线程。 
2,response.body().string()方法也必须放在子线程中。当执行这行代码得到结果后,再跳转到UI线程修改UI



最近在做入库出库的pda物流项目,需要上传出库入库的xml数据,于是用到Httpurlconnection和okhttp进行文件上传
(1)
private void httpsUrlConnectionPost(String pathfile) {
java.io.File file = new java.io.File(pathfile);
URL url= null ;
try {
if ( INSTORYTYPE == true ){
url = new URL( SERVER_INPUT_URL );
} else {
url = new URL( SERVER_OUT_URL );
}
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true, 默认情况下是false;
con.setDoOutput( true );
// 设置是否从httpUrlConnection读入,默认情况下是true;
con.setDoInput( true );
// 设定请求的方法为"POST",默认是GET
con.setRequestMethod( "POST" );
con.setSSLSocketFactory(Network. getSSLSocketFactory ());
//
con.setRequestProperty( "signature" , (String) map .get( "signature" ));
con.setRequestProperty( "content-length" , (String) map .get( "content-length" ));
con.setRequestProperty( "content_md5" , (String) map .get( "content_md5" ));
con.setRequestProperty( "version" , (String) map .get( "version" ));
// Post 请求不能使用缓存
con.setUseCaches( false );
OutputStream out = con.getOutputStream();
//读取本地xml文件流
FileInputStream fileInputStream = new FileInputStream(file);
byte [] data = new byte [ 2048 ];
int len = 0 ;
int sum = 0 ;
while ((len = fileInputStream.read(data)) != - 1 ) {
//将读取到的本地文件流读取到HttpsURLConnection,进行上传
out.write(data, 0 , len);
sum = len + sum;
}
out.flush();
fileInputStream.close();
out.close();

int code = con.getResponseCode(); //获取post请求返回状态
System. out .println( "code=" + code + " url=" + url);
if (code == 200 ) {
InputStream inputStream2 = con.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = inputStream2.read(data)) != - 1 ) {
bos.write(data, 0 , len);
}
inputStream2.close();
String content = bos.toString();
bos.close();
System. out .println( "result =" + content);
//将返回的json格式的字符串转化为json对象'
Message messag= mHandler .obtainMessage();
messag. obj =content;
mHandler .sendMessage(messag);
}
} catch (Exception e) {
e.printStackTrace();
}


}
(2) 头部参数是我项目特殊需求,默认可以不加头部参数
try {
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String s = null;
while ((s = br.readLine()) != null) {
sb.append(s);
}
} catch(IOException e) {
e.printStackTrace();
} finally {
if(br != null) {
br.close();
}
}
//这里是关键
RequestBody.create()的第二个参数需要传入使用这个方法
RequestBody create(MediaType contentType, String content)
content是文件的内容,通过本地读取出来,不要传入File对象,可能会出现问题。
RequestBody fileBody = RequestBody.create(MediaType.parse("text/xml;charset=utf-8"), sb.toString());
requestPostFile = new Request.Builder()
.url(SERVER_OUT_URL)
.post(fileBody)
.addHeader("content-length",fis1.available()+"")
.addHeader("content_md5",md5Value1)
.addHeader("signature",sysList.get(0).getSignature())
.addHeader("version","1")
.build();
} catch (IOException e) {
e.printStackTrace();
}

client.newCall(requestPostFile).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {

}

@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
Logger.d(response.body().string()+"-----");
Logger.d(response.body());
}
});











你可能感兴趣的:(android基础)