httpURLConnection实例
?
package com.hyf.base.connection;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.Vector;/** * <br> * description: HttpURLConnection学习 * </br> * DateTime: 2012-2-16 上午11:18:03 * * @author haoyf * @version 1.0 */public class HttpConnect {/** * 1.打开一个连接 * 2.设置属性和头部信息 * 3.连接实际连接 * 4.访问 */private HttpURLConnection httpConn;private InputStream in;private OutputStream out;/** * <br> * description: 初始化 * </br> * @param connectURL * URL连接地址 * @throws MalformedURLException * @throws IOException */public HttpConnect(String connectURL) throws MalformedURLException, IOException {httpConn = (HttpURLConnection) new URL(connectURL).openConnection(); //打开一个新的连接httpConn.setRequestMethod("POST"); //设置请求方式httpConn.setDoInput(true); //设置true:应用程序要从URL连接读取数据httpConn.setDoOutput(true); //设置true:应用程序将数据写入URL连接httpConn.setRequestProperty("Content-Type", "text/html"); //设置头信息,拥有多个具有相同键的实例的请求属性,使用以逗号分隔的列表语法,这样可实现将多个属性添加到一个属性中httpConn.setConnectTimeout(2*60*1000); //连接超时,以毫秒不单位}/** * <br> * description: 初始化 * </br> * @param connectUrl * URL连接地址 * @param method * 请求方式 * @throws MalformedURLException * @throws IOException */public HttpConnect(String connectUrl, String method) throws MalformedURLException, IOException {httpConn = (HttpURLConnection) new URL(connectUrl).openConnection();httpConn.setRequestMethod(method);httpConn.setDoInput(true);httpConn.setDoOutput(true);}/** * <br> * description: 设置头部 * </br> * @param key * 请求的关键字 * @param value * 该键关联的值 */public void setHeader(String key, String value) {httpConn.setRequestProperty(key, value);}/** * <br> * description: 向URL发送数据 * </br> * @param data * 发送的数据 * @throws IOException */public void SendData(String data) throws IOException {byte[] f = data.getBytes("UTF-8");out = httpConn.getOutputStream(); //getOutputStream()方法,自动调用connect()连接方法out.write(f, 0, f.length);out.flush();out.close();}/** * <br> * description: 收到的数据 * </br> * @return * String * @throws IOException */public String ReceiveData() throws IOException {in = new DataInputStream(httpConn.getInputStream());StringBuffer reMsg = new StringBuffer();int ch;while ((ch = in.read()) != -1) {reMsg.append((char) ch);}String ret = reMsg.toString();return ret;}/** * <br> * description: 释放连接 * </br> */public void releaseHttpConnect() {try {if (httpConn != null) {httpConn.disconnect();}if (out != null) {out.close();}if (in != null) {in.close();}} catch (Exception e) {e.printStackTrace();}}/** * <br> * description: 读取UTF数据 * </br> * String * @return * @throws IOException */public String ReceiveUTFString() throws IOException {in = new DataInputStream(httpConn.getInputStream());Vector<byte[]> bufLst = new Vector<byte[]>();int len = 0;while (true) {byte[] buf = new byte[256];int l = in.read(buf, 1, 255);if (l == -1) {break;}buf[0] = (byte) ((byte) l & 0xFF);len += (int) buf[0] & 0xFF;bufLst.add(buf);}byte[] bigBuf = new byte[len];int off = 0;for (int i = 0; i < bufLst.size(); i++) {System.arraycopy(bufLst.get(i), 1, bigBuf, off,(int) bufLst.get(i)[0] & 0xFF);off += (int) bufLst.get(i)[0] & 0xFF;}String ret = new String(bigBuf, "UTF-8");return ret;}/** * <br> * description: 根据编码获取数据 * </br> * @param encoding * 编码方式 * @return * String */public String receiveByEncode(String encoding) {DataInputStream in;try {in = new DataInputStream(httpConn.getInputStream());InputStreamReader inread = new InputStreamReader(in, encoding);StringBuffer reMsg = new StringBuffer();int ch;while ((ch = inread.read()) != -1) {reMsg.append((char) ch);}String ret = reMsg.toString();return ret;} catch (IOException e) {e.printStackTrace();return null;}}/*****************流的附加方法**********************************//** * <br> * description: 将UTF-8byte转换成String * </br> * @param rec * byte * @return */public String BytesToString(byte[] rec) {ByteArrayInputStream bais = new ByteArrayInputStream(rec);DataInputStream dis = new DataInputStream(bais);String BTS = null;try {BTS = new String(rec, "UTF-8");bais.close();dis.close();} catch (Exception e) {e.printStackTrace();}return BTS;}/** * <br> * description: 数据流拷贝 * </br> * @param in * 输入流 * @param out * 输出流 * @throws IOException */private void copy(InputStream in, OutputStream out) throws IOException {try {byte[] buffer = new byte[4096];int nrOfBytes = -1;while ((nrOfBytes = in.read(buffer)) != -1) {out.write(buffer, 0, nrOfBytes);}out.flush();} catch (IOException e) {} finally {try {if (in != null) {in.close();}} catch (IOException ex) {}try {if (out != null) {out.close();}} catch (IOException ex) {}}}/** * <br> * description: 读取文件数据 * @param fileName * 文件名 * @return * byte */public byte[] getFileByte(String fileName) {InputStream fileInputStream = getClass().getResourceAsStream(fileName);return getFileByte(fileInputStream);}/** * <br> * description: 读取文件数据 * </br> * @param fileName * 文件名 * @return * String */public String getFileString(String fileName) {InputStream fileInputStream = getClass().getResourceAsStream(fileName);return getFileString(fileInputStream);}/** * <br> * description: 读取文件数据 * </br> * @param in * 输入流 * @return * String */public String getFileString(InputStream in) {ByteArrayOutputStream out = new ByteArrayOutputStream(4096);try {copy(in, out);} catch (IOException e) {e.printStackTrace();}return out.toString();}/** * <br> * description: 读取文件数据 * </br> * @param in * 输入流 * @return * byte */public byte[] getFileByte(InputStream in) {ByteArrayOutputStream out = new ByteArrayOutputStream(4096);try {copy(in, out);} catch (IOException e) {e.printStackTrace();}return out.toByteArray();}}??
1. HttpURLConnection 的connect ()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
??? 无论是post还是get,http请求实际上直到HttpURLConnection 的getInputStream()这个函数里面才正式发送出去。
2. 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,
??? 对connection对象的一切配置(那一堆set函数)
??? 都必须要在connect ()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。
??? 这些顺序实际上是由http请求的格式决定的。
??? 如果inputStream读操作在outputStream的写操作之前,会抛出例外:
??? java.net.ProtocolException: Cannot write output after reading input.......
3. http请求实际上由两部分组成,
??? 一个是http头,所有关于此次http请求的配置都在http头里面定义, 一个是正文content。
??? connect ()函数会根据HttpURLConnection 对象的配置值生成http头部信息,因此在调用connect 函数之前,
??? 就必须把所有的配置准备好。
4. 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,
??? 实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,
??? 而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。
??? 至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求
??? 正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http
??? 请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数
??? 之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)
??? 都是没有意义的了,执行这些操作会导致异常的发生。
?