⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpclient.java

📁 FIRE (Flexible Interface Rendering Engine)是一个J2ME上的灵活的图形界面引擎
💻 JAVA
字号:
/* * Fire (Flexible Interface Rendering Engine) is a set of graphics widgets for creating GUIs for j2me applications.  * Copyright (C) 2006-2008 Bluevibe (www.bluevibe.net) * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *  *//** *  */package gr.fire.browser.util;import gr.fire.browser.Browser;import gr.fire.util.FireConnector;import gr.fire.util.Log;import gr.fire.util.StringUtil;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import javax.microedition.io.Connector;import javax.microedition.io.HttpConnection;import javax.microedition.io.HttpsConnection;/** * This class implements the Http functionality for the Browser module.  * It makes http requests using the supplied FireConnector instance and handles  * cookies and redirects approprietly.  *  * It also supports local file urls (starting with file://) *  * The HttpClient instance can remember the previous request made and can handle appropriatelly  * relative URLs based on that information. *  * @see FireConnector * @see Browser *  * @author padeler * */public class HttpClient{	private String[][] defaultHeaderValues = new String[][] {         {"User-Agent","Fire v2.0 Mozilla/4.0 (compatible; MSIE 6.0)"},		 {"Accept","text/xml, application/xhtml+xml, text/css, multipart/mixed, ,*/*;q=0.8"},		 {"Accept-Language","en-us,en;q=0.5"},		 {"Accept-Charset","utf-8, ISO-8859-1;q=0.8, *;q=0.7"}	   };			protected FireConnector connector;	private Vector savedCookies=new Vector();	private Request currentPage=null;	/**	 * Constructor for the HttpClient. The new instance uses the supplied FireConnector instance 	 * to open input/output streams to the requested resource.   	 * @param connector	 */	public HttpClient(FireConnector connector)	{		this.connector = connector;	}		/**	 * Makes a http request to URL using the set method (HttpConnection.GET or HttpConnection.POST) and the supplied request parameters.	 *  	 * @param url	 * @param requestMethod	 * @param requestProperties User supplied Http request header parameters. 	 * @param data if method is POST then the post data are in this array. 	 * @param updateCurrentPage if set to true the HttpClient will remember the URL of this request in order to handle feature relative path requests	 * @return	 */	public Request requestResource(String url, String requestMethod, Hashtable requestProperties, byte[]data,boolean updateCurrentPage)	{		if(url==null) throw new IllegalArgumentException("Request for resource to null url?");				url = StringUtil.proccessUrl(url,false);				if(url.indexOf("://")==-1 && currentPage!=null) // url path is relevative to current. 		{			Log.logDebug("Resolving URL: "+url);			if(url.startsWith("/"))			{				url = currentPage.getBaseURL()+url;			}			else			{				String base = currentPage.getBaseURL();				String file = currentPage.getFile();				int idx=-1;				if(file!=null)				{					idx =file.lastIndexOf('/');					if(idx==0) idx=-1; // file starts with "/" ignore that				}								if(idx==-1)				{					String s = "";					if(base.endsWith("/")==false) s="/"; 										url = base+s+url;				}				else				{					int start = 0;					if(file.startsWith("/")) start=1;					String sep="/";					if(base.endsWith("/")) sep="";					url = base+sep+file.substring(start,idx)+"/"+url;				}			}			Log.logDebug("URL Resolved to: "+url);		}				int idx = url.indexOf("://");		if(idx==-1) throw new IllegalArgumentException("URL must start with the protocol.");				String protocol = url.substring(0,idx);				if(protocol.equals("file"))		{			Log.logInfo("File: ["+url+"]");			InputStream in=null;			try			{				in = connector.openInputStream(url);			} catch (Exception e)			{				Log.logDebug("Exception:" +e.getClass()+": "+e.getMessage());			}						if(in==null)			{				Log.logWarn("Failed to load local resource "+url);				return null;			}						Request result = new Request("","file",url.substring(7),Request.defaultEncoding,in);			if(updateCurrentPage) currentPage = result;						return result;		}				Log.logInfo(requestMethod+" ["+url+"]");		HttpConnection conn=null; 		try{ // the resource is located remotelly. Try to retrieve it.			int mode = Connector.READ;			if(HttpConnection.POST.equals(requestMethod) && data!=null) mode=Connector.READ_WRITE;			conn = (HttpConnection)connector.open(url,mode,true);			conn.setRequestMethod(requestMethod);			for(int i=0;i<defaultHeaderValues.length;++i)			{				conn.setRequestProperty(defaultHeaderValues[i][0], defaultHeaderValues[i][1]);			}            			if(requestProperties!=null)			{				Enumeration propKeys = requestProperties.keys();				while(propKeys.hasMoreElements())				{					String key = (String)propKeys.nextElement();					String val = (String)requestProperties.get(key);					conn.setRequestProperty(key,val);						}			}						// add cookies 			String cookies = getCookies(conn,conn.getFile());			if(cookies.length()>0)			{				conn.setRequestProperty("Cookie",cookies);			}						// add referer			if(currentPage!=null && currentPage.getProtocol().equals("file")==false)			{				String q = currentPage.getQuery();				if(q!=null) q = "?"+q;				else q="";				String referer = currentPage.getBaseURL()+currentPage.getFile()+q;				conn.setRequestProperty("Referer",referer);			}			if(mode==Connector.READ_WRITE && data!=null) // exoume na grapsoume kiolas.			{				conn.setRequestProperty("Content-Length",""+data.length);								OutputStream out = conn.openOutputStream();				out.write(data);				Log.logDebug("Post data["+data.length+"] sent.");				Log.logDebug("["+new String(data)+"]");			}			Log.logDebug("Attempting to retrieve response code..");			int code = conn.getResponseCode();						Log.logInfo("Response "+code+" "+conn.getResponseMessage());						for(int i=0;i<100;++i)			{				String key = conn.getHeaderFieldKey(i);				if(key==null) break;								if(key.toLowerCase().equals("set-cookie")) 				{					// the cookieStr may be more than one cookies seperated by commas. 					// First we split the cookies and then we parse them.					// this is a bit tricky since a cookie may contain commas as well...(who thought of that delimiter anyway?)					Vector cookieStrings = Cookie.splitCookies(conn.getHeaderField(i));					for(int j=0;j<cookieStrings.size();++j)											saveCookie((String)cookieStrings.elementAt(j),conn.getHost());				}				else Log.logDebug(key+": "+conn.getHeaderField(i));			}						if(code==HttpConnection.HTTP_MOVED_PERM) // 301			{ 								if(updateCurrentPage)					currentPage = new Request(conn);				String redirect = conn.getHeaderField("location");				Log.logInfo("Redirect "+code+" to location: " +redirect);				conn.close();				return requestResource(redirect,requestMethod,requestProperties,data,updateCurrentPage);			}			else if(code==HttpConnection.HTTP_MOVED_TEMP || code==HttpConnection.HTTP_SEE_OTHER)			{// must redirect using the GET method (see protocol)				if(updateCurrentPage)					currentPage = new Request(conn);				String redirect = conn.getHeaderField("location");				Log.logInfo("Redirect "+code+" to location: " +redirect);				conn.close();				return requestResource(redirect,HttpConnection.GET,requestProperties,data,updateCurrentPage);			}			else // responce is 200 or another http code.			{				Request result = new Request(conn);											if(updateCurrentPage && code==HttpConnection.HTTP_OK) // updateCurrentPage only when responce is 200 (OK)					currentPage = result;				return result;			}		}catch(Exception ex)		{			Log.logError("Request to "+url+" failed.",ex);			if(conn!=null){				try{conn.close();}catch(IOException e){					Log.logWarn("Failed to close the connection.",e);				}			}		}		return null; 	}		private void saveCookie(String cookieStr,String host)	{				try{					Cookie newCookie = new Cookie(cookieStr,host);					int idx = savedCookies.indexOf(newCookie); // check to see if cookie already exists			Date expires = newCookie.getExpires();			if(idx>-1)			{				savedCookies.removeElementAt(idx);			}						if(expires==null ||  System.currentTimeMillis()< (expires.getTime()))			{				savedCookies.addElement(newCookie);				Log.logDebug("Saved Cookie "+newCookie.getName());			}			else // expiration date is in the past.				Log.logDebug("Removed (expired: "+expires+") Cookie: "+newCookie.getName()); 		}catch(Exception e)		{			Log.logWarn("Failed to save cookie: "+cookieStr,e);		}	}		private String getCookies(HttpConnection req,String path)	{		String host = req.getHost();		if(path==null) path="/";		boolean includeSecure = req instanceof HttpsConnection;		String res = "";		for(int i =0 ;i<savedCookies.size();++i)		{			Cookie c = (Cookie)savedCookies.elementAt(i);			if(c.match(host,path) && (includeSecure || !c.isSecure()))			{				res += c.toString()+"; ";				Log.logDebug("Sending Cookie: "+c.getName());			}		}		return res;	}		/**	 * Stores the cookies currently saved in memory, to the record store.	 * 	 * @param cookiesStorage the name of the record store to hold the cookies.	 * @throws IOException	 */	public void storeCookies(String cookiesStorage) throws IOException	{		if(savedCookies.size()==0)		{			Log.logInfo("No cookies to store in recordstore.");			return; // nothing to save.		}		try{			try{				connector.rmsDelete(cookiesStorage);			}catch(Throwable e){ // try to delete last save cookies.				Log.logWarn("Failed to delete old saved cookies file. "+e.getMessage());			}						ByteArrayOutputStream bout = new ByteArrayOutputStream();			DataOutputStream dout = new DataOutputStream(bout);			for(int i=0;i<savedCookies.size();++i)			{				Cookie c = (Cookie)savedCookies.elementAt(i);				Cookie.serialize(c,dout);			}			byte []buf = bout.toByteArray();			int free = connector.rmsFree();			if(free<buf.length) throw new IOException("Not enough free storage space to save cookies.");			connector.rmsWrite(cookiesStorage,buf);		}catch(Throwable e)		{			if(e instanceof IOException) throw (IOException)e;			else throw new IOException("Store cookies failed. "+e.getMessage());		}		Log.logInfo("Stored "+savedCookies.size()+" to record store: "+cookiesStorage);	}		/**	 * Load the cookies previously stored in the specified recordstore using the {@link #storeCookies(String)} method.	 * @param cookiesStorage	 * @throws IOException	 */	public void loadCookies(String cookiesStorage) throws IOException	{		try{			InputStream in = connector.rmsRead(cookiesStorage);			if(in==null) return; // no stored cookies found						DataInputStream din = new DataInputStream(in);			int cookiesCount=0;			while(din.available()>0)			{				Cookie c = Cookie.deSerialize(din);				savedCookies.addElement(c);				cookiesCount++;			}			Log.logInfo("Loaded "+cookiesCount+" cookies from record store: "+cookiesStorage);		}catch(Throwable e)		{			if(e instanceof IOException) throw (IOException)e;			else throw new IOException("Load cookies failed. "+e.getMessage());		}	}		/**	 * If a call to the {@link #requestResource(String, String, Hashtable, byte[], boolean)} was made earlies with the updateCurrentPage==true 	 * then this method will return that URL.	 * @return	 */	public String getCurrentURL()	{		return (currentPage!=null)?currentPage.getURL():null;	}	public String[][] getDefaultHeaderValues()	{		return defaultHeaderValues;	}	public void setDefaultHeaderValues(String[][] defaultHeaderValues)	{		this.defaultHeaderValues = defaultHeaderValues;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -