1、InetAddress
InetAddress代表IP地址,其有两个子类Inet4Address、Inet6Address,使用类方法getByName、getByAddress、getLocalHost来获取InetAddress对象:
import java.net.*;
public class Test
{
public static void main(String[] args)throws Exception
{
InetAddress ip = InetAddress.getByName("www.baidu.com"); //根据主机名或IP地址文本获得InetAddress
String str = ip.getHostName(); //"www.baidu.com"
str = ip.getHostAddress(); //"111.13.100.91"
str = ip.getCanonicalHostName(); //111.13.100.91
ip = InetAddress.getByAddress(new byte[]{111,13,100,91}); //根据原始地址获得InetAddress
str = ip.getHostName(); //"111.13.100.91"
boolean bPing = ip.isReachable(2000); //测试主机是否可达
InetAddress ipLocal = InetAddress.getLocalHost(); //获得本机IP对应的InetAddress
}
}
2、URLDecoder、URLEncoder
当URL中包含非西欧字符的时候应该将这些非西欧字符转换为"application/x-www-form-urlencoded"格式的字符串,使用URLEncoder的类方法encode()来将普通字符串转换为特殊字符串,使用URLDecoder的类方法decode()来将特殊字符转换为普通字符:
import java.net.*;
public class Test
{
public static void main(String[] args)throws Exception
{
String urlStr = URLEncoder.encode("疯狂Java学习" , "UTF-8");//指定转换时使用的字符集为utf8
System.out.println(urlStr); //%E7%96%AF%E7%8B%82Java%E5%AD%A6%E4%B9%A0
String keyWord = URLDecoder.decode(urlStr, "UTF-8");//指定转换时使用的字符集为utf8
System.out.println(keyWord); //疯狂Java学习
}
}
3、URI、URL、URLConnection、HttpURLConnection
URI(统一资源标识符)用来标识某一互联网资源,URL(统一资源定位符)表示资源在互联网上的位置,可见URL其实就是符合URI的子集。URI的格式如下:
协议名:http、https、ftp等,最后附一个冒号。
登录信息:指定用户名和密码作为身份认证,此项可选。
服务器地址:可以是域名或IP地址。
服务器端口号:此项可选,省略则为使用默认端口号。
带层次的文件路径:用来定位特指的资源。
查询字符串:针对已指定的文件路径内的资源传入任意参数,此项可选。
片段标识符:标记出已获取资源中的子资源(文档内的某个位置),该项可选而且RFC中没有明确规定其使用方法。
URL可以由协议名、主机、端口、资源组成:protocal://host:port/resourceName,如http://www.javase.org/index.php。URL中的getProtocal()、getHost()、getPort()、getFile()、getPath()、getQuery()可以分别获得URL的协议名、主机名、端口号、资源名、路径部分、查询字符串部分。
还有一个URI类,一个URI对象代表资源标识符,它用来解析。
URL的openConnection()方法用来获得一个该URL的连接对象(URLConnection类型),调用该方法不会建立网络连接。在与URL的连接建立好后,可以使用URLConnection的getInputStream方法可以获得对应的输入流(用来获得URLConnection相应的内容),getOutputStream方法获得对应的输出流(用于向URLConnection发送请求参数)。URLConnection表示与URL之间的通信连接,它是一个抽象类,HttpURLConnection是其子类,表示与URL之间的HTTP连接。在建立和远程资源的连接之前,可以通过setRequestProperty()设置通用请求头字段(请求属性),通过addRequestProperty()增加请求头字段的值。
URLPermission是一个工具类,它用于管理HttpURLConnection的权限。
每个HttpURLConnection实例用来向http服务器发出单个请求,而且与服务器的底层连接可能会与其它HttpURLConnection实例共享,调用某个HttpURLConnection实例的InputStream或OutputStream的close方法来释放当前实例的网络资源但对于其它的共享实例无影响,调用某个HttpURLConnection实例的disconnect方法则可能会导致底层连接关闭如果持久连接在那时是空闲的话。
下面是使用HttpURLConnection来获得网上指定图片大小并下载该图片的示例代码:
import java.net.*;
import java.io.*;
public class Test
{
public static void main(String[] args)throws Exception
{
URL url = new URL("http://e.hiphotos.baidu.com/image/pic/item/9358d109b3de9c82ddf742856181800a19d8432d.jpg");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000); //设置超时
conn.setRequestMethod("GET"); //设置请求方法为GET
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*"); //设置客户端希望接受的数据类型
conn.setRequestProperty("Accept-Language", "zh-CN"); //客户端希望接收的语言类型
conn.setRequestProperty("Charset", "UTF-8"); //接受的字符集
conn.setRequestProperty("Connection", "Keep-Alive"); //连接重用(长连接):http1.0中每个请求/应答客户和服务器都要新建一个连接,
//当使用Keep-Alive模式时可以使连接持续有效,避免了重新建立连接。http1.1中默认启用Keep-Alive,如果设置"Connection: close ",才关闭。
//目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求,所以是否能完成一个完整的Keep- Alive连接就看服务器设置情况了。
int fileSize = conn.getContentLength(); //获得URL指向资源的大小
System.out.println(fileSize);
InputStream inStream = conn.getInputStream();
RandomAccessFile currentPart = new RandomAccessFile("image.jpg" , "rw");
byte[] buffer = new byte[1024];
int hasRead = 0;
int length = 0;
// 读取网络数据,并写入本地文件
while ((hasRead = inStream.read(buffer)) != -1)
{
currentPart.write(buffer, 0, hasRead);
// 累计下载的总大小
length += hasRead;
}
System.out.println(length);
currentPart.close();
inStream.close();
conn.disconnect(); //指示该底层连接上无其他请求了
}
}
如果只是发送GET方式请求,则使用connect方法建立与远程资源的连接,如果是发送POST方式的请求,则需要先设置doIn和doOut两个请求头字段的值,再获取URLConnection实例对应的输出流来发送请求参数。在建立和远程资源的连接之前,还可以通过以下方法设置特定请求头字段:setAllowUserInteraction()、setDoInput()、setDoOutput()、 setIfModifiedSince()、setUseCaches()。
在与URL的连接建立好后,可以使用URLConnection的getContent()获得该URLConnection的内容,调用getHeaderField(String name)获得指定响应头字段的值,也可以调用下列方法获得特定响应头字段的值:getContentEncoding()、getContentLength()、getContentType()、getDate()、getExpiration()、getLastModifed()。
不管是发送GET请求还是POST请求,程序中获取URLConnection响应的方式完全一样:如果可以确定远程响应是字符流则可以使用字符流来读取,如果无法确定的话就使用字节流读取。
下面是向Web站点发送GET请求和POST请求,并从Web站点获取响应的示例:
import java.io.*;
import java.net.*;
import java.util.*;
public class GetPostTest
{
/**
* 向指定URL发送GET方法的请求
* @param url 发送请求的URL
* @param param 请求参数,格式满足name1=value1&name2=value2的形式。
* @return URL所代表远程资源的响应
*/
public static String sendGet(String url , String param)
{
String result = "";
String urlName = url + "?" + param; //URL与请求参数以'?'隔开
try
{
URL realUrl = new URL(urlName);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent"
, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 建立实际的连接
conn.connect();
// 获取所有响应头字段
Map> map = conn.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet())
{
System.out.println(key + "--->" + map.get(key));
}
try(
// 定义BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream() , "utf-8")))
{
String line;
while ((line = in.readLine())!= null)
{
result += "\n" + line;
}
}
}
catch(Exception e)
{
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
/**
* 向指定URL发送POST方法的请求
* @param url 发送请求的URL
* @param param 请求参数,格式应该满足name1=value1&name2=value2的形式。
* @return URL所代表远程资源的响应
*/
public static String sendPost(String url , String param)
{
String result = "";
try
{
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
try(
// 获取URLConnection对象对应的输出流
PrintWriter out = new PrintWriter(conn.getOutputStream()))
{
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
}
try(
// 定义BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader
(conn.getInputStream() , "utf-8")))
{
String line;
while ((line = in.readLine())!= null)
{
result += "\n" + line;
}
}
}
catch(Exception e)
{
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
// 提供主方法,测试发送GET请求和POST请求
public static void main(String args[])
{
// 发送GET请求
String s = GetPostTest.sendGet("http://localhost:8888/abc/a.jsp", null);
System.out.println(s);
// 发送POST请求
String s1 = GetPostTest.sendPost("http://localhost:8888/abc/login.jsp", "name=crazyit.org&pass=leegang");
System.out.println(s1);
}
}