统一资源定位符(URL),有时候也被俗称为“网址”,它们的存在就如同在网络上的门牌,是网络上标准资源的地址,是网络中最基础的部分。
URL 标准格式如下:
协议类型://服务器地址:端口/路径/文件名
Java 提供了一系列 API 来解析 URL 的,捡常用的说一下:
public class NetTest {
public static void main(String[] args) {
try {
URL url = new URL("https://www.li-xyz.com:1443/content/images/2017/02/sp170223_205027.png");
System.out.println("此 URL 的文件名:"+url.getFile());
System.out.println("此 URL 的主机名:"+url.getHost());
System.out.println("此 URL 的路径:"+url.getPath());
System.out.println("此 URL 的协议:"+url.getProtocol());
System.out.println("此 URL 的端口:"+url.getPort());
System.out.println("此 URL 的查询部分:"+url.getQuery());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果
此 URL 的文件名:/content/images/2017/02/sp170223_205027.png
此 URL 的主机名:www.li-xyz.com
此 URL 的路径:/content/images/2017/02/sp170223_205027.png
此 URL 的协议:https
此 URL 的端口:-1
此 URL 的查询部分:null
因为我们没有指定端口,所以返回值为 -1。
为啥查询部分是 null 呢?
我们把 URL 修改一下:
URL url = new URL("https://www.li-xyz.com:1443/content/images?username=123&password=456");
这个时候 URL 的查询结果就是:
username=123&password=456
URL 还有两个重要的方法:openConnection() 和 openStream()。
该方法返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。获取到了连接之后,我们就可以读取或者写入此 URL 所代表的资源,在下面会讲到。
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
此打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream,然后就可以读取 URL 所指向的文件的内容了
一个小例子:
public class NetTest {
public static void main(String[] args) {
try {
URL url = new URL("https://www.li-xyz.com:1443/content/images/2017/02/sp170223_205027.png");
InputStream is = url.openStream();
byte[] buf = new byte[1024];
int len = 0;
FileOutputStream fos = new FileOutputStream(new File("D:\\newPic.png"));
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
System.out.println("111");
fos.flush();
}
fos.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
然后就将这个图片下载到本地了。
URLConnection 是一个抽象类,代表着我们的客户端和 URL 之间的通信链接,此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:
Java 提供了一下方法来帮我们修改连接参数
使用 setRequestProperty 方法来修来请求属性。
请求属性就不用多说了,在《网络编程总结(二):HTTP 协议》一文中列取了常用的请求属性,当然我们也可以自定义我们自己的请求属性。
在获取到远程连接之后,可以使用以下方法来获取访问头字段和内容:
我们经常使用的是 URLConnection 的子类 HttpURLConnection。
HttpURLConnection 是支持 HTTP 特定功能的 URLConnection,每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。
HttpURLConnection 有几个重要的方法:
一个简单的小例子:
服务器端就是简单的从请求中获取到输入流,然后输出到本地。
UploadServlet
public class WelcomeServlet extends HttpServlet {
private String greeting;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doPost方法");
ServletInputStream is = req.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
FileOutputStream fos = new FileOutputStream(
new File("D:\\HAHAHAHA.PNG"));
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
fos.flush();
}
is.close();
fos.close();
System.out.println("OK");
}
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (request.getMethod().equals("GET")) {
doGet(request, response);
} else if (request.getMethod().equals("POST")) {
doPost(request, response);
}
}
}
客户端获取到连接,然后获取输出流,将文件输出
public class NetTest {
public static void main(String[] args) {
try {
URL url = new URL("http://127.0.0.1:8080/ServletTest/upload");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
FileInputStream fis = new FileInputStream(new File("C:\\Users\\LGB\\Desktop\\Pics\\sp170223_185642.png"));
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
os.write(buf, 0, len);
os.flush();
}
System.out.println("OK");
os.close();
fis.close();
InputStream inputStream = conn.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
}