Java为网络支持提供了 java.net 包。
包括 URL和 URLConnection等类。
InetAddress类代表 IP 地址, 包含2个子类:
Inet4Address : 代表 IPv4, Internet Protocol version 4
Inet6Address: 代表 IPv6, Internet Protocol version 6
InetAddress没有提供构造器, 提供下面两个静态方法获取InetAddress实例。
getByName(String host) : 根据主机名
getByAddress(byte[] addr): 根据原始IP地址
提供下面方法获取对应IP和主机名
getCanonicalHostName():获取全限定名称
getHostAddress():获取IP字符串
getHostName(): 获取主机
在isReachable(timeOut), 测试是否可达地址。
代码实现中–目前其实在WINDOWS平台,并没有采用ICMP协议来完成,而是采用TCP的PORT 7来完成功能的。因而不是通常从们所讲的PING的程序
public class InetAddressTest {
public static void main(String[] args) throws Exception{
InetAddress ip = InetAddress.getByName("www.baidu.com");
System.out.println("是否可达:" + ip.isReachable(2000));
//获取ip字符串
System.out.println(ip.getHostAddress());
InetAddress local = InetAddress.getByAddress(new byte[]{127, 0, 0, 1});
System.out.println("是否可达:" + local.isReachable(2000));
System.out.println(local.getCanonicalHostName());
}
}
//Output
是否可达:false
220.181.111.37
是否可达:true
localhost
URLEncoder 和 URLDecoder, 完成普通字符串和 application/x-www-form-urlencoded
MIME类型之间的转换。
包含西欧字符的普通字符串不会转换, 中文字符会转换, 每个中文字符占两个字节,可以转成2个16进制的数字, “%XX%XX”, 格式。
转换时需要指定字符集, 字符集不同对应的字节数,并不完全相同。
String urlStr = URLEncoder.encode("普通", "GBK");
System.out.println(urlStr);
String word = URLDecoder.decode(urlStr, "GBK");
System.out.println(word);
urlStr = URLEncoder.encode("普通", "utf-8");
System.out.println(urlStr);
word = URLDecoder.decode(urlStr, "utf-8");
System.out.println(word);
//Output
%C6%D5%CD%A8
普通
%E6%99%AE%E9%80%9A
普通
URI Uniform Resource Identifiers 统一资源标识符。作用是解析, 不能用于定位任何资源。
URL Uniform Resource Locator 统一资源定位器,
包含一个可打开到达该资源的输入流。 格式:
protocal://host:port/resourceName
URL 类提供了多个构造器用于创建URL对象, 下面方法可访问该URL对应的资源
getFile(): 获取资源名
getHost(): 获取主机
getPath(): 获取路径
getPort(): 端口
getProtocol(): 协议
getQuery(): 获取查询字符串
UrlConnection openConnection(): 返回 UrlConnection 对象,代表与URL所引用的远程对象的连接
openStream(): 打开连接, 返回一个用于读取该URL资源的InputStream。
创建URL连接, 发送请求。
发送 GET请求
public class HttpForGet {
/**
* 执行一个HTTP GET请求,返回请求响应的HTML
*
* @param url
* 请求的URL地址
* @param headers
* 请求的查询参数,可以为null
* @return 返回请求响应的HTML
*/
public static String doGet(String url, HashMap<String, String> headers) {
URL obj = null;
String result = "";
try {
obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
for(String item : headers.keySet()) {
con.setRequestProperty(item, headers.get(item));
}
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
result = response.toString();
} catch (Exception e) {
logger.error("doGet url={}", url, e);
}
return result;
}
}
发送POST请求:
public class HttpForPost {
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String postData(String url, String param, HashMap<String, String> headers) {
PrintWriter out = null;
BufferedReader in = null;
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)");
//add request header
for (String item : headers.keySet()) {
conn.setRequestProperty(item, headers.get(item));
}
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
logger.error("error in HttpForPost", e);
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
logger.error("error in HttpForPost", ex);
}
}
return result;
}
}
URLPermission工具类, 用于管理 HttpURLConnection的权限问题。
java.net 下有 Proxy 和 ProxySelector 两个类。
Proxy代表一个代理服务器, 在打开 UrlConnection 时指定 Proxy, 创建Socket时也可以指定Proxy。
public class Proxy {
/**
* Represents the proxy type.
*
* @since 1.5
*/
public enum Type {
/**
* Represents a direct connection, or the absence of a proxy.
*/
DIRECT,
/**
* Represents proxy for high level protocols such as HTTP or FTP.
*/
HTTP,
/**
* Represents a SOCKS (V4 or V5) proxy.
*/
SOCKS
};
public Proxy(Type type, SocketAddress sa) {}
代理样例:
URL url = new URL("http://www.baidu.com");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3000));
URLConnection connection = url.openConnection(proxy);
connection.setConnectTimeout(10000);
ProxySelector 为代理选择器,
ProxySelector 是一个抽象类,用户可以自己继承实现代理选择器,
实现下面两个方法:
public abstract List
public abstract void connectFailed(URI uri, SocketAddress sa, IOException ioe); 代理失败时回调该方法。
使用样例:
ProxySelector.setDefault(new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
List<Proxy> result = new ArrayList<>();
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3000));
result.add(proxy);
return null;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
System.out.println("connect proxy fail");
}
});
URL url = new URL("http://www.baidu.com");
URLConnection connection = url.openConnection();
ProxySelector 总会返回一个固定的代理服务器, 程序默认使用该代理服务器
上面 openConnection 虽然没有指定Proxy, 还是会使用代理服务器。