网络访问之HttpURLConnection

一、网络访问:

(一)、网络访问的基本概念和流程:
访问网络的方式分为:基于TCP协议的网络通信;基于HTTP协议的网络访问。前者主要学Socket的用法(之后的课程中会讲到),而后者是网络访问中学习的重点。

基于HTTP协议进行网络访问的类主要有:URL、URLConnection、HttpURLConnection、HttpClient这几个类。HttpURLConnection、HttpClient在之后的Android中比较重要。

HttpURLConnection类在java.net包中,是java原生的类;而HttpClient并非Java原生的类,是Apache开源组织提供的。如果在普通的java项目中使用HttpClient,需要导入第三方类包。不过Android中已经内置了HttpClient,也就是说在Android项目中,可以顺利地使用HttpClient类。

(二)、URL介绍:
URL(Uniform Resource Locator)对象代表统一资源定位器,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是数据库等更复杂的对象。通常情况下,URL由协议名、主机、端口和资源组成。
基本格式如下:
协议名://主机:端口/资源
例如:
http://www.sohu.com/index.php

(三)、HttpURLConnection类的基本用法:
使用步骤:
1、实例化URL对象。调用URL有参构造方法,参数是一个url地址(URL对象专门跟网址挂钩的);
2、调用URL对象的openConnection()方法(跟服务器创建连接,返回值是URLConnection对象,我们要建立的是HTTPURLConnection,所以要强转,),创建HttpURLConnection对象。HttpURLConnection对象可以建立客户端和服务器端之间的连接(建立服务器和客服端的连接,记得强转,子类功能更强,方法更多);
3、调用HttpURLConnection对象的getResponseCode()获取客户端与服务器端的连接状态码。如果是200,则说明连接正常,服务器有响应(看服务器是不是给返回内容,以这个码为准);
4、调用HttpURLConnection对象的getInputStream()方法,该方法返回InputStream对象(输入输出以客服端为标志位,输入到客服端);
5、通过标准IO流操作,解析流操作。

(四)、示例代码:

public static void main(String[] args) {
//定义需要访问的url地址
String urlString = "http://www.baidu.com";
URL urlObj;
BufferedInputStream bis = null;
HttpURLConnection httpConn = null;
try {
// 创建url对象
//有参数,得输入网址。如:"http://192.168.120.107/"。 // 创建HttpURLConnection对象,通过这个对象打开跟远程服务器之间的连接
urlObj = new URL(urlString);
// 创建HttpURLConnection对象,通过这个对象打开跟远程服务器之间的连接
httpConn = (HttpURLConnection) urlObj.openConnection();

// 判断跟服务器的连接状态。如果是200,则说明连接正常,服务器有响应
if (httpConn.getResponseCode() == 200) {
// 服务器有响应后,会将访问的url页面中的内容放进inputStream中,使用httpConn就可以获取到这个字节流
bis = new BufferedInputStream(httpConn.getInputStream());//获得网页上的内容

// 以下执行标准的IO操作,将流中的内容写到本地文件中
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("abc.html"));
byte[] buffer = new byte[1024];
int c = 0;
while ((c = bis.read(buffer)) != -1) {
bos.write(buffer,0,c);
bos.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

(五)、网络访问方式——GET/POST:
1、HMTL表单的书写:核心标签:

<form>
<input type="text">
<input type="password">
<input type="radio">
<input type="checkbox">
<input type="submit">
<input type="reset">
<input type="button">
<input type="image">
<textarea>
<select>
<option>

【说明:】主要的表单控件:文本框、密码框、单选框、多选框、下拉列表、文字域、图片域、隐藏域、提交按钮、重置按钮等。
  其中最需要注意的就是多选框,一组多选的id和name在命名上需要注意。

2、表单的示例代码:

表单:
<form method="post或get" action="接收页面的地址" enctype="multipart/form-data">
<!-- 当需要上传图片或其他文件时,必须要设置form的enctype属性为"multipart/form-data" -->
文本框:<input type="text" name="username" id="username" />
密码框:<input type="password" name="password" id="password" />
单选项:
<input value="男" name="sex" checked="checked" type="radio">男
<input value="女" name="sex" type="radio">女
下拉列表:
<select name="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="天津">天津</option>
</select>
多选框:
<input name="fonds[]" type="checkbox" value="服装">服装
<input name="fonds[]" type="checkbox" value="电子">电子
<input name="fonds[]" type="checkbox" value="图书">图书
<input name="fonds[]" type="checkbox" value="食品">食品
隐藏域:<input type="hidden" name="id" value="100" />
提示:隐藏域的使用目的是为了隐式传值,所以必须有value值才有意义。
文字域:<textarea name="info" id="info"></textarea>
提交:<input name="submit" type="submit" value="注册">
重置:<input name="reset" type="reset" value="重置">

【说明:】
每种控件一般常用属性都需要写,name属性为了表单传值id属性主要用于样式和表单脚本验证Value属性表示控件初始值,视情形而定;size属性主要是定义控件的大小;maxlength属性定义最大允许输入内容的长度。

3、POST和GET在表单提交时的区别:
最大的区别在三方面:传值方式及安全性、传值大小、灵活性。

Post传递必须依赖于表单,传值的内容没有大小限制,传值内容不会在地址栏显示,而是将表单内各个字段与其内容放置在HTML header内一起传送到ACTION属性所指的服务器。整个过程用户看不到,因此比 Get 传值安全;

Get传值方式是把参数加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,因此传递的数据可以在URL中被用户看到,因此安全性不高。而且Get 传递的数据不可以过长(小于1024个字节),当超过这个长度后会自动裁切掉多余内容,将裁切后的内容传递给服务器。

Get 传参可以通过表单,也可以不通过表单,直接通过地址栏传参。因此 Get 传参更灵活。而对比之下,post方式不够灵活。

(六)、服务器
1、服务器作为硬件来说,通常是指那些具有较高计算能力,能够提供给多个用户使用的计算机。服务器与PC机的不同点很多,例如PC机在一个时刻通常只为一个用户服务。服务器与主机不同,主机是通过终端给用户使用的,服务器是通过网络给客户端用户使用的。
2、服务器作为软件来说,通常指Web服务器。Web服务器是可以向发出请求的浏览器提供文档的程序。

服务器是一种被动程序:只有当Internet上运行在其他计算机中的浏览器发出请求时,服务器才会响应;
最常用的Web服务器是Apache、Tomcat和Microsoft的Internet信息服务器(Internet Information Services,IIS)。

php程序一般运行在apache服务器上,也可以运行在IIS服务器上;( Apache是世界使用排名第一的Web服务器软件)

java写的bs程序都运行在Tomcat服务器上;(Tomcat由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,能运行Servlet 和JSP )

asp.net写的程序都运行在IIS服务器上。

这里写图片描述



(一)、通过HttpURLConnection从服务器取得数据:
1、核心代码:
// 创建url对象
URL urlObj = new URL(urlString);
// 创建HttpURLConnection对象,通过这个对象打开跟远程服务器之间的连接
HttpURLConnection httpConn = (HttpURLConnection) urlObj.openConnection();

// 判断跟服务器的连接状态。如果是200,则说明连接正常,服务器有响应
if (httpConn.getResponseCode() == 200) {
// 服务器有响应后,会将访问的url页面中的内容放进inputStream中,使用httpConn就可以获取到这个字节流
bis = new BufferedInputStream(httpConn.getInputStream());
}

2、深入分析:

1、上述代码中忽略了请求网络的Method。到底是GET还是POST,没有明确说明。
2、忽略了HTTP访问过程中的头信息的设置问题,也就是一堆setRequestProperty()方法的使用。(什么是头信息?)
3、HttpURLConnection对象有setDoInput()和setDoOutput()方法。到底代表什么意思?
4、HttpURLConnection对象中的connect()方法有什么用?这个方法是不是才是真正跟服务器建立连接的方法呢?如何那样,那么URL对象的openConnection()方法又是有什么用?
5、Http访问网络的超时问题。
6、HttpURLConnection对象配置HTTP头部信息和connect()方法的调用顺序问题。
7、如何向服务器POST提交数据?



二、HttpWatch插件:
(一)、介绍:
HttpWatch是强大的网页数据分析工具.集成在IE工具栏.包括网页摘要、Cookies管理、缓存管理、消息头发送/接受、字符查询、POST数据和目录管理功能。
只需要选择相应的网站,软件就可以对网站与IE之间的请求和回复的通讯情况进行分析并显示其日志记录。每一个HTTP记录都可以详细的分析其 Cookies、头信息、字符查询、POST数据等信息。
(二)、目的:
让同学们使用这个IE插件,目的是为了更透彻地理解客户端机器和服务器之间是如何通讯的,更透彻地理解GET和POST。更重要地是在模拟浏览器访问网络时,需要通过很多setRequestProperty()方法设置很多头信息。什么是头信息,到底有哪些头信息需要设置。通过httpWatch能帮同学们很好的理解这一点。

<headers>
<header name="Accept">image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/x-shockwave-flash,application/xaml+xml,application/vnd.ms-xpsdocument,application/x-ms-xbap,application/x-ms-application,application/msword,application/vnd.ms-excel,application/vnd.ms-powerpoint,*/*</header>
<header name="Accept-Encoding">gzip,deflate</header>
<header name="Accept-Language">zh-cn</header>
<header name="Cache-Control">no-cache</header>
<header name="Connection">Keep-Alive</header>
<header name="Content-Length">37</header>
<header name="Content-Type">application/x-www-form-urlencoded</header>
<header name="Cookie">PHPSESSID=dccscri3qftumao92bll8ia933</header>
<header name="Host">127.0.0.1</header>
<header name="User-Agent">Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; Shuame)</header>
</headers>

关于常见浏览器的User-Agent的信息。

1、IE 
  而IE各个版本典型的userAgent如下: 
  Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) 
  Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2) 
  Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) 
  Mozilla/4.0 (compatible; MSIE 5.0; Windows NT) 
  其中,版本号是MSIE之后的数字。 

2、Firefox 
  Firefox几个版本的userAgent大致如下: 
  Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1 
  Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070309 Firefox/2.0.0.3 
  Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803 Firefox/1.5.0.12  其中,版本号是Firefox之后的数字。 

3、Opera 
  Opera典型的userAgent如下: 
  Opera/9.27 (Windows NT 5.2; U; zh-cn) 
  Opera/8.0 (Macintosh; PPC Mac OS X; U; en) 
  Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.0  
  其中,版本号是靠近Opera的数字。 

4、Safari (苹果的浏览器)
  Safari典型的userAgent如下: 
  Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML,like Gecko) Version/3.1 Safari/525.13 
  Mozilla/5.0 (iPhone; U; CPU like Mac OS X) AppleWebKit/420.1 (KHTML,like Gecko) Version/3.0 Mobile/4A93 Safari/419.3 
  其版本号是Version之后的数字。 

5、Chrome (Google的浏览器)
  目前,Chrome的userAgent是: 
Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML,like Gecko) Chrome/0.2.149.27 Safari/525.13  
  其中,版本号在Chrome之后的数字。 



三、HttpURLConnection访问网络的完整写法:
(一)、各种属性设置:
1、设置网络访问请求方式:
例如:httpConn.setRequestMethod(“POST”);
查看HttpURLConnection类的源码,会看到默认情况下的网络请求方式就是“GET”。
也就是说如果不设置请求方式,默认情况下等同存在以下代码:httpConn.setRequestMethod(“GET”);

2、设置网络连接超时时间:
例如: httpConn.setConnectTimeout(3000); // 设置网络访问的超时时间为3000毫秒

3、配置本次连接的Content-type:
例如: httpConn.setRequestProperty(“Content-Type”,”application/x-www-form-urlencoded”);
配置为application/x-www-form-urlencoded的意思是正文是urlencoded编码过的form参数,当我们传递含有中文的参数时,要使用URLEncoder.encode进行编码,目的是减少编码问题。(windows操作系统中,默认地址栏是GBK编码,而实际工作中我们的文件都采用utf-8编码,为了编码乱码,我们会在参数传递中使用URLEncoder.encode进行编码)。

4、配置头信息中的Accept、Connection、User-Agent、Cache-Control、Accept-Encoding等属性。【备注:】在设置头信息完成前,不能执行任何输出性的语句(诸如:System.out.println(),否则会出现IllegalStateException异常)。

5、setDoInput():【important】
例如:httpConn.setDoInput(true);
设置服务器是否往httpConn对象中输入数据,默认情况下是true。
【备注:】如何理解从httpConn中读入呢?
当客户端与服务器建立连接后,如果服务器正常响应,也就是状态码为200时,会将服务器端返回的数据都放进HttpURLConnection对象中。而客户端需要获取的时候,只需要通过调用httpConn.getInputStream()就可以拿到存放在其中的所有数据。

6、setDoOutput():【important】
例如:httpConn.setDoOutput(true);
设置是否从httpConn对象中输出数据, 默认情况下是false。
【备注:】为什么服务器要从httpConn对象中输出数据呢?

而如果数据量大或者考虑到安全因素时,数据都是通过post传递。

post传参时,数据不是通过头文件传输,而是被放在http正文内传输给服务器。具体来说,就是把需要传给服务器的参数放进HttpURLConnection对象中。当客户端与服务器端建立连接后,通过httpConn.getOutputStream()返回OutputStream对象,再通过OutputStream对象的write()方法将post方式传递给服务器的参数写在其中,当flush()方法执行后,数据就被发送给了服务器。

所以只要通过post传参,服务器一定要从httpConn对象中输出数据。而此时,setDoOutput()必须设置为true。

7、调用connect()方法:
HttpURLConnection对象的connect()方法,作用是建立与服务器的实际连接。但是实际上,我们发现不写这句话,URL对象的openConnection()方法就实现了连接。从源码中我们看到connect()方法实际上是个抽象方法。从API中也实在无法明白JAVA官方希望表达的意思。但是建议大家以后写上此句。
需要注意的是:所有的属性设置都必须在httpConn.connect()方法前完成,否则会出现IllegalStateException异常。
【有资料认为:connect()方法调用后,实际上也并没有发送http请求。无论是post还是get请求,直到HttpURLConnection对象调用getOutputStream()或getInputStream()方法后,内存缓冲区中封装好的完整的HTTP请求才正式发送给了服务器。】



(二)、GET方式下载数据的示例代码:

/**
* 作用:实现网络访问文件,将获取到的数据存在字节数组中
* 
* @param url:访问网络的url地址。为了防止传中文参数时出现编码问题。采用URLEncoder.encode()对含中文的字符串进行编码处理。
* 而服务器端会自动对进行过编码的字符串进行decode()解码。
* @return byte[]
*/
public static byte[] downLoadByteFromURL(String url) {
HttpURLConnection httpConn = null;
BufferedInputStream bis = null;
ByteArrayOutputStream baos = null;
try {
URL urlObj = new URL(url);
httpConn = (HttpURLConnection) urlObj.openConnection();
// 以下两项都是默认值。虽然可以不写,但是建议写上。
httpConn.setRequestMethod("GET");
                        // 设置将服务器返回数据写入到httpConn对象
httpConn.setDoInput(true);
                        // 设置访问超时时间
                        httpConn.setConnectTimeout(8000);
                        // 设置是否使用缓存 httpConn.setUseCaches(false);
                        // 建立远程对象实际连接
                        httpConn.connect();

if (httpConn.getResponseCode() == 200) {
bis = new BufferedInputStream(httpConn.getInputStream());
baos = new ByteArrayOutputStream();
int c = 0;
byte[] buffer = new byte[8 * 1024];
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer,c);
baos.flush();
}
return baos.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}



(三)、POST方式下载数据的示例代码:
1、操作步骤:
实例化URL对象,参数是一个url地址;

调用URL对象的openConnection(),返回URLConnection对象。为了获取更多方法,转换成HttpURLConnection对象;

调用 HttpURLConnection对象的setRequestProperty()方法设置头信息;(Accept、Content-Type、Cache、User-Agent,setConnectTimeout())

调用 HttpURLConnection对象的setDoOutput(),setDoInput();

调用 HttpURLConnection对象的getOutputStream(),将客户端Post过来的数据以字节数组的形式传递给服务器

调用 HttpURLConnection对象的getResponseCode()方法获取服务器的返回码;

如果返回状态码是200,则调用 HttpURLConnection对象的getInputStream()方法获取服务器返回的流信息;

执行标准的IO流操作。

/** * 作用:实现网络访问文件,先给服务器通过“POST”方式提交数据,再返回相应的数据 * * @param url * :访问网络的url地址 * @param params * :访问url时,post传递给服务器的参数。格式为:username=wangxiangjun&password= * 123456。使用时需要将该字符串转成byte[]. * @return byte[] */ public static byte[] doPostSubmit(String url,String params) { 
BufferedOutputStream bos = null;
 BufferedInputStream bis = null; 
HttpURLConnection httpConn = null; 
ByteArrayOutputStream baos = null; 
try { URL urlObj = new URL(url);
 httpConn = (HttpURLConnection) urlObj.openConnection();
 httpConn.setRequestProperty("Accept","*/*"); 
httpConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); 
httpConn.addRequestProperty( "User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML,like Gecko) Chrome/0.2.149.27 Safari/525.13"); 
httpConn.setConnectTimeout(8000);
 httpConn.setUseCaches(false); 
httpConn.setRequestMethod("POST"); 
httpConn.setDoOutput(true); 
httpConn.setDoInput(true); 
httpConn.connect(); 
if (params != null) { 
bos = new BufferedOutputStream(httpConn.getOutputStream()); 
bos.write(params.getBytes(),params.length()); 
bos.flush(); 
}
 if (httpConn.getResponseCode() == 200) { 
bis = new BufferedInputStream(httpConn.getInputStream());
 baos = new ByteArrayOutputStream(); 
int c = 0;
 byte[] buffer = new byte[8 * 1024];
 while ((c = bis.read(buffer)) != -1) {
 baos.write(buffer,c); 
baos.flush(); 
} 
return baos.toByteArray();
 } 
} 
catch (Exception e) { 
e.printStackTrace(); 
} finally {
 try { if (bis != null) { 
bis.close(); 
}
 if (bos != null) {
 bos.close(); 
}
 if (baos != null) {
 baos.close(); 
} 
} catch (IOException e) { 
e.printStackTrace(); 
} 
}
 return null; } /** * 作用:实现网络访问文件,先给服务器通过“POST”方式提交数据,再返回相应的数据 * * @param url * :访问网络的url地址 * @param params * :访问url时,post传递给服务器的参数。是个Map集合。使用时需要将其转成byte[]。第三个参数是字符集。 * @return byte[] */ public static byte[] doPostSubmit(String url,Map<String,String> params,String charset) {
 BufferedOutputStream bos = null; 
BufferedInputStream bis = null; 
HttpURLConnection httpConn = null; 
ByteArrayOutputStream baos = null; 
try { URL urlObj = new URL(url);
 httpConn = (HttpURLConnection) urlObj.openConnection(); 
httpConn.setRequestProperty("Accept",like Gecko) Chrome/0.2.149.27 Safari/525.httpConn.setDoInput(true); httpConn.connect();
 StringBuilder builder = new StringBuilder(); 
if (params != null && !params.isEmpty()) {
 for (Map.Entry<String,String> entry : params.entrySet()) { 
ry { builder.append(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(),charset) + "&");
 } 
catch (Exception e) { e.printStackTrace();
 }
 } 
} // 去除最后一个&符号
 byte[] data = builder.substring(0,builder.lastIndexOf("&")) .getBytes(); 
bos = new BufferedOutputStream(httpConn.getOutputStream()); 
bos.write(data,data.length); 
bos.flush();
 if (h13");
 httpConn.setConnectTimeout(8000);
httpConn.setUseCaches(false); 
httpConn.setRequestMethod("POST"); 
httpConn.setDoOutput(true); 
ttpConn.getResponseCode() == 200) { 
bis = new BufferedInputStream(httpConn.getInputStream()); 
baos = new ByteArrayOutputStream(); 
int c = 0; byte[] buffer = new byte[8 * 1024]; 
while ((c = bis.read(buffer)) != -1) { 
baos.write(buffer,c);
 baos.flush(); 
}
 return baos.toByteArray(); 
}
 }
 catch (Exception e) {
 e.printStackTrace();
 } finally { try { if (bis != null) {
 bis.close();
 }
 if (bos != null) {
 bos.close(); 
} 
if (baos != null) { 
baos.close(); 
}
 } catch (IOException e) 
{ e.printStackTrace(); } 
} return null; 
}



(四)、URLEncoder类:
1、作用:
Windows操作系统中,网络中URL地址的编码是GBK编码,而实际工作中,文件编码常为utf-8编码。为了防止中文参数在传递时出现编码问题。采用URLEncoder.encode()对含中文的字符串进行编码处理。而服务器端会自动对进行过编码的字符串进行URLDecoder.decode()解码。
编码过程非常简单,任何字符只要不是ASCII码数字,字母,或者前面提到的标点符,它们都将被转换成字节形式,每个字节都写成这种形式:一个“%”后面跟着两位16进制的数值。空格被编码成“%20”,加号(+)本身被编码为“%2B”。

2、示例代码:

 String str_encode;
String str_encode2;
try {
str_encode = URLEncoder.encode("ABCabc123中国","utf-8");
str_encode2 = URLEncoder.encode("ABCabc123中国","gbk");
System.out.println(str_encode);
System.out.println(str_encode2);

String str_decode = URLDecoder.decode(str_encode,"utf-8");
String str_decode2 = URLDecoder.decode(str_encode2,"gbk");
System.out.println(str_decode);
System.out.println(str_decode2);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

//输出结果为:
ABCabc123%E4%B8%AD%E5%9B%BD
ABCabc123%D6%D0%B9%FA
ABCabc123中国
ABCabc123中国

【备注:】
从上例中可以看出。utf-8编码中的中文是三字节编码,所以“中”字编码后是%E4%B8%AD%。
GBK编码中的中文是双字节编码,所以“中”字编码后是 %D6%D0。



五、封装HttpURLConnection类:HttpURLConnHelper
(一)、需要封装哪些方法?
1、/**
* 作用:实现网络访问文件,将获取到数据储存在文件流中
*
* @param url
* :访问网络的url地址
* @return inputstream
*/
InputStream downLoadFileFromURL(String url);

2、/**
* 作用:实现网络访问文件,将获取到的数据存在字节数组中
*
* @param url
* :访问网络的url地址
* @return byte[]
*/
byte[] downLoadByteFromURL(String url);

3、/**
* 作用:实现网络访问文件,先给服务器通过“POST”方式提交数据,再返回相应的数据
*
* @param url
* :访问网络的url地址
* @param params
* :访问url时,post传递给服务器的参数。格式为:username=wangxiangjun&password=
* 123456。使用时需要将该字符串转成byte[].
* @return byte[]
*/
byte[] doPostSubmit(String url,String params);

4、/**
* 作用:实现网络访问文件,先给服务器通过“POST”方式提交数据,再返回相应的数据
*
* @param url
* :访问网络的url地址
* @param params
* :访问url时,post传递给服务器的参数。是个Map集合。使用时需要将其转成byte[].
* @return byte[]
*/
byte[] doPostSubmit(String url,String charset);

核心代码:

/**
* 作用:实现网络访问文件,将获取到数据储存在文件流中
*
* @param url
* :访问网络的url地址
* @return inputstream
*/
public static InputStream downLoadFileFromURL(String url) {
URL urlObj;
BufferedInputStream bis = null;
HttpURLConnection httpConn = null;
try {
// 创建url对象
urlObj = new URL(url);
// 创建HttpURLConnection对象,通过这个对象打开跟远程服务器之间的连接
httpConn = (HttpURLConnection) urlObj.openConnection();

// 判断跟服务器的连接状态。如果是200,则说明连接正常,服务器有响应
if (httpConn.getResponseCode() == 200) {
// 服务器有响应后,会将访问的url页面中的内容放进inputStream中,使用httpConn就可以获取到这个字节流
bis = new BufferedInputStream(httpConn.getInputStream());
return bis;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 对流对象进行关闭,对Http连接对象进行关闭。以便释放资源。
bis.close();
} catch (IOException e) {
e.printStackTrace();
}

}
return null;
}

/**
* 作用:实现网络访问文件,将获取到的数据存在字节数组中
*
* @param url
* :访问网络的url地址
* @return byte[]
*/
public static byte[] downLoadByteFromURL(String url) {
HttpURLConnection httpConn = null;
BufferedInputStream bis = null;
ByteArrayOutputStream baos = null;
try {
URL urlObj = new URL(url);
httpConn = (HttpURLConnection) urlObj.openConnection();
// 以下两项都是默认值。虽然可以不写,但是建议写上。
httpConn.setRequestMethod("GET");
// 设置将服务器返回数据写入到httpConn对象
httpConn.setDoInput(true);
// 设置访问超时时间
httpConn.setConnectTimeout(8000);
// 设置是否使用缓存
httpConn.setUseCaches(false);
// 建立远程对象实际连接
httpConn.connect();

if (httpConn.getResponseCode() == 200) {
bis = new BufferedInputStream(httpConn.getInputStream());
baos = new ByteArrayOutputStream();
int c = 0;
byte[] buffer = new byte[8 * 1024];
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer,c);
baos.flush();
}
return baos.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

/**
* 作用:实现网络访问文件,先给服务器通过“POST”方式提交数据,再返回相应的数据
*
* @param url
* :访问网络的url地址
* @param params
* :访问url时,post传递给服务器的参数。格式为:username=wangxiangjun&password=
* 123456。使用时需要将该字符串转成byte[].
* @return byte[]
*/
public static byte[] doPostSubmit(String url,String params) {
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
HttpURLConnection httpConn = null;
ByteArrayOutputStream baos = null;

try {
URL urlObj = new URL(url);
httpConn = (HttpURLConnection) urlObj.openConnection();
httpConn.setRequestProperty("Accept","*/*");
httpConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConn.addRequestProperty(
"User-Agent",like Gecko) Chrome/0.2.149.27 Safari/525.13");
httpConn.setConnectTimeout(8000);
httpConn.setUseCaches(false);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.connect();

if (params != null) {
bos = new BufferedOutputStream(httpConn.getOutputStream());
bos.write(params.getBytes());
bos.flush();
}
if (httpConn.getResponseCode() == 200) {
bis = new BufferedInputStream(httpConn.getInputStream());
baos = new ByteArrayOutputStream();
int c = 0;
byte[] buffer = new byte[8 * 1024];
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer,c);
baos.flush();
}
return baos.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

/**
* 作用:实现网络访问文件,先给服务器通过“POST”方式提交数据,再返回相应的数据
*
* @param url
* :访问网络的url地址
* @param params
* :访问url时,post传递给服务器的参数。是个Map集合。使用时需要将其转成byte[].
* @return byte[]
*/
public static byte[] doPostSubmit(String url,String charset) {
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
HttpURLConnection httpConn = null;
ByteArrayOutputStream baos = null;

try {
URL urlObj = new URL(url);
httpConn = (HttpURLConnection) urlObj.openConnection();
httpConn.setRequestProperty("Accept",like Gecko) Chrome/0.2.149.27 Safari/525.13");
httpConn.setConnectTimeout(8000);
httpConn.setUseCaches(false);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.connect();

StringBuilder builder = new StringBuilder();
if (params != null && !params.isEmpty()) {
for (Map.Entry<String,String> entry : params.entrySet()) {
try {
builder.append(entry.getKey() + "="
+ URLEncoder.encode(entry.getValue(),charset)
+ "&");
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 去除最后一个&符号
byte[] data = builder.substring(0,builder.lastIndexOf("&"))
.getBytes();
bos = new BufferedOutputStream(httpConn.getOutputStream());
bos.write(data,data.length);
bos.flush();
if (httpConn.getResponseCode() == 200) {
bis = new BufferedInputStream(httpConn.getInputStream());
baos = new ByteArrayOutputStream();
int c = 0;
byte[] buffer = new byte[8 * 1024];
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer,c);
baos.flush();
}
return baos.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

相关文章

Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...
Android实现自定义带文字和图片的Button 在Android开发中经常...
Android 关于长按back键退出应用程序的实现最近在做一个Andr...
android自带的时间选择器只能精确到分,但是对于某些应用要求...