- URL 的概念
- HTTP/HTTPS 协议
- 使用 URL 类
- 使用 HttpURLConnection 发送 GET 请求
- 使用 HttpURLConnection 发送 POST 请求
- 实例:Downloader 下载程序
Kotlin 可以通过使用 Java 的 java.net.URL
类进行高层次网络编程,通过 URL 类访问互联网资源。使用 URL 进行网络编程不需要掉协议本身有太多的了解,相对而言是比较简单的。
一、URL 的概念
互联网资源是通过 URL 指定的,URL 是 Uniform Resource Locator 的简称,翻译过来是 “一致资源定位器” ,但人们都习惯 URL 这个简称。
- URL 组成格式如下:
协议名://资源名
“协议名” 指明获取资源所使用的传输协议,如 http、ftp、gopher 和 file 等,“资源名” 则应该是资源的完整地址,包括主机名、端口号、文件名 或 文件内部的一个引用。
如:
http://www.baidu.com/
http://home.sohu.com/home/welcome.html
http://www.51work6.com:8800/Gamlan/network.html#BOTTOM
二、HTTP/HTTPS 协议
互联网访问大多都是基于 HTTP/HTTPS 协议。
1、HTTP 协议
HTTP 是 Hypertext Transfer Protocol 的缩写,即超文本传输协议。HTTP 是一个属于应用层的面向对象的协议,其简捷、快速的方式适用于分布式超文本信息的传输。HTTP 协议支持 C/S 网络结构,是无连接协议,即每一次请求时建立连接,服务器处理完客户端的请求后,应答给客户端然后断开连接,不会一直占用网络资源。
HTTP/1.1 协议共定义了 8 种请求函数:OPTIONS
、HEAD
、GET
、POST
、PUT
、DELETE
、TRACE
和 CONNECT
。在 HTTP 访问中,一般使用 GET
和 POST
函数。
GET 函数。向指定的资源发出请求,发送的信息 “显示” 的跟在 URL 后面。GET 函数应该只用在读取数据,例如静态图片等。GET 函数优点像使用明信片给别人写信,“信内容” 写在外面,接触到的人都可以看到,因此是不安全的。
POST 函数。向指定的资源提交数据,请求服务器进行处理,例如提交表单或者上传文件等。数据被包含在请求体中。POST 函数像是把 “信内容” 装入信封中,接触到的人都看不到,因此是安全的。
2、HTTPS 协议
HTTPS 是 Hypertext Transfer Protocol Secure 的缩写,即超文本传输安全协议,是超文本传输协议 和 SSL 的组合,用以提供加密通信及对网络服务器身份的鉴定。
简单地说,HTTPS 是 HTTP 的升级版,HTTPS 与 HTTP 的区别是:HTTPS 使用 https://
代替 http://
,HTTPS 使用端口 443,而 HTTP 使用端口 80 来与 TCP/IP 进行通信。SSL 使用 40 位关键字作为 RC4 流加密算法,这对于商业信息的加密是合适的。HTTPS 和 SSL 支持使用 X.509 数字认证,如果需要的话,用户可以确认发送者是谁。
三、使用 URL 类
java.net.URL
类用于请求互联网上的资源,采用 HTTP/HTTPS 协议,请求函数是 GET
函数,一般是请求静态的、少量的服务器端数据。
URL 类常用的构造函数如下:
-
URL(spec: String!)
。根据字符串表示形式创建 URL 对象。 -
URL(protocol: String!, host: String!, file: String!)
。根据指定的协议名、主机名 和 文件名称创建 URL 对象。 -
URL(protocol: String!, host: String!, port: Int! file: String!)
。根据指定的协议名、主机名、端口号 和 文件名称创建 URL 对象。
URL 类常用函数如下:
-
openStream()
。打开到此 URL 的连接,并返回一个输入流 InputStream 对象。 -
openConnection()
。打开到此 URL 的新连接,返回一个 URLConnection 对象。
fun main(args: Array<String>) {
val url = "http://www.baidu.com"
URL(url).openStream().use { input ->
input.bufferedReader().forEachLine {
println(it)
}
}
}
四、使用 HttpURLConnection 发送 GET 请求
由于 URL 类只能发送 HTTP/HTTPS 的 GET 函数请求,如果想进行其他函数的操作时,可以使用 HttpURLConnection
类型。
private const val urlString = "http://www.51work6.com/service/mynotes/WebService.php" +
"?email=fengxueyan@alipaycampus.com&type=JSON&action=query"
fun main(args: Array<String>) {
var conn: HttpURLConnection? = null
try {
conn = URL(urlString).openConnection() as HttpURLConnection
conn.connect()
conn.inputStream.use { input ->
val data = input.bufferedReader().readText()
println(data)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
conn?.disconnect()
}
}
// 返回数据
{
"ResultCode": 0,
"Record": [
{
"ID": 666,
"CDate": "2017-05-18",
"Content": "欢迎来到智捷课堂。"
},
{
"ID": 666,
"CDate": "2018-10-18",
"Content": "Welcome to zhijieketang."
}
]
}
五、使用 HttpURLConnection 发送 POST 请求
HttpURLConnection 也可以发送 HTTP/HTTPS 的 POST 请求,下面是使用 HttpURLConnection 发送 POST 请求的案例。
private const val urlString = "http://www.51work6.com/service/mynotes/WebService.php"
fun main(args: Array<String>) {
var conn: HttpURLConnection? = null
try {
conn = URL(urlString).openConnection() as HttpURLConnection
conn.requestMethod = "POST" // 指定POST请求
conn.doOutput = true // 设置请求过程可以传递参数给服务器
// post请求参数
val param = String.format("email=%s&type=%s&action=%s", "fengxueyan@alipaycampus.com", "JSON", "query")
DataOutputStream(conn.outputStream).use { os ->
os.writeBytes(param)
}
conn.connect()
conn.inputStream.use { input ->
val data = input.bufferedReader().readText()
println(data)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
conn?.disconnect()
}
}
// 返回数据
{
"ResultCode": 0,
"Record": [
{
"ID": 666,
"CDate": "2017-05-18",
"Content": "欢迎来到智捷课堂。"
},
{
"ID": 666,
"CDate": "2018-10-18",
"Content": "Welcome to zhijieketang."
}
]
}
六、实例:Downloader 下载程序
private const val urlString = "https://ss0.bdstatic.com/" +
"5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"
fun main(args: Array<String>) {
var conn: HttpURLConnection? = null
try {
conn = URL(urlString).openConnection() as HttpURLConnection
conn.connect()
conn.inputStream.use { input ->
BufferedOutputStream(FileOutputStream("./download.png")).use { bos ->
input.copyTo(bos)
}
}
println("下载成功!")
} catch (e: Exception) {
e.printStackTrace()
println("下载失败!")
} finally {
conn?.disconnect()
}
}