一、URL和URI
在Internet中,每一个站点,无论是www站点或是其他协议的站点,其中任何一个资源,都有一个唯一的统一资源标识符URI(Universal Resource Identifier)。
URL是Uniform Resource Locator统一资源定位符的缩写,URL指向URI,是一种常见形式的URI,指明如何使用网络协议在网络中访问到该资源。
资源可以是通常意义的文件,包括图片、声音、文本、服务等,还指数据库中的文档、命令查询的结果、email、电话号码、短信等。
在个人计算机中,通常使用目录结构来存储和查找某个文件,在复杂的互联网中,要查找某个资源就要借助于URL,不仅仅是文件和目录,还包括存储在网络中哪个主机上,以何种方式提供何种服务等。
二、URI的定义
在www的规范中,URI的定义格式是:<scheme>://<authority><path>?<query>#fragment
其中scheme和path是必须的,虽然有时path是空的。
scheme(方案):scheme决定了一个资源的标识是如何被指定的。常见的scheme包括http、ftp、mailto、file、data等等。
authority(授权信息):[user:password@]host[:port]
path(路径):指以‘/’符号分隔的目录层次结构。
query(查询):指以‘?’符号开始的查询串,之后是若干”属性=值“格式的序列,中间以‘&‘符号分隔。例如:data?param1=value1¶m2=value2
fragment(段):以符号‘#’开始,指指向某二级资源的段标识符,常用在html页面中。
分析:https://www.baidu.com/img/bd_logo1.png
scheme指https,authority指www.baidu.com,path指/img/,query没有定义,fragment没有定义。
三、URI类
URI在java中有一个相对应的URI类来操作,创建URI对象,无非是提供不同的String参数来设定scheme,authority,path,query,fragment等部分的值来完成。
常用构造方法:
public URL toURL() throws MalformedURLException
将URI对象转换为URL对象,URL是特殊形式的URI,除了标识网络资源,还提供了定位该资源的方法以及访问机制。
URI类还包括了一系列获取URI各个组成部分内容的get方法:
getScheme()、getSchemeSpecificPart()、getAuthority()。getUserInfo()、getHost()、getPort()、getPath()、getQuery()、getFragment()
四、URL的定义:
互联网上的各种资源,例如文件、web站点、网页、FTP站点、Email地址等可以访问的资源,都有特定的URL。
URL是包括协议、主机名、端口、路径、查询字符串和参数等字段的对象。例如:<传输协议>://<主机名>:<端口号>/<文件名> # <引用>
例如:http://www.souhu.com/index.html
URL后面可能还跟有一个‘片段’,也成为”引用“。该片段由井字符”#“指示,后面跟由更多的字符,例如:http://java.sun.com/index.html#chapter1
其中传输协议(protocol)指明获取资源所使用的传输协议,如http、ftp、file等。
主机名(hostname)指定资源所在的计算机,可以是IP地址,如127.0.0.1,也可以是主机名或域名,如www.sun.com。
一个计算机中可能有多种服务(应用程序),端口号用来区分不同的网络服务,如http服务的默认端口号是80,ftp服务的默认端口号是21等。
文件名(filename)包括该文件的完整路径,在http协议中,缺省的文件名是index.html,因此,http://java.sun.com就等同于http://java.sum.com/index.html。
引用(reference)为资源内的某个引用,用来定位显示文件内容的位置,如http://java.sun.com/index.html#chaper1。但并非所有的URL都包含这些元素,对于多数的协议,主机名和文件名是必须的,但是端口号和文件内部的引用则是可选的。
五、URL类
URI和URL类这两个类是相对独立的,没有层次关系。java程序定位和检索网络上的数据最简单的方法是使用URL类,使用URL类不需要考虑协议的细节、所要检索的数据的格式以及如何与服务器进行通信,只要把URL告知Java,就可以检索到数据。
与InetAddress对象不同,用户可以构造java.net.URL实例,URL有6种构造方法,差别在于他们要求的信息不同。
1、public URL(String spec)throws MalformedURLException
根据String表示形式创建URL对象,例如:
URL u = new URL("http://java.sun.com:80/docs/books/tutorial.html#downloading")
2、public URL(URL context,String spec)throws MalformedURLException
通过在指定的上下文中对给定的spec进行解析创建URL,新的URL从给定的上下文URL和spec参数创建。
例如:URL u = new URL("http://java.sun.com:80/docs/books/");
URL u1 = new URL(u,"tutorial.intro.html");
URL u2 = new URL(u,"tutorial.super.html");
3、pubic URL(String protocol,String host,String file)throws MalformedURLException
根据指定的protocol名称,host名称和file名称创建URL,使用协议的默认端口。
4、public URL(String protocol,String host,int port,String file) throws MalformedURLException
根据指定的protocol、host、port号和file创建URL对象。
例如:URL u=new URL("http://java.sun.com",80,"docs/books/tutorial.intro.html");
5、public URL(URL context,String spec,URLStreamHandler handler)throws MalformedURLException
通过在指定的上下文中用指定的处理程序对给定的spec进行解析来创建URL,如果处理程序为null,则使用两参数构造方法进行解析。
6、public URL(String protocol,String host,int port,String file,URLStreamHandler handler)throws MalformedURLException
根据指定的protocol、host、port号、file和handler创建URL对象,指定port号为-1指示URL应使用协议默认的端口,指定hander为null指示URL应使用协议的默认流处理程序。
查询URL的各个部分:
public String getQuery():获得URL的查询部分。
public String getPath():获得此URL的路径部分
public int getPort():获得此URL的端口号,如果未设置端口号,则返回-1
public int getDefaultPort():获得此URL关联协议的默认端口号。
public String getAuthority():获得此URL的权限部分。
public String getProtocol():获得此URL的协议名称。
public String getHost():获得此URL的主机名(如果适用)。
public String getFile():获得此URL的文件名。
public String getRef():获得此URL的引用。
public String getUserInfo():获得此URL的userInfo部分。
从URL检索数据:
1、public final InputStream openStream() throws IOException
打开到URL的连接并返回一个用于从该连接读入的InputStream,在URL对象创建以后,就可以通过它来访问指定的www资源,这时需要调用URL类的openStream()方法,该方法与指定的URL建立连接并返回一个InputStream类的对象,这样访问网络资源的操作就变成了IO操作,接下来就可以用字节流的方式读取资源数据,当一个流打开时,得到的数据是URL参考文件的原始内容,协议相关的信息已经被去掉,网络连接要比文件流慢且不可靠,所以用BufferedReader或BufferedInputStream进行缓冲更为高效。
代码实例:
import java.net.URL;
import java.io.BufferedInputStream;
public class OpenStream{
public static void main(String args[]) throws Exception{
URL url = new URL("file:///C://boot.ini");
BufferedInputStream stream = new BufferedInputStream(url.openStream());
int c;
while((c=stream.read())!=-1)
System.out.print((char)c);
Stream.close();
}
}
2、public URLConnection openConnection() throws IOException
返回一个URLConnection对象,它表示到URL所引用的远程对象的连接,如果呼叫失败,将会触发一个IOException异常。
例如:
try{
URL u = new URL("http://www.google.cn");
try{URLConnection uc = u.openConnecion();
InputStream in = uc.getInputStream;
}
catch(IOException e){
System.err.println(e)
}
}
catch(MalformedURLException e){
System.err.println(e);
}
3、public final Object getContent()throws IOException
返回URL的内容。
例如:
URL url = new URL("file:///C://boot.ini");
Object obj = url.getContent();
System.out.println(obj.toString());
public final Object getContent(Class[] classes)throws IOException
检索URL的数据,并试图把它转换成对象的某个类型。
例如:ASCII或HTML文件,返回的对象通常是某种InputStream,如果URL指向一副图像,比如一个GIF或JPEG文件,那么将返回java.awt.ImageProducer。
六、URLConnection类
实际应用中光读取数据是不够的,很多情况下我们需要发送一些数据到服务器中去,这就要求我们实现同网络资源的双向通信,URLConnection类就是用来解决这一问题的,URLConnection类也是定义在java.net包中,它表示java程序和URL在网络上的通信连接,URLConnection能够提供比URL更强的服务器交互作用机制。
6.1、URLConnection类的主要功能是:
1、与远程资源服务器进行交互,包括查询服务器的属性。
2、设置服务器连接的参数等。
3、另外一个功能就是获取URL资源。
6.2、类URLConnection只有一个构造方法,但是确实protected,无法通过new来创建URLConnection的实例,当与一个URL建立连接时,首先要在一个URL对象上通过方法openConnection()生成对应URLConnection对象,URLConnection是以HTTP协议为中心的类,其中很多方法只有处理HTTP的URL时才起作用。
构造实例如下: URL url = new URL("www.souhu.com");
URLConnection urlcon=url.openConnection();
URL和URLConnection之间的区别:
1、URLConnection提供了对MIME首部的访问和HTTP的响应。
2、URLConnection允许配置发项服务器的请求参数。
3、URLConnection允许用户向服务器读写数据。
6.3、URLConnection的使用步骤:
1.创建一个URL对象。
2.调用URL对象的openConnection()方法来检索这个URL的URLConnection对象。
3.设置URLConnection的参数和普通请求属性。
4.如果只是发送GET方式请求,使用connect方法建立和远程资源之间的实际连接即可,如果需要发送POST方式的请求,需要获取URLConnection实例对应的输出流来发送请求参数。
5.访问远程资源的头字段或通过输入流读取远程资源的数据。
6.4、从URLConnection读取数据的两种方式:
1.getInputStream():返回该URLConnection对应的输入流,用于获取URLConnection响应的内容。然后再使用getContent()方法处理内容。
2.getOutputStream():返回该URLConnection对应的输出流,用于向URLConnection发送请求参数。
3.如果既要使用输入流读取URLConnection响应的内容,也要使用输出流发送请求参数,一定要先使用输出流,再使用输入流。
6.6、从服务器读数据:
步骤:
1.创建一个URL对象。
2.调用URL对象的openConnection()方法来检索这个URL的URLConnection对象。
3.调用URLConnection的getInputStream()方法。
4.用常用的流API从输入流读取数据。
使用URL的openStream()方法从HTTP服务器下载文本文件,下载二进制文件,可以用URLConnection的getContentLength()先找到文件的长度,然后再准确读出这么多数目的字节。
6.7、向服务器写数据:
再使用POST向服务器提交一个表格,或PUT上传好一个文件时需要向URLConnection写数据。
getOutputStream()方法返回OutputStream,向服务器写数据,默认情况下,URLConnection不允许输出,所以必须在请求输出之前调用setDoOutput(true),把一个URL设置doOutput为true时,请求模式就由GET变成了POST。
在建立和远程资源的实际链接之前,程序可以通过如下方式来设置请求头字段:
setAllowUserInteraction:设置URLConnection的allowUserInteraction请求头字段的值。
setDoInput:设置该URLConnection的doInput请求头字段的值。
setDoOutput:设置该URLConnection的ifModifiedSince请求头字段的值。
setUseCaches:设置该URLConnection的uesCaches请求头字段的值。
除此之外,还可以使用如下方法来设置或增加通用头字段:
setRequestProperty(String key,String value):设置该URLConnection的key请求头字段值为value.
addRequestProperty(String key,String value):为该URLConnection的key请求头字段增加value值,该方法不会覆盖原请求头字段的值,而是将新值追加到原请求头字段中。
七、HttpURLConnection类
该类是URLConnection的子类,它扩展了URLConnection类的功能,提供了对HTTP协议中特有功能的支持,例如返回服务器响应的状态码。通常对网络资源的访问可以通过URL对象的openStream()或者URLConnection类提供的方法完成,但它们并不提供对HTTP协议细节上的支持。
构造方法:
同其父类一样,HttpURLConnection同样没有公共的构造函数,只有一个保护的构造函数,要获得HttpURLConnection对象的实例,还是需要通过URL对象的openConnection()方法。如果URL对象的协议被设置为HTTP协议,那么返回的URLConnection对象实际上就是一个HttpURLConnection对象
例如: