MDA/MDD/TDD/DDD/DDDDDDD
          posts - 536, comments - 111, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          HttpURLConnection timeout solution

          Posted on 2010-04-14 17:04 leekiang 閱讀(1339) 評論(0)  編輯  收藏 所屬分類: java應用服務器io,tcp
          From: Niels Campbell (niels_campbell_at_lycos.co.uk)
          Date: 01/23/04
          Date: 23 Jan 2004 09:14:16 -0800
          After spending nearly 3 days on this problem to come up with a

          solution I think it is only right to post the solution.

          I found that you can't set the soTimeout on an HttpURLConnection as
          the sockets are encapsulated within the HttpURLConnection
          implementation.

          I found Mike Reiche solution in which he uses a handler to set a
          timeout value. This nearly worked. Looking at the code in the rt.jar I
          found that the initial timeout was working, but the call
          parseHTTP(...) in HttpClient was then attempting a second connection
          which had a time out value of 0(infinite).

          I modified the code to override the doConnect() in the NetworkClient
          and managed to get a timeout occurring. To be exact two timeouts
          occur.

          It works on
          java version "1.4.0_03"
          Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_03-b04)
          Java HotSpot(TM) Client VM (build 1.4.0_03-b04, mixed mode)
          and
          java version "1.2.2"
          Classic VM (build JDK-1.2.2_013, native threads, symcjit)

          Anyway here is the code, excuse the formatting.

          /* HttpTimeoutURLConnection.java */
          import java.net.*;
          import java.io.*;
          import sun.net.www.http.HttpClient;

          // Need to override any function in HttpURLConnection that create a
          new HttpClient
          // and create a HttpTimeoutClient instead. Those functions are
          // connect(), getNewClient(), getProxiedClient()

          public class HttpTimeoutURLConnection extends
          sun.net.www.protocol.http.HttpURLConnection
          {

          ????public HttpTimeoutURLConnection(URL u, HttpTimeoutHandler handler,
          int iSoTimeout)
          ????????throws IOException
          ????{
          ????????super(u, handler);
          ????????HttpTimeoutClient.setSoTimeout(iSoTimeout);
          ????}

          ????public void connect() throws IOException
          ????{
          ????????if (connected)
          ????????{
          ????????????return;
          ????????}

          ????????try
          ????????{
          ????????????if ("http".equals(url.getProtocol())) // && !failedOnce <-
          PRIVATE
          ????????????{
          ????????????????// for safety's sake, as reported by KLGroup
          ????????????????synchronized (url)
          ????????????????{
          ????????????????????http = HttpTimeoutClient.getNew(url);
          ????????????????}
          ????????????}
          ????????????else
          ????????????{
          ????????????????if (handler instanceof HttpTimeoutHandler)
          ????????????????{
          ????????????????????http = new HttpTimeoutClient(super.url,
          ((HttpTimeoutHandler)handler).getProxy(),
          ((HttpTimeoutHandler)handler).getProxyPort());
          ????????????????}
          ????????????????else
          ????????????????{
          ????????????????????throw new IOException("HttpTimeoutHandler
          expected");
          ????????????????}
          ????????????}

          ????????????ps = (PrintStream)http.getOutputStream();
          ????????}
          ????????catch (IOException e)
          ????????{
          ????????????throw e;
          ????????}

          ????????connected = true;
          ????}

          ????protected HttpClient getNewClient(URL url)
          ????????throws IOException
          ????{
          ????????HttpTimeoutClient httpTimeoutClient = new HttpTimeoutClient
          (url, (String)null, -1);
          ????????return httpTimeoutClient;
          ????}

          ????protected HttpClient getProxiedClient(URL url, String s, int i)
          ????????throws IOException
          ????{
          ????????HttpTimeoutClient httpTimeoutClient = new HttpTimeoutClient
          (url, s, i);
          ????????return httpTimeoutClient;
          ????}

          }

          /* HttpTimeoutHandler.java */
          import java.net.*;
          import java.io.IOException;

          public class HttpTimeoutHandler extends
          sun.net.www.protocol.http.Handler
          {
          ????private int iSoTimeout=0;

          ????public HttpTimeoutHandler(int iSoTimeout)
          ????{
          ????????// Divide the time out by two because two connection attempts
          are made
          ????????// in HttpClient.parseHTTP()

          ????????if (iSoTimeout%2!=0)
          ????????{
          ????????????iSoTimeout++;
          ????????}
          ????????this.iSoTimeout = (iSoTimeout/2);
          ????}

          ????protected java.net.URLConnection openConnection(URL u) throws
          IOException
          ????{
          ????????return new HttpTimeoutURLConnection(u, this, iSoTimeout);
          ????}

          ????protected String getProxy()
          ????{
          ????????return proxy;
          ????}

          ????protected int getProxyPort()
          ????{
          ????????return proxyPort;
          ????}
          }

          /* HttpTimeoutFactory.java */
          import java.net.*;

          public class HttpTimeoutFactory implements URLStreamHandlerFactory
          {
          ????private int iSoTimeout=0;

          ????public HttpTimeoutFactory(int iSoTimeout)
          ????{
          ????????this.iSoTimeout = iSoTimeout;
          ????}

          ????public URLStreamHandler createURLStreamHandler(String str)
          ????{
          ????????return new HttpTimeoutHandler(iSoTimeout);
          ????}
          }

          /* HttpTimeoutClient.java */
          import sun.net.www.http.HttpClient;
          import java.net.*;
          import sun.net.*;
          import sun.net.www.*;
          import java.io.*;

          public class HttpTimeoutClient extends HttpClient
          {
          ????private static int iSoTimeout=0;

          ????public HttpTimeoutClient(URL url, String proxy, int proxyPort)
          throws IOException
          ????{
          ????????super(url, proxy, proxyPort);
          ????}

          ????public HttpTimeoutClient(URL url) throws IOException
          ????{
          ????????super(url, null, -1);
          ????}

          ????public static HttpTimeoutClient getNew(URL url)
          ????????throws IOException
          ????{
          ????????HttpTimeoutClient httpTimeoutClient = (HttpTimeoutClient)
          kac.get(url);

          ????????if (httpTimeoutClient == null)
          ????????{
          ????????????httpTimeoutClient = new HttpTimeoutClient (url); // CTOR
          called openServer()
          ????????}
          ????????else
          ????????{
          ????????????httpTimeoutClient.url = url;
          ????????}

          ????????return httpTimeoutClient;
          ????}

          ????public static void setSoTimeout(int iNewSoTimeout)
          ????{
          ????????iSoTimeout=iNewSoTimeout;
          ????}

          ????public static int getSoTimeout()
          ????{
          ????????return iSoTimeout;
          ????}

          ????// Override doConnect in NetworkClient

          ????protected Socket doConnect(String s, int i)
          ????????throws IOException, UnknownHostException, SocketException
          ????{
          ????????Socket socket=super.doConnect(s,i);

          ????????// This is the important bit
          ????????socket.setSoTimeout(iSoTimeout);
          ????????return socket;
          ????}

          }

          /* Example use */
          import java.util.*;
          import java.io.*;
          import java.net.*;

          public class SystemProperty
          {
          ????public static void main(String[] args)
          ????{
          ????????String sSoapUrl=" ????????System.out.println("Connecting to [" + sSoapUrl + "]");

          ????????URLConnection urlConnection = null;
          ????????URL url=null;

          ????????try
          ????????{
          ????????????url = new URL((URL)null, sSoapUrl, new
          HttpTimeoutHandler(10000));
          ????????????urlConnection = url.openConnection();

          ????????????// Optional
          ????????????url.setURLStreamHandlerFactory(new
          HttpTimeoutFactory(10000));

          ????????????System.out.println("Url class
          ["+urlConnection.getClass().getName()+"]");
          ????????}
          ????????catch (MalformedURLException mue)
          ????????{
          ????????????System.out.println(">>MalformedURLException<<");
          ????????????mue.printStackTrace();
          ????????}
          ????????catch (IOException ioe)
          ????????{
          ????????????System.out.println(">>IOException<<");
          ????????????ioe.printStackTrace();
          ????????}

          ????????HttpURLConnection httpConnection =
          (HttpURLConnection)urlConnection;
          ????????System.out.println("Connected to [" + sSoapUrl + "]");

          ????????byte[] messageBytes=new byte[10000];
          ????????for (int i=0; i<10000; i++)
          ????????{
          ????????????messageBytes[i]=80;
          ????????}

          ????????try
          ????????{
          ????????????httpConnection.setRequestProperty("Connection", "Close");
          ????????????httpConnection.setRequestProperty("Content-Length",
          String.valueOf(messageBytes.length));
          ????????????httpConnection.setRequestProperty("Content-Type",
          "text/xml; charset=utf-8");
          ????????????httpConnection.setRequestMethod("POST");
          ????????????httpConnection.setDoOutput(true);
          ????????????httpConnection.setDoInput(true);
          ????????}
          ????????catch (ProtocolException pe)
          ????????{
          ????????????System.out.println(">>ProtocolException<<");
          ????????????pe.printStackTrace();
          ????????}

          ????????OutputStream outputStream=null;

          ????????try
          ????????{
          ????????????System.out.println("Getting output stream");
          ????????????outputStream =httpConnection.getOutputStream();
          ????????????System.out.println("Got output stream");

          ????????????outputStream.write(messageBytes);
          ????????}
          ????????catch (IOException ioe)
          ????????{
          ????????????System.out.println(">>IOException<<");
          ????????????ioe.printStackTrace();
          ????????}

          ????????try
          ????????{
          ????????????System.out.println("Getting input stream");
          ????????????InputStream is=httpConnection.getInputStream();
          ????????????System.out.println("Got input stream");

          ????????????byte[] buf = new byte[1000];
          ????????????int i;

          ????????????while((i = is.read(buf)) > 0)
          ????????????{
          ????????????????System.out.println(""+new String(buf));
          ????????????}
          ????????????is.close();
          ????????}
          ????????catch (Exception ie)
          ????????{
          ????????????ie.printStackTrace();
          ????????}

          ????}
          }

          Cheers,
          Niels

          來源:http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2004-01/3271.html
          ???? http://www.weblogicfans.net/viewthread.php?tid=1101
          ???? http://forums.sun.com/thread.jspa?threadID=568948
          備注:在HttpTimeoutClient類中的第二個構造函數中的:super(url,null,-1)改為super(url, (String)null,-1)即可。
          主站蜘蛛池模板: 克拉玛依市| 康保县| 霍州市| 安新县| 黄梅县| 阳原县| 海安县| 新源县| 清丰县| 大名县| 资兴市| 万盛区| 丰原市| 丰县| 昌乐县| 安乡县| 绥阳县| 景东| 靖远县| 涞水县| 金平| 札达县| 革吉县| 萍乡市| 公主岭市| 新巴尔虎左旗| 吕梁市| 什邡市| 黄石市| 松阳县| 东乡族自治县| 海阳市| 舒兰市| 凭祥市| 浙江省| 达州市| 娱乐| 宁武县| 星子县| 扬州市| 义马市|