引言
HttpURLConnection 是 Android 提供的一个轻量级 HTTP 客户端,支持多种 HTTP 方法,尽管在功能上不如之后会介绍的OkHttp复杂多样,但它在一些基本的网络请求场景下依然表现出色,简单易用和直接集成两个优点让HttpURLConnection仍是处理简单 HTTP 请求时的首选工具。
应用场景和基本用法
HttpURLConnection的应用场景相当广泛,这里以天气预报应用为例,想要实现天气预报的核心功能非常简单,只需要从服务器获取当前天气信息并向服务器发送用户的位置信息,
应用启动时需要从天气服务的API获取当前天气信息。这个需求可以通过 GET
请求来实现
fun getWeatherData(apiUrl: String): String {
val url = URL(apiUrl)
val connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.connectTimeout = 8000
connection.readTimeout = 8000
try {
val inputStream = connection.inputStream
val reader = BufferedReader(InputStreamReader(inputStream))
val response = StringBuilder()
var line: String?
while (reader.readLine().also { line = it } != null) {
response.append(line)
}
return response.toString()
} finally {
connection.disconnect()
}
}
首先创建了一个 HttpURLConnection
实例,指定 GET
作为请求方法,并设置了连接和读取超时。通过调用 connection.inputStream
方法,我们实际启动了网络连接。服务器的响应数据被读取并存储到一个 StringBuilder
中,最终返回给调用者。最后调用 connection.disconnect()
关闭连接,释放资源。
从天气服务的API获取天气信息后,应用需要向服务器上传用户的位置信息,以便获取更精准的天气预报。这个需求可以通过 POST
请求来实现
fun postUserLocation(apiUrl: String, jsonLocationData: String): String {
val url = URL(apiUrl)
val connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.connectTimeout = 8000
connection.readTimeout = 8000
connection.doOutput = true
try {
val outputStream = connection.outputStream
outputStream.write(jsonLocationData.toByteArray())
outputStream.flush()
val inputStream = connection.inputStream
val reader = BufferedReader(InputStreamReader(inputStream))
val response = StringBuilder()
var line: String?
while (reader.readLine().also { line = it } != null) {
response.append(line)
}
return response.toString()
} finally {
connection.disconnect()
}
}
对于 POST
请求的实现,我们同样创建了一个 HttpURLConnection
实例,但这次指定 POST
作为请求方法。我们通过设置 doOutput = true
来允许将数据发送到服务器。之后,我们将位置信息的 JSON 字符串写入输出流,并读取服务器的响应,返回结果。最后,同样关闭连接。
这个天气预报场景中的 GET
和 POST
请求示例代码本身是可以运行的,但要在应用中跑,还需要一些额外的配置和数据准备。首先需要一个有效的天气服务 API 网址,例如OpenWeatherMap、高德天气 API等等,此外对于 POST
请求,假设你要发送用户位置信息,数据需要以 JSON 格式提供,最后你需要确保在 AndroidManifest.xml
中声明了网络访问权限。
扩展
除了基本的 GET
和 POST
请求,HttpURLConnection还有一些进阶的使用技巧
身份验证
在开发中,有时需要在请求中附带身份验证信息,比如在访问受限的 API 资源时,通过在请求头中添加 Authorization 头部来携带 Token。这种情况下,我们可以使用 HttpURLConnection
来设置自定义请求头。
connection.setRequestProperty("Authorization", "Bearer your_token_here")
通过 setRequestProperty
方法为请求添加了一个 Authorization
头部,用于向服务器提供身份验证信息,可以让请求满足特定的 API 访问需求 。
处理重定向
当我们要跟踪用户行为或处理某些特定的重定向逻辑时,我们可能需要手动处理 HTTP ,这时我们可以通过禁用 HttpURLConnection
的自动重定向处理,并在代码中自定义重定向行为。
connection.instanceFollowRedirects = false
通过设置 instanceFollowRedirects
为 false
,禁用默认的重定向行为,并手动处理服务器返回的重定向响应。
上传文件
在处理文件上传时,HttpURLConnection
同样能够胜任。通过设置 Content-Type
为 multipart/form-data
并在请求体中包含文件数据,从而可以实现文件的上传操作。
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=boundary")
这个设置告诉服务器,请求体中可能包含多个部分数据(即文件和表单数据),并使用特定的边界字符串 boundary
来分隔各部分内容。这样,服务器就可以正确解析上传的文件和其他表单数据。
总结
HttpURLConnection
作为 Android 系统提供的原生 HTTP 请求工具,尽管功能相对简单,但它仍然具备处理基本网络请求的能力。其轻量级和系统内置的特性,使得 HttpURLConnection
在一些简单或对性能要求较高的场景中仍然被广泛使用。
然而,随着现代应用对网络请求的复杂性和高效性的要求越来越高,HttpURLConnection
的局限性也逐渐显现。比如,处理复杂的网络请求、增强的连接池管理、更好的性能优化等需求,往往需要更强大的工具来应对,OkHttp
作为一个开源的 HTTP 客户端,提供了许多 HttpURLConnection
所不具备的高级特性。它不仅能够更高效地处理并发请求,还拥有丰富的扩展能力,使得网络请求更加简洁和可靠,我们将在下一篇更深入的了解它。