由URL下载网页、文件在android也是常见操作,其实最后也是上文说的文件流操作。
URL
/**
* Class {URL} represents a Uniform Resource
* Locator, a pointer to a "resource" on the World
* Wide Web. A resource can be something as simple as a file or a
* directory, or it can be a reference to a more complicated object,
* such as a query to a database or to a search engine.
* In general, a URL can be broken into several parts. Consider the
* following example:
* http://www.example.com/docs/resource1.html
* The URL above indicates that the protocol to use is
* {http} (HyperText Transfer Protocol) and that the
* information resides on a host machine named
* {www.example.com}. The information on that host
* machine is named {/docs/resource1.html}. The exact
* meaning of this name on the host machine is both protocol
* dependent and host dependent.
*/
URLConnection
URLConnection
public abstract class URLConnection {}
/**
* The abstract class {URLConnection} is the superclass
* of all classes that represent a communications link between the
* application and a URL. Instances of this class can be used both to
* read from and to write to the resource referenced by the URL. In
* general, creating a connection to a URL is a multistep process:
*
* [1] The connection object is created by invoking the {openConnection} method on a URL.
*
* [2]The setup parameters and general request properties are manipulated.
*
* [3] The actual connection to the remote object is made, using the {connect} method.
*
* The remote object becomes available. The header fields and the contents of the remote object can be accessed.
*/
这些方法有什么不同?对应网页不同的操作,默认用GET
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
/* Set the method for the URL request, one of:
* GET
* POST
* HEAD
* OPTIONS
* PUT
* DELETE
* TRACE
* are legal, subject to protocol restrictions. The default
* method is GET.
*/
setDoOutput: //从输入读,往输出写(设置数据流的方向)
/**
* Sets the value of the {@code doOutput} field for this
* {@code URLConnection} to the specified value.
* <p>
* A URL connection can be used for input and/or output. Set the DoOutput
* flag to true if you intend to use the URL connection for output,
* false if not. The default is false.
**/
从Web下载文件的例子
public static File downloadFile(String urlStr, String folder, String fileName) {
URL url = null;
HttpURLConnection conn = null;
InputStream inStream = null;
FileOutputStream outStream = null;
try {
//1.通过url字符串生成 URL
url = new URL(urlStr);
//2.通过URL生成HttpURLConnection
conn = (HttpURLConnection) url.openConnection();
//3.设置参数
conn.setRequestMethod(HTTP_GET);
conn.setDoOutput(false);
//4. connect
conn.connect();
//5. 如果链接成功
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileNameString = fileName;
//5.1 获得conn的InputStream 和要写入文件的outStream
inStream = conn.getInputStream();
File aimFile = new File(folder, fileNameString);
outStream = new FileOutputStream(aimFile);
//5.2 循环从InputStream 读到数据写入到 outStream
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
Log.i(TAG, "please check file of tmp.config exit or not");
return aimFile;
}
}
}
获得Web内容
和从Web上下载文件的方法基本是相同的,只是文件是 raw data流的方式,而要获得内容是获得字符的方式
url -> HttpURLConnection -> 配置参数 -> connect -> conn.getInputStream -> 以stream的方式读写
不同之处是不再是stream的方式:
InputStream -> InputStreamReader-> BufferedReader: readline -> StringBuffer -> toString
String -> JSONObject ->key:value
JSONObject(result).getString("data")//获得网页内容
public static String httpGetWebContext(Context context, String url, String sid) {
String ret = "";
url += addToken(sid);
HttpURLConnection conn = null;
URL currUrl;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader br = null;
try {
currUrl = new URL(url);
} catch (MalformedURLException e) {
return ret;
}
Log.d(TAG, "currUrl : " + currUrl);
try {
// 判断是 http 请求还是 https 请求
if (currUrl.getProtocol().toLowerCase().equals("https")) {
// Don't trust all SSL, it might cause some security issue.
// HTTPSTrustManager.allowAllSSL();
conn = (HttpsURLConnection) currUrl.openConnection();
Log.d(TAG, "use HTTPS protocol");
} else {
conn = (HttpURLConnection) currUrl.openConnection();
}
conn.setConnectTimeout(CONNECTION_TIME_OUT);
conn.setReadTimeout(SOCKET_TIME_OUT);
conn.setRequestMethod("GET");
conn.setDoOutput(false);
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
br = new BufferedReader(inputStreamReader);
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
ret = sb.toString();
}
}
}
在URL中加入Token,对访问web的请求者加了限制,
//有关加密,通过当前的时间和SID生成MD5,服务端根据传入的时间和服务端的SID生成MD5和传入的MD5比较,如果MD5两者相等,则服务端返回数据,否则访问失败。
/**
* https://xxxx/?r=123456&t=406e4ad4ae1
* r is timestamp UMT, token=md5(sid+r)
*/
public static String addToken(String sid) {
StringBuilder ret = new StringBuilder();
String r = Device.getUTCTimeStr();
if (!TextUtils.isEmpty(sid) && !TextUtils.isEmpty(r)) {
String token = Utils.MD5(sid + r);
ret.append("?r=");
ret.append(r);
ret.append("&t=");
ret.append(token);
}
return ret.toString();
}
服务端有对应的SID,URL中又传入了时间,通过MD5得到token,