【java】自己封装的httpHelper访问类及其相关联的类 访问http

来源:互联网 发布:如何找到外包项目 知乎 编辑:程序博客网 时间:2024/06/03 17:56

20141030

这个大三的时候写的,现在看起来感觉多线程上有一些不足之处,如果大家觉得可以当作参考自己改改吧。


后注:

以下的代码是JRE用的,如果用在android要修改的,比如说UrlConnection.getContentLongLength是没有的,要改成getContentLength(),还有就是一些导入的包要删改。我已经改好了android的版本。就不发了

还有就是由于本人刚从C#转JAVA对于JAVA的异常了解的不够,直接在工具类里catch异常了,然后e.print....我以为和C#一样是可以把catch到的异常直接throw出来的,于是又进行了修改。使用了throws回避异常

修改后的包android 或 JRE的想要的mail 164858843@qq.com

 

最近想在android上写个使用到http协议的小程序,发现没封装过的写的代码太繁琐,就自己动手花了一天时间构思封装,方便http相关操作, 提供一系列同步 、异步的方法,  也有文件下载相关的同步、异步方法 ,所有的异步方法都提供一系列的回调接口,使用线程池,方便快捷~

总共有这么几个类
Cookies.java
这个是借鉴网上的管理cookie的方法,为了实现cookie的保持,sessionID的传送,所封装的一个管理cookie的类
HttpConnProp.java 
这个是http发送请求时请求报文里要设置的相关参数,直接new一个对象就是我设置的默认参数
ReturnData.java
http返回数据的的封装,有一个String是html文档,有一个HttpConnProp对象是请求完成后更新后的属性对象,特别的cookie和Referer,都是跟新后的
只要把返回的新的HttpConnProp对象给下一个连接,就可以保持session
HttpHelper.java
主类,里面有各种各样的方法
先看看我写的的工具库部分方法的使用效果:
 
异步get,post测试
HttpHelper.AysnGetHtml("http://www.baidu.com",HttpConnProp.getDefaultHttpConnProp(), "gb2312",new HttpHelper.AsynExecuteCallBack() {@Overridepublic void exceptionOccored(Exception e) {// TODO Auto-generated method stub}@Overridepublic void beforeExecute() {// TODO Auto-generated method stubSystem.out.println("执行之前");}@Overridepublic void afterExecute(ReturnData rData) {// TODO Auto-generated method stubSystem.out.println("执行之后");//System.out.print(rData.getHtmlData());}});HttpHelper.AysnPostHtml("http://web.61166.com/member/index_doajax.php","fmdo=login&dopost=login&userid=zhaozeyang&pwd=wodemima",new HttpConnProp(), "gb2312",new HttpHelper.AsynExecuteCallBack() {@Overridepublic void exceptionOccored(Exception e) {// TODO Auto-generated method stub}@Overridepublic void beforeExecute() {// TODO Auto-generated method stub}@Overridepublic void afterExecute(ReturnData rData) {// TODO Auto-generated method stubSystem.out.println(rData.getHtmlData());}});HttpHelper.shutTheThreadPoolDown();//等待所有线程完成后关闭线程池服务

下载文件测试
 HttpHelper.downLoadFile("http://avatar.csdn.net/B/7/7/1_zwl230631.jpg", "g://rfegr22g.jpg"); //异步下载测试 HttpHelper.AsynDownLoadFile("http://61.164.109.222/2345.zip", "g://112121.rar", new HttpHelper.asynDownLoadCallBack() { @Override public void duringDownLoad(long hasDownedByte, long FileLength) { // TODO Auto-generated method stub if(FileLength != 0 ) System.out.println("已下载"+hasDownedByte + "总数" + FileLength + "百分比" + (double)hasDownedByte/FileLength*100 +"%"); else{ System.out.println("已下载"+hasDownedByte); } } @Override public void downLoadFinished() { // TODO Auto-generated method stub System.out.println("下载完成"); } @Override public void downLoadErrorOccured(Exception e) { // TODO Auto-generated method stub System.out.println("err"); } @Override public void beforeDownLoad() { // TODO Auto-generated method stub System.out.println("开始下载"); } });
 
 
接下来为我写的类库代码:
 
Cookies.java
package cn.zzy;import java.util.HashMap;import java.util.Map.Entry;import java.util.Set;/** *  * Cookie的封装 *  *  */public class Cookies {private HashMap<String, String> hashMap;public Cookies() {hashMap = new HashMap<String, String>();}/** *  * @return 返回一个空的Cookies对象 */public static final Cookies getEmptyCookieObj() {return new Cookies();}/** *  * 清除 Cookies 里面的所有 Cookie 记录 */public void clear() {hashMap.clear();}/** *  * 根据 key 获取对应的 Cookie 值 *  *  *  * @param key *  *            要获取的 Cookie 值的 key *  * @return 如果不存在 key 则返回 null */public String getCookie(String key) {return hashMap.get(key);}/** *  * 在 Cookies 里设置一个 Cookie *  *  *  * @param key *  *            要设置的 Cookie 的 key *  * @param value *  *            要设置的 Cookie 的 value */public void putCookie(String key, String value) {hashMap.put(key, value);}/** *  * 在 Cookies 里面设置传入的 cookies * 格式  key=value *  *  * @param cookies */public void putCookies(String cookies) {if (cookies == null)return;String[] strCookies = cookies.split(";");for (int i = 0; i < strCookies.length; i++) {for (int j = 0; j < strCookies[i].length(); j++) {if (strCookies[i].charAt(j) == '=') {this.putCookie(strCookies[i].substring(0, j),strCookies[i].substring(j + 1,strCookies[i].length()));}}}}/** *  * 获取 Cookies 的字符串 */@Overridepublic String toString() {// TODO Auto-generated method stubif (hashMap.isEmpty())return "";Set<Entry<String, String>> set = hashMap.entrySet();StringBuilder sb = new StringBuilder(set.size() * 50);for (Entry<String, String> entry : set) {sb.append(String.format("%s=%s;", entry.getKey(), entry.getValue()));}sb.delete(sb.length() - 1, sb.length());return sb.toString();}}
HttpConnProp.java
package cn.zzy;/** *  * http链接的相关属性类 */public class HttpConnProp {private  String CONTENT_TYPE;private  String ACCEPT;private  String USER_AGENT;    private  boolean IS_KEEP_ALIVE;    private  boolean IS_USE_CACHE;    private  boolean IS_INSTANCE_FOLLOW_REDIRECTS;    private  int TIMEOUT;    private  String REFERER;    private Cookies COOKIES = null;        /**     * 以默认属性构造一个属性类     * 详细修改可自己调用set函数进行逐个修改     * 使用默认的话直接new就可以了     */    public HttpConnProp(){    this.CONTENT_TYPE = "application/x-www-form-urlencoded";    this.ACCEPT = "*/*";    this.USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0.1";    this.IS_KEEP_ALIVE = true;    this.IS_USE_CACHE = false;    this.IS_INSTANCE_FOLLOW_REDIRECTS = true;    this.TIMEOUT = 300000;    this.REFERER = "";    COOKIES = Cookies.getEmptyCookieObj();             }        /**     * 获得一个以默认属性构造的本类对象     * 也可以直接new 一个无参数的的本类对象,也是默认参数的     * @return     * httpConnProp对象     */    public static HttpConnProp getDefaultHttpConnProp() {    return new HttpConnProp();    }    /**     *      * @param hcp     * 待复制的对象     * @return     * 复制好后的对象     */    public static HttpConnProp copy(HttpConnProp hcp){    HttpConnProp hcp2 = new HttpConnProp();    hcp2.setAccept(hcp.getAccept());    hcp2.setContentType(hcp.getContentType());    hcp2.setCookies(hcp.getCookies());    hcp2.setIsInstanceFollowRedirects(hcp.getIsInstanceFollowRedirects());    hcp2.setIsKeepAlive(hcp.getIsKeepAlive());    hcp2.setISUseCaches(hcp.getIsUseCaches());    hcp2.setReferer(hcp.getReferer());    hcp2.setTimeOut(hcp.getTimeOut());    hcp2.setUserAgent(hcp.getUserAgent());    return hcp2;        }        public String getContentType(){return this.CONTENT_TYPE;}    public void setContentType(String ContentType){this.CONTENT_TYPE = ContentType;}        public String getAccept(){return this.ACCEPT;}    public void setAccept(String Accept){this.ACCEPT = Accept;}        public String getUserAgent(){return this.USER_AGENT;}    public void setUserAgent(String UserAgent){this.USER_AGENT = UserAgent;}        public boolean getIsKeepAlive(){return this.IS_KEEP_ALIVE;}    public void setIsKeepAlive(boolean isKeepAlive){this.IS_KEEP_ALIVE = isKeepAlive;}        public boolean getIsUseCaches(){return this.IS_USE_CACHE;}    public void setISUseCaches(boolean ISUseCaches){this.IS_USE_CACHE = ISUseCaches;}        public boolean getIsInstanceFollowRedirects(){return this.IS_INSTANCE_FOLLOW_REDIRECTS;}    public void setIsInstanceFollowRedirects(boolean ISInstanceFollowRedirects){this.IS_INSTANCE_FOLLOW_REDIRECTS = ISInstanceFollowRedirects;}        public String getReferer(){return this.REFERER;}    public void setReferer(String referer){this.REFERER = referer;}    public int getTimeOut(){return this.TIMEOUT;}    public void setTimeOut(int timeout){this.TIMEOUT = timeout; }        public Cookies getCookies(){return this.COOKIES;}    public void  setCookies(Cookies cookies) {this.COOKIES = cookies;}    }

ReturnData.java
package cn.zzy;import java.io.UnsupportedEncodingException;/** * http请求后返回的东西的包装类 *  * @author zzy *  *  */public class ReturnData {private String htmlData;private HttpConnProp updatedProp;private String encoding;/** *  * @param red *            返回的html信息 * @param hcp *            更新后的HttpConnProp,特别是cookie * @param encoding *            返回的string的编码 */public ReturnData(String red, HttpConnProp hcp, String encoding) {this.htmlData = red;this.updatedProp = hcp;this.encoding = encoding;}/** *  把结果的string 转byte[] * @return byte[]数组 */public byte[] getReturnByteData() {try {return this.htmlData.getBytes(this.encoding);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}public String getHtmlData() {return this.htmlData;}public void setHtmlData(String setb) {this.htmlData = setb;}public HttpConnProp getUpdateProp() {return this.updatedProp;}public void setUpdateProp(HttpConnProp uprop) {this.updatedProp = uprop;}public String getEncoding() {return this.encoding;}public void setEncoding(String e) {this.encoding = e;}};
HttpHelper.java
package cn.zzy;import java.io.*;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLConnection;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 自己写的java用HttpHelper 方便http相关操作 提供一系列同步 异步的方法 * 也有文件下载相关的异步、同步方法 * 所有的异步方法都提供一系列的回调接口。方便快捷~ *  *  */public class HttpHelper {/** * 固定5个线程来执行类内异步方法(默认) */private static ExecutorService executorService = Executors.newFixedThreadPool(5);/** * 立刻停止线程池服务,若有线程在running,强制停止 PS:命令行程序最后必须执行shutdown停止线程池服务,否则程序结束不了 * 警告:若一旦结束线程池服务,将不能再添加执行异步任务,除非运行本类中的openNewExecutorService() */public static void shutTheThreadPoolDownNow() {executorService.shutdownNow();}/** * 等待所有线程完成执行后关闭线程池服务 PS:命令行程序最后必须执行shutdown停止线程池服务,否则程序结束不了 * 警告:若一旦结束线程池服务,将不能再添加执行异步任务,除非运行本类中的openNewExecutorService() */public static void shutTheThreadPoolDown() {executorService.shutdown();}/** * 关闭默认的线程池服务,新建一个新的线程池服务 *  * @param RunningThreadCount */public static void openNewExecutorService(int RunningThreadCount) {if (!executorService.isShutdown())executorService.shutdown();executorService = Executors.newFixedThreadPool(RunningThreadCount);}/** *  * 用于异步通信的回调接口 *  */public interface AsynExecuteCallBack {public void beforeExecute();public void afterExecute(ReturnData rData);public void exceptionOccored(Exception e);}/** * 异步方法: 以get方式获得ReturnData对象,使用回调接口处理获得对象 *  * @param strUrl *            请求的URL地址 * @param hcp *            连接的属性类 * @param encoding *            编码字符串 例如 ASCII gb2312 utf-8 等 * @param callback *            回调接口 */public static void AysnGetHtml(final String strUrl, final HttpConnProp hcp,final String encoding, final AsynExecuteCallBack callback) {executorService.execute(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubcallback.beforeExecute();try {ReturnData rd = getHtmlBytes(strUrl, hcp, null, false,encoding);callback.afterExecute(rd);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();callback.exceptionOccored(e);}}});}/** * 异步方法: 添加一个任务 以post方式获取页面 *  * @param strUrl *            网页的URL地址 * @param strPost *            POST的数据 注意POST属性的值如果是中文或含有特殊符号根据相应编码URLencode * @param hcp *            http连接相应的属性类 * @param encoding *            编码字符串 例如 ASCII gb2312 utf-8 等 * @param callback *            一系列回调接口 */public static void AysnPostHtml(final String strUrl, final String strPost,final HttpConnProp hcp, final String encoding,final AsynExecuteCallBack callback) {executorService.execute(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubcallback.beforeExecute();try {ReturnData rd = getHtmlBytes(strUrl, hcp, strPost, true,encoding);callback.afterExecute(rd);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();callback.exceptionOccored(e);}}});}/** * 同步方法: 以gb2312编码,默认的链接属性get页面 *  * @param strUrl *            访问的URL地址 * @return 网页的html */public static String getHtml(String strUrl) {return getHtml(strUrl, new HttpConnProp(), "gb2312");}/** * 同步方法: get方式取页面,返回html页面 *  * @param strUrl *            网页URL地址 * @param hcp *            访问属性的类对象 * @param encoding *            编码字符串 例如 ASCII gb2312 utf-8 等 * @return 如果出现错误返回null,否则返回页面的String对象 */public static String getHtml(String strUrl, HttpConnProp hcp,String encoding) {try {return getHtmlBytes(strUrl, hcp, null, false, encoding).getHtmlData();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}/** * 同步方法: 以post方式获取页面 *  * @param strUrl *            网页URL地址 * @param strPost *            POST的数据 注意POST属性的值如果是中文或含有特殊符号根据相应编码URLencode * @param hcp *            http连接的属性对象 * @param encoding *            返回的数据存储的编码和post的编码,例如'gb2312'、'utf-8' * @return 返回得到的html */public static String postHtml(String strUrl, String strPost,HttpConnProp hcp, String encoding) {try {return getHtmlBytes(strUrl, hcp, strPost, true, encoding).getHtmlData();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}/** * 同步方法: *  * 本Helper中最主要的方法 其他的一些方法都是根据此方法进行包装 *  * @param strUrl *            网页URL地址 * @param httpConnProp *            http连接的属性 * @param strPost *            POST的数据 注意POST属性的值如果是中文或含有特殊符号根据相应编码URLencode,如果是get *            isPost设置为false,请设置null * @param isPost *            是否是POST方法 * @param encoding *            返回的数据存储的编码和post的编码,例如'gb2312'、'utf-8' * @return 一个返回信息的包装,内部类ReturnData,里面有HttpConnProp的更新和请求得到的数据 * @throws IOException */public static ReturnData getHtmlBytes(String strUrl,HttpConnProp httpConnProp, String strPost, boolean isPost,String encoding) throws IOException {HttpURLConnection.setFollowRedirects(true);// 静态变量设置 防止某些服务出错,特别是IIS的HttpURLConnection httpCon = null;InputStream is = null;BufferedInputStream bis = null;String temp = "";// System.out.println(httpConnProp.getCookies().toString());try {URL url = new URL(strUrl);httpCon = (HttpURLConnection) url.openConnection();// 设置相关属性httpCon.setReadTimeout(httpConnProp.getTimeOut());httpCon.setConnectTimeout(httpConnProp.getTimeOut());httpCon.setUseCaches(httpConnProp.getIsUseCaches());// 设置缓存if (httpConnProp.getIsKeepAlive())httpCon.setRequestProperty("connection", "Keep-Alive");httpCon.setInstanceFollowRedirects(httpConnProp.getIsInstanceFollowRedirects());// 设置跳转跟随httpCon.setRequestProperty("Referer", httpConnProp.getReferer());httpCon.setRequestProperty("Content-Type",httpConnProp.getContentType());httpCon.setRequestProperty("Accept", httpConnProp.getAccept());httpCon.setRequestProperty("User-Agent",httpConnProp.getUserAgent());httpCon.setRequestProperty("Cookie", httpConnProp.getCookies().toString());httpCon.setRequestProperty("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");if (isPost) {// 如果是post 设置post信息httpCon.setDoOutput(true);httpCon.setDoInput(true);httpCon.setUseCaches(false);// POST请求不能使用缓存httpCon.setRequestProperty("Context-Length",String.valueOf(strPost.getBytes(encoding).length));httpCon.setRequestMethod("POST");httpCon.connect();OutputStream os = null;// 输出post信息的流try {os = httpCon.getOutputStream();os.write(strPost.getBytes(encoding));os.flush();} finally {if (os != null)os.close();}}// 获取数据is = httpCon.getInputStream();bis = new BufferedInputStream(is);byte[] buffer = new byte[512];int count = 0;while ((count = bis.read(buffer)) != -1) {temp += (new String(buffer, 0, count, encoding));}} catch (Exception e) {e.printStackTrace();// TODO: handle exception} finally {try {if (bis != null)bis.close();if (is != null)is.close();} catch (Exception e) {e.printStackTrace();}}HttpConnProp updtedHttpConnProp = HttpConnProp.copy(httpConnProp);if (httpCon != null) {updtedHttpConnProp.getCookies().putCookies(httpCon.getHeaderField("Set-Cookie"));// 更新 refererupdtedHttpConnProp.setReferer(strUrl);// System.out.println("输出号:--" + httpCon.getResponseCode());httpCon.disconnect();httpCon = null;}return new ReturnData(temp, updtedHttpConnProp, encoding);}/** * 同步方法: * 从网络上下载文件 缓存4kb * @param strUrl * 文件URL地址 * @param fileURL * 保存地址 如g://1.rar (注意是覆蓋的) */   public static void downLoadFile(final String strUrl, final String fileURL) {    downLoadFile(strUrl, fileURL,4096);   }/** * 同步方法: 从网络上下载文件 *  * @param strUrl *文件URL地址 * @param fileURL *保存地址 如g://1.rar (注意是覆蓋的) * @bufferLength * 下载缓存的大小,byte单位 ,建议4096 (4KB) */public static void downLoadFile(final String strUrl, final String fileURL,final int bufferLength) {BufferedInputStream in = null;BufferedOutputStream out = null;try {in = new BufferedInputStream(new URL(strUrl).openStream());File img = new File(fileURL);out = new BufferedOutputStream(new FileOutputStream(img));byte[] buf = new byte[bufferLength];int count = in.read(buf);while (count != -1) {out.write(buf, 0, count);count = in.read(buf);}in.close();out.close();} catch (Exception e) {e.printStackTrace();}}/** *  * 文件异步下载的接口 *  */interface asynDownLoadCallBack {public void beforeDownLoad();// 下载文件之前/** * 如果服务器不指定文件的长度,则fileLength = 0  要用到这几个参数的话要自己在回调接口处判断 * @param hasDownedByte * 已经下载的字节数 * @param FileLength * 文件总字节数 若服务器无此信息即为0 */public void duringDownLoad(long hasDownedByte, long FileLength);// 下载文件之中public void downLoadFinished();// 下载文件之后public void downLoadErrorOccured(Exception e);// 出错后}/** * 异步方法: * 以4KB缓存从网上下载文件 * @param strUrl * 文件URL地址 * @param fileURL * 保存的地址 如g://1.rar * @param callback * 回调接口 */public static void AsynDownLoadFile(final String strUrl,final String fileURL, final asynDownLoadCallBack callback) {AsynDownLoadFile(strUrl, fileURL, callback,4096);}    /**     * 异步方法:     * 从网络上异步下载文件     * @param strUrl     * 文件URL地址     * @param fileURL     * @param callback     * @param bufferLength     */public static void AsynDownLoadFile(final String strUrl,final String fileURL, final asynDownLoadCallBack callback,final int bufferLength) {executorService.execute(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubURLConnection urlConnection = null;BufferedInputStream bis = null;BufferedOutputStream bos = null;long fileLength = 0;long hasDowned = 0;try {urlConnection = new URL(strUrl).openConnection();fileLength = urlConnection.getContentLengthLong();// 获取报文里给的数据长度bis = new BufferedInputStream(urlConnection.getInputStream());bos = new BufferedOutputStream(new FileOutputStream(new File(fileURL)));callback.beforeDownLoad();// 执行回调函数byte[] buffer = new byte[bufferLength];int count = bis.read(buffer);while (count != -1) {bos.write(buffer, 0, count);hasDowned += count;// 如果服务器不指定文件的长度,则fileLength = 0  要用到这几个参数的话要自己在回调接口处判断callback.duringDownLoad(hasDowned, fileLength);count = bis.read(buffer);}callback.downLoadFinished();} catch (Exception e) {e.printStackTrace();callback.downLoadErrorOccured(e);}finally{try {bis.close();bos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});}}

花了一天时间弄的,累死了。 但还不是很完全,还可以添加更多的方法。如果用于android的话还可以继承一下httpHelper个类,使用android类库再写几个android专用方法,比如load图片
 
目前有好多android的网络编程框架

原创粉丝点击