基于原生URL和URLConnection的请求组件
介绍
java的http组件有很多比如httpClient、okHttp等,但是其实java.net包就自带了原生的访问http资源的类(URL、URLConnection),学会原生的对我们理解和使用第三方组件也很有帮助,原生包的缺点就是编程相对繁琐,扩展不易。第三方组件相对而言功能强大扩展好,但是它们底层其实还是基于java.net原生类的。
URL类
URL:统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的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.
备注
URI:统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。
URL是URI的一个子集,事实上我们更多的是直接使用URL而不是URI来表示资源
http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html
对这个URL进行分析:
http:指的是使用何种协议进行交流
www.socs.uts.edu.au:指的是请求的主机名(根据DNS查找出对应的ip地址)
MosaicDocs-old/url-primer.html:指的是资源目录(路径)
URLConnection类
URLConnection类表示一个C/S连接,其最常用的实现是HttpURLConnection类(基于http协议实现的连接,还有ftp协议实现等)。
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.
备注 URLConnection对象是由URL对象的openConnection()方法获得的。
HttpURLConnection类核心方法
abstract public class HttpURLConnection extends URLConnection {
public void setRequestMethod(String method) throws ProtocolException {}//重点掌握
public int getResponseCode() throws IOException {}//重点掌握
//Returns an input stream that reads from this open connection.
//设置输入流就是为了获得请求体里的数据
public InputStream getInputStream() throws IOException {}//重点掌握
//Returns an output stream that writes to this connection.
//获得这个输出流其实就是为了向请求体里增加数据
public OutputStream getOutputStream() throws IOException {}//重点掌握
//设置从HttpURLConnection对象能否获得输入和输出流
public void setDoInput(boolean doinput) {}//默认为true(因为很常用所以设置为true),重点掌握
//如果是post方法时,就一定要设置为true
public void setDoOutput(boolean dooutput) {}//默认为false,重点掌握
//Sets the general request property. If a property with the key already
//exists, overwrite its value with the new value.
//就是设置请求头信息
public void setRequestProperty(String key, String value) {}
public Map<String,List<String>> getRequestProperties() {}
}
基于URL和URLConnection工具类
/**
* 基于原生java.net的URL和URLConnection的封装的HttpUtils请求工具
*
* @author xuyi3
* @2016年6月24日 @下午3:09:27
* @HttpUtils
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class HttpUtils {
/**
* 基于java原生的URL和URLConnection发送get请求
*
* @param urlPath
* 请求地址
* @return response data
*/
public static String sendGet(final String urlPath) {
// 响应数据流
InputStream inputStream = null;
// 请求返回数据
StringBuilder stringBuilder = new StringBuilder();
try {
// 新建一个URL对象
URL url = new URL(urlPath);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
// 设置请求方法
httpUrlConnection.setRequestMethod("GET");
httpUrlConnection.setRequestProperty("connection", "Keep-Alive");
// 设置一系列请求头 ...
httpUrlConnection.setRequestProperty("Accept-Charset", "UTF-8");
// httpUrlConnection.setRequestProperty(key, value);//设置请求头
int responseCode = httpUrlConnection.getResponseCode();
if (responseCode != 200) {
return "request fail code" + responseCode;
}
inputStream = httpUrlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放流资源
releaseResource(inputStream, null);
}
return stringBuilder.toString();
}
/**
*
* 基于java原生的URL和URLConnection发送form表单类型post请求
*
* @param urlPath
* 请求地址
* @param params
* 请求提交参数
* @return response data
*/
public static String sendFormPost(final String urlPath, final Map<String, String> params) {
// 响应数据流
InputStream inputStream = null;
// 请求输出流
OutputStream outputStream = null;
// 请求返回数据
StringBuilder stringBuilder = new StringBuilder();
try {
// 新建一个URL对象
URL url = new URL(urlPath);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
// 设置请求方法post请求
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("connection", "Keep-Alive");
// 使用post请求数据时,最好要设置以下请求头
httpUrlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpUrlConnection.setDoOutput(true);// 默认为false,如果使用post请求的话则一定要设置为true否则获取输出流救护失败。
// httpUrlConnection.setDoInput(true);//默认已经为true,所以不需要设置
// 赋值提交的post表单数据
outputStream = httpUrlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write(ConverterMapToParams(params));
bufferedWriter.flush();
int responseCode = httpUrlConnection.getResponseCode();
if (responseCode != 200) {
return "request fail code" + responseCode;
}
inputStream = httpUrlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放流资源
releaseResource(inputStream, outputStream);
}
return stringBuilder.toString();
}
/**
* 发送json格式的post请求
*
* @param urlPath
* 请求地址
* @param params
* 提交的json数据
* @return
*/
public static String sendJsonPost(final String urlPath, final String params) {
// 响应数据流
InputStream inputStream = null;
// 请求输出流
OutputStream outputStream = null;
// 请求返回数据
StringBuilder stringBuilder = new StringBuilder();
try {
// 新建一个URL对象
URL url = new URL(urlPath);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
// 设置请求方法post请求
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("connection", "Keep-Alive");
// 使用post请求数据时,最好要设置以下请求头
httpUrlConnection.setRequestProperty("Content-Type", "application/json");
httpUrlConnection.setDoOutput(true);// 默认为false,如果使用post请求的话则一定要设置为true否则获取输出流救护失败。
// httpUrlConnection.setDoInput(true);//默认已经为true,所以不需要设置
// 赋值提交的post表单数据
outputStream = httpUrlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write(params);
bufferedWriter.flush();
int responseCode = httpUrlConnection.getResponseCode();
if (responseCode != 200) {
return "request fail code" + responseCode;
}
inputStream = httpUrlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放流资源
releaseResource(inputStream, outputStream);
}
return stringBuilder.toString();
}
/**
* Map对象转为key=value&key2=value2字符串格式
*
* @param params
* @return
*/
private static String ConverterMapToParams(final Map<String, String> params) {
StringBuilder stringBuilder = new StringBuilder();
if (params != null) {
for (Entry<String, String> entry : params.entrySet()) {
stringBuilder.append(entry.getKey());
stringBuilder.append("=");
stringBuilder.append(entry.getValue());
stringBuilder.append("&");
}
}
String result = stringBuilder.substring(0, stringBuilder.lastIndexOf("&"));
return result;
}
/**
* 释放流资源
*
* @param in
* 输入流
* @param out
* 输出流
*/
private static void releaseResource(InputStream in, OutputStream out) {
if (in != null) {
try {
in.close();
in = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
out = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* 备注:
*
* httpUrlConnection.setDoOutput(true);以后就可以使用conn.getOutputStream().write()
* httpUrlConnection.setDoInput(true);以后就可以使用conn.getInputStream().read();
* get请求用不到conn.getOutputStream(),因为参数直接追加在地址后面,因此默认是false。
*
*
*/
}
参考
https://en.wikipedia.org/wiki/Help:URL
http://www.cnblogs.com/nick-huang/p/3859353.html
http://www.ibm.com/developerworks/cn/xml/x-urlni.html