URLConnection类
这是一个抽象类,与URL类相比,主要有以下不同点
1、对与服务器的通信提供了更多的控制,如检查、设置首部,使用put post等http方法
2、URLConnection是Java协议处理器(protocol hanler)的一部分,该部分还包括URLStreamHandler,将协议的细节和数据处理分开
3、URLConnection还可以向服务器写入数据
URLConnection的构造方法是protected的,即只能由URLConnection和他的子类访问,除非派生URLConnection处理新的URL类型,否则使用URL获取;在运行时,一般由使用的协议创建所需的对象,然后使用 java.lang.Class的forName()和newInstance()实例化URLConnection对象;抽象类URLConnection的connect()方法没有实现,因子子类必须实现该方法,完成与服务器的连接(该方法依赖于服务类型);
打开URLConnection的一般步骤
1、构造URL对象
2、调用该对象的openConnection(),获取URLConnection对象
3、配置URLConnection(可选)
4、读取首部(可选)
5、获得输入流并读取数据
6、获得输出流并写入数据
7、关闭连接
Note:第一次构建URLConnection时,实际的连接没有打开,即没有socket连接,需要使用connect()建立连接,而一般而言,connect()是隐式调用的,需要打开连接的方法会在连接未建立是使用connect()建立连接,如getInputStream(),getContent()等
从服务器读取数据
1、构建URL对象
2、获得URLConnection对象
3、调用URLConnection的getInputStream()方法
4、使用常规API读取数据
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class SourceViewer2 {
public static void main(String[] args) {
String url = "https://www.baidu.com";
try {
//构造URL
URL u = new URL(url);
// 获取URLConnection对象
URLConnection connection = u.openConnection();
// 打开输入流
try (InputStream raw = connection.getInputStream()) {// 自动关闭
// 使用常规API读取数据
Reader reader = new InputStreamReader(raw);
int c;
while((c = reader.read()) != -1) {
System.out.print((char) c);
}
}
} catch (MalformedURLException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
}
获取指定的首部字段
getContenType,获取MIME的完整内容类型,没有类型则返回null,
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class EncodeingAwareSourceViewer {
public static void main(String[] args) {
String url = "https://www.baidu.com";
try {
String defaultEncoding = "ISO-8859-1";
URL u = new URL(url);
URLConnection connection = u.openConnection();
// 获取响应的MIME类型
String encodingType = connection.getContentType();
int encodingStart = encodingType.indexOf("charset=");
if(encodingStart != -1) {
defaultEncoding = encodingType.substring(encodingStart+8);
System.out.println(defaultEncoding);
}
InputStream in = new BufferedInputStream(connection.getInputStream());
Reader reader = new InputStreamReader(in, defaultEncoding);
int c;
while((c = reader.read()) != -1) {
System.out.print((char) c);
}
reader.close();
} catch (MalformedURLException e) {
System.out.println(e);
} catch (UnsupportedEncodingException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
}
getContentLength,获取内容的大小,没有则返回-1;注意,getContenLength有可能因为内容过大超出int的范围而返回-1,这时可以使用Java 7 的getContentLengthLong,返回long型数据;该方法可以用来控制在接收多少数据后关闭连接
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class BinarySaver {
public static void main(String[] args) throws IOException {
String url = "http://img3.kwcdn.kuwo.cn/star/KuwoArtPic/2013/7/1396927592034_w.jpg";
try {
URL u = new URL(url);
saveBinaryFile(u);
} catch (MalformedURLException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
public static void saveBinaryFile(URL url) throws IOException {
URLConnection connection = url.openConnection();
String contentType = connection.getContentType();
int contentLength = connection.getContentLength();
// 判断文件类型,确保得到一个长度已知的二进制文件
if (contentType.startsWith("text/") || contentLength == -1) {
System.out.println(contentType);
System.out.println(contentLength);
throw new IOException("this is not a binary file");
}