[本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.youkuaiyun.com/jesson20121020]
统一资源定位符URL
URL(Uniform Resource Locator)表示Internet上某一资源的地址,通过URL我们可以访问internet上的各种网络资源,比如最常见的WWW,FTP站点.
URL的组成:
protocol://resourceName
协议名(protocol)指明获取资源所使用的传输协议,如http,ftp,gopher,file等,资源名(resourceName)则应该是资源的完整地址,包括主机名、端口号、文件名或文件内部的一个引用。如:
协议名://主机名
http://www.sun.com
协议名://主机名+文件名
http://www.sun.com/index.html
协议名://主机名+端口号+文件名+内部引用
http://www.sun.com:80/index.html#内部引用
创建URL:
java.net 中实现了URL类,并提供了以下几种构造方法:
//通过一个表示URL地址的字符串来构造一个URL对象
public URL(String spec);
// 通过基URL和相对URL构造一个URL对象
public URL(URL context,String spec);
如:URL net263 = new URL("http://www.263.net");
URL index263 = new URL(net263,"index.html");
// 通过协议,主机名和文件名来创建URL
public URL(String protocal,String host,String file);
// 通过协议,主机名,端口号和文件名来创建URL
public URL(String protocal,String host,int port,String file);
解析URL:
一个URL对象生成后,其属性是不能被改变的,但是我们可能通过类URL所提供的方法来攻取这些属性:
<pre name="code" class="java"> public String getProtocol(); // 获取该URL的协议名
public String getHost(); //获取该URL的主机名
public int getPost(); // 获取该URL的端口号,如果没有设置端口号,则返回-1
public String getFile(); //获取该URL的文件名
public String getPath(); // 获取该URL的路径
public String getUserInfo(); // 获取该URL的使用者信息
读取指定URL的网络资源
当我们得到一个URL对象时,就可以通过它读取到指定www资源,这时我们可以使用URL的方法openStream()与指定的URL建立连接并返回InputStream类的对象以从这一连接中读取数据,看以下的例子:
/**
* 通过URL的openStream读取指定网络数据
*/
private static void testOpenStream(String urlString) {
try {
URL url = new URL(urlString);
InputStream in = url.openStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));
System.out.println("获得的服务器内容:");
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out
.println("----------------------------------------------------");
}
通过URL的方法openStream()方法只能从网络中读取数据,如果我们同时还想输出数据时,我们必须先与URL建立连接,然后才能对其进行读写,这时就要使用URLConnection类了。
类URLConnection也可以在java.net中定义,它表示java程序和URL在网络上的通信连接,当与一个URL建立连接时,通过URL的openConnection方法返回一个URLConnection对象,此对象提供了很多方法,其中,getInputStream()和getOutputStream()方法是最常用的方法,用来获取网络的输入流和输出流。
此外,与URL通信有两种方式,一种是Post请求,一种是Get请求,下面的例子详细说明了两种请求的详细用法。
/**
* 通过URL的openConnection方法来与服务器交互 Post请求F
*/
private static void testURLPost(String urlString, String param) {
System.out.println("Post请求......");
PrintWriter pWriter = null;
BufferedReader in = null;
try {
URL url = new URL(urlString);
URLConnection urlConnection = url.openConnection();
// 设置是否向UrlConnection输出,因为这个是post请求,参数要放在正文内,因此需要设为true,
// 默认情况下是false;
urlConnection.setDoOutput(true);
// 设置是否从UrlConnection读入,默认情况下是true;
urlConnection.setDoInput(true);
// Post 请求不能使用缓存
urlConnection.setUseCaches(false);
// 此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,所以在开发中不调用上述的connect()也可以)。
// 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。
pWriter = new PrintWriter(urlConnection.getOutputStream());
// 向数据流中写出数据,这些数据将存到内存缓冲区中
pWriter.print(param);
// 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)
pWriter.flush();
// 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,
// 在调用下边的getInputStream()函数时才把准备好的请求正式发送到服务器
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
// 获取所有响应头字段
Map<String, List<String>> map = urlConnection.getHeaderFields();
System.out.println("响应头字段:");
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
System.out.println("Post请求返回结果:");
String line1 = null;
while ((line1 = in.readLine()) != null) {
System.out.println(line1);
}
pWriter.flush();
System.out
.println("----------------------------------------------------");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (pWriter != null)
pWriter.close();
if (in != null)
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 向服务器发送数据Get请求
*
* @param urlString
*/
private static void testURLGet(String urlString) {
System.out.println("Get请求......");
BufferedReader in = null;
try {
URL url = new URL(urlString);
// 打开和URL之间的连接
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = urlConnection.getHeaderFields();
System.out.println("响应头字段:");
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String line;
System.out.println("Get请求返回结果:");
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
下面给出全部代码,并演示执行结果:
URLDemo.java
package com.jesson.mianshi.network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
public class URLDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 通过URL的openStream读取指定网络数据
String urlString = "http://excise001.sinaapp.com/login.html";
testOpenStream(urlString);
// Post请求
String urlString2 = "http://excise001.sinaapp.com/handle_login.php";
testURLPost(urlString2, "username=jesson&password=20121020");
// Get请求
String urlString3 = urlString2 + "?username=jesson&password=20121020";
testURLGet(urlString3);
}
/**
* 通过URL的openStream读取指定网络数据
*/
private static void testOpenStream(String urlString) {
try {
URL url = new URL(urlString);
InputStream in = url.openStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));
System.out.println("获得的服务器内容:");
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out
.println("----------------------------------------------------");
}
/**package com.jesson.mianshi.network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
public class URLDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 通过URL的openStream读取指定网络数据
String urlString = "http://excise001.sinaapp.com/login.html";
testOpenStream(urlString);
// Post请求
String urlString2 = "http://excise001.sinaapp.com/handle_login.php";
testURLPost(urlString2, "username=jesson&password=20121020");
// Get请求
String urlString3 = urlString2 + "?username=jesson&password=20121020";
testURLGet(urlString3);
}
/**
* 通过URL的openStream读取指定网络数据
*/
private static void testOpenStream(String urlString) {
try {
URL url = new URL(urlString);
InputStream in = url.openStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));
System.out.println("获得的服务器内容:");
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out
.println("----------------------------------------------------");
}
/**
* 通过URL的openConnection方法来与服务器交互 Post请求F
*/
private static void testURLPost(String urlString, String param) {
System.out.println("Post请求......");
PrintWriter pWriter = null;
BufferedReader in = null;
try {
URL url = new URL(urlString);
URLConnection urlConnection = url.openConnection();
// 设置是否向UrlConnection输出,因为这个是post请求,参数要放在正文内,因此需要设为true,
// 默认情况下是false;
urlConnection.setDoOutput(true);
// 设置是否从UrlConnection读入,默认情况下是true;
urlConnection.setDoInput(true);
// Post 请求不能使用缓存
urlConnection.setUseCaches(false);
// 此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,所以在开发中不调用上述的connect()也可以)。
// 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。
pWriter = new PrintWriter(urlConnection.getOutputStream());
// 向数据流中写出数据,这些数据将存到内存缓冲区中
pWriter.print(param);
// 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)
pWriter.flush();
// 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,
// 在调用下边的getInputStream()函数时才把准备好的请求正式发送到服务器
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
// 获取所有响应头字段
Map<String, List<String>> map = urlConnection.getHeaderFields();
System.out.println("响应头字段:");
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
System.out.println("Post请求返回结果:");
String line1 = null;
while ((line1 = in.readLine()) != null) {
System.out.println(line1);
}
pWriter.flush();
System.out
.println("----------------------------------------------------");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (pWriter != null)
pWriter.close();
if (in != null)
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 向服务器发送数据Get请求
*
* @param urlString
*/
private static void testURLGet(String urlString) {
System.out.println("Get请求......");
BufferedReader in = null;
try {
URL url = new URL(urlString);
// 打开和URL之间的连接
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = urlConnection.getHeaderFields();
System.out.println("响应头字段:");
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String line;
System.out.println("Get请求返回结果:");
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
* 通过URL的openConnection方法来与服务器交互 Post请求F
*/
private static void testURLPost(String urlString, String param) {
System.out.println("Post请求......");
PrintWriter pWriter = null;
BufferedReader in = null;
try {
URL url = new URL(urlString);
URLConnection urlConnection = url.openConnection();
// 设置是否向UrlConnection输出,因为这个是post请求,参数要放在正文内,因此需要设为true,
// 默认情况下是false;
urlConnection.setDoOutput(true);
// 设置是否从UrlConnection读入,默认情况下是true;
urlConnection.setDoInput(true);
// Post 请求不能使用缓存
urlConnection.setUseCaches(false);
// 此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,所以在开发中不调用上述的connect()也可以)。
// 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。
pWriter = new PrintWriter(urlConnection.getOutputStream());
// 向数据流中写出数据,这些数据将存到内存缓冲区中
pWriter.print(param);
// 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)
pWriter.flush();
// 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,
// 在调用下边的getInputStream()函数时才把准备好的请求正式发送到服务器
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
// 获取所有响应头字段
Map<String, List<String>> map = urlConnection.getHeaderFields();
System.out.println("响应头字段:");
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
System.out.println("Post请求返回结果:");
String line1 = null;
while ((line1 = in.readLine()) != null) {
System.out.println(line1);
}
pWriter.flush();
System.out
.println("----------------------------------------------------");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (pWriter != null)
pWriter.close();
if (in != null)
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 向服务器发送数据Get请求
*
* @param urlString
*/
private static void testURLGet(String urlString) {
System.out.println("Get请求......");
BufferedReader in = null;
try {
URL url = new URL(urlString);
// 打开和URL之间的连接
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = urlConnection.getHeaderFields();
System.out.println("响应头字段:");
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String line;
System.out.println("Get请求返回结果:");
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
执行上述代码,运行结果如下:
获得的服务器内容:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en" />
<title>注册</title>
</head>
<body>
<form action="handle_login.php" method="get">
<p>用户名:<input type="text" class="text" name="username" />
<p>密码: <input type="text" class="text" name="password" />
<p><input type="submit" name="submit" value="登录" />
</form>
</body>
</html><script type="text/javascript">!function(){var closed=false,bdiv;var charset=document.charset||document.characterSet;var utf8=['该页面的提供者尚未完成','实名认证','您的访问可能存在风险'];var gbk=['��ҳ����ṩ����δ���','ʵ����֤','��ķ��ʿ��ܴ��ڷ���'];var en=['The provider of this page is not','verified','there are risks when you visiting'];function banner(){var char=charset.toLowerCase(),lang='';switch(true){case char.indexOf('utf')==0:lang=utf8;break;case char.indexOf('gb')==0:lang=gbk;break;default:lang=en;}var _div='<div style="position:fixed;_position:absolute;top:0;left:0;right:0;padding:12px;background-color:rgba(0,0,0,0.5);filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7F000000,endcolorstr=#7F000000);color:#fff;text-align:center;font-size:16px;font-family:simsun,serif;cursor:default;z-index:2147483647;"><p style="margin:0;padding:0;">'+lang[0]+' <a style="text-decoration:none;color:#37afe4;" target="_blank" href="http://sae.sina.com.cn/?m=faq&a=view&doc_id=22">'+lang[1]+'</a> '+lang[2]+'</p><a style="position:absolute;right:12px;top:50%;font-size:20px;color:#fff;border:none;margin:0;padding:0;;margin-top:-10px;line-height:20px;background:none;cursor:pointer;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;outline:none;">x</a></div>',div=document.createElement('div');div.innerHTML=_div;var close=div.getElementsByTagName('a')[1],x=0,y=0;close.οnmοuseοver=function(event){var e=event?event:window.event;x=e.clientX;y=e.clientY;};close.οnclick=function(event){if(event&&!event.initMouseEvent){return}var e=event?event:window.event;if(Math.abs(e.clientX-x)<10&&Math.abs(e.clientY-y)<10){div.style.display='none';closed=true;}};return div}function t(){if(closed){clearInterval(tt);return}if(bdiv&&bdiv.parentNode){bdiv.parentNode.removeChild(bdiv)}bdiv=banner();document.body.appendChild(bdiv);}t();var tt=setInterval(t,5000);}();</script>
----------------------------------------------------
Post请求......
响应头字段:
null--->[HTTP/1.1 200 OK]
Transfer-Encoding--->[chunked]
Date--->[Thu, 16 Apr 2015 13:41:48 GMT]
Via--->[10.67.15.22]
Set-Cookie--->[saeut=123.138.79.12.1429191708765018; path=/; max-age=311040000]
Connection--->[keep-alive]
Content-Type--->[text/html]
Server--->[nginx/1.4.4]
Post请求返回结果:
{"login_flag":"login success"}<script type="text/javascript">!function(){var closed=false,bdiv;var charset=document.charset||document.characterSet;var utf8=['该页面的提供者尚未完成','实名认证','您的访问可能存在风险'];var gbk=['��ҳ����ṩ����δ���','ʵ����֤','��ķ��ʿ��ܴ��ڷ���'];var en=['The provider of this page is not','verified','there are risks when you visiting'];function banner(){var char=charset.toLowerCase(),lang='';switch(true){case char.indexOf('utf')==0:lang=utf8;break;case char.indexOf('gb')==0:lang=gbk;break;default:lang=en;}var _div='<div style="position:fixed;_position:absolute;top:0;left:0;right:0;padding:12px;background-color:rgba(0,0,0,0.5);filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7F000000,endcolorstr=#7F000000);color:#fff;text-align:center;font-size:16px;font-family:simsun,serif;cursor:default;z-index:2147483647;"><p style="margin:0;padding:0;">'+lang[0]+' <a style="text-decoration:none;color:#37afe4;" target="_blank" href="http://sae.sina.com.cn/?m=faq&a=view&doc_id=22">'+lang[1]+'</a> '+lang[2]+'</p><a style="position:absolute;right:12px;top:50%;font-size:20px;color:#fff;border:none;margin:0;padding:0;;margin-top:-10px;line-height:20px;background:none;cursor:pointer;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;outline:none;">x</a></div>',div=document.createElement('div');div.innerHTML=_div;var close=div.getElementsByTagName('a')[1],x=0,y=0;close.οnmοuseοver=function(event){var e=event?event:window.event;x=e.clientX;y=e.clientY;};close.οnclick=function(event){if(event&&!event.initMouseEvent){return}var e=event?event:window.event;if(Math.abs(e.clientX-x)<10&&Math.abs(e.clientY-y)<10){div.style.display='none';closed=true;}};return div}function t(){if(closed){clearInterval(tt);return}if(bdiv&&bdiv.parentNode){bdiv.parentNode.removeChild(bdiv)}bdiv=banner();document.body.appendChild(bdiv);}t();var tt=setInterval(t,5000);}();</script>
----------------------------------------------------
Get请求......
响应头字段:
null--->[HTTP/1.1 200 OK]
Transfer-Encoding--->[chunked]
Date--->[Thu, 16 Apr 2015 13:41:48 GMT]
Via--->[10.67.15.48]
Set-Cookie--->[saeut=123.138.79.12.1429191708839430; path=/; max-age=311040000]
Connection--->[keep-alive]
Content-Type--->[text/html]
Server--->[nginx/1.4.4]
Get请求返回结果:
{"login_flag":"login success"}<script type="text/javascript">!function(){var closed=false,bdiv;var charset=document.charset||document.characterSet;var utf8=['该页面的提供者尚未完成','实名认证','您的访问可能存在风险'];var gbk=['��ҳ����ṩ����δ���','ʵ����֤','��ķ��ʿ��ܴ��ڷ���'];var en=['The provider of this page is not','verified','there are risks when you visiting'];function banner(){var char=charset.toLowerCase(),lang='';switch(true){case char.indexOf('utf')==0:lang=utf8;break;case char.indexOf('gb')==0:lang=gbk;break;default:lang=en;}var _div='<div style="position:fixed;_position:absolute;top:0;left:0;right:0;padding:12px;background-color:rgba(0,0,0,0.5);filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7F000000,endcolorstr=#7F000000);color:#fff;text-align:center;font-size:16px;font-family:simsun,serif;cursor:default;z-index:2147483647;"><p style="margin:0;padding:0;">'+lang[0]+' <a style="text-decoration:none;color:#37afe4;" target="_blank" href="http://sae.sina.com.cn/?m=faq&a=view&doc_id=22">'+lang[1]+'</a> '+lang[2]+'</p><a style="position:absolute;right:12px;top:50%;font-size:20px;color:#fff;border:none;margin:0;padding:0;;margin-top:-10px;line-height:20px;background:none;cursor:pointer;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;outline:none;">x</a></div>',div=document.createElement('div');div.innerHTML=_div;var close=div.getElementsByTagName('a')[1],x=0,y=0;close.οnmοuseοver=function(event){var e=event?event:window.event;x=e.clientX;y=e.clientY;};close.οnclick=function(event){if(event&&!event.initMouseEvent){return}var e=event?event:window.event;if(Math.abs(e.clientX-x)<10&&Math.abs(e.clientY-y)<10){div.style.display='none';closed=true;}};return div}function t(){if(closed){clearInterval(tt);return}if(bdiv&&bdiv.parentNode){bdiv.parentNode.removeChild(bdiv)}bdiv=banner();document.body.appendChild(bdiv);}t();var tt=setInterval(t,5000);}();</script>
以上就是基于URL高层次的java网络编程,下节会给出基于Socket低层次java网络编程。