需求:因為測試伺服器有多台,一般都是通過綁定host來訪問某一台測試伺服器,現在就想用代碼來實現綁定host的功能,這樣就省去了修改本機host的步驟。
以下是用代理來實現:
public static HttpURLConnection getConnection(String urlstr, String proxyhost)throws Exception { URL url = new URL(urlstr); byte ip[] = new byte[4]; String arr[] = proxyhost.split("\\."); for (int i = 0; i < 4; i++) { int tmp = Integer.valueOf(arr[i]); ip[i] = (byte) tmp; } //產生proxy代理對象,因為http底層是socket實現 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress( InetAddress.getByAddress(ip), 80)); return (HttpURLConnection) url.openConnection(proxy);}public static void main(String[] args) throws Exception { String url = "http://www.xujsh.com/api/hao123"; String proxyhost = "192.168.119.182"; HttpURLConnection httpUrlConn = getConnection(url, proxyhost); InputStream in = httpUrlConn.getInputStream(); String response = FileUtil.getContent(in, "UTF-8"); System.out.println(response);}
參考:http://blog.csdn.net/zhongweijian/article/details/7619453
以下是基於HttpClient的實現:
public static void main(String[] args)throws Exception { HttpHost proxyhost = new HttpHost("192.168.119.182", 80, "http"); DefaultHttpClient httpclient = new DefaultHttpClient(); try { httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyhost); HttpHost targethost = new HttpHost("www.xujsh.com", 80, "http"); HttpGet get = new HttpGet("/api/hao123"); System.out.println("executing request to " + targethost + " via " + proxyhost); HttpResponse rsp = httpclient.execute(targethost, get); HttpEntity entity = rsp.getEntity(); System.out.println("----------------------------------------"); System.out.println(rsp.getStatusLine()); Header[] headers = rsp.getAllHeaders(); for (int i = 0; i<headers.length; i++) { System.out.println(headers[i]); } System.out.println("----------------------------------------"); if (entity != null) { System.out.println(EntityUtils.toString(entity)); } } finally { httpclient.getConnectionManager().shutdown(); }}
其實也不難理解,原理大概就是:用戶端發送一個請求給服務端,如果服務端是一個Proxy 伺服器,它就會轉寄用戶端的請求,如果服務端不是一個Proxy 伺服器,
而只是一台普通的應用伺服器,它就是自己來響應這個請求。
其實Proxy 伺服器本身也不是什麼神秘的東西,我們來自己寫一個簡單的Proxy 伺服器。在原生8989連接埠接收用戶端的請求,然後進行轉寄。
服務端:
public class MyProxyServer { public static void main(String[] args) { try { new Thread(new SimpleProxyServer(8989)).start(); } catch (IOException e) { e.printStackTrace(); } }}class SimpleProxyServer implements Runnable { private ServerSocket listenSocket; public SimpleProxyServer(int port) throws IOException { this.listenSocket = new ServerSocket(port); } public void run() { for (;;) { try { Socket clientSocket = listenSocket.accept(); System.out .println("Create a new Thread to handle this connection"); new Thread(new ConnectionHandler(clientSocket)).start(); } catch (IOException e) { e.printStackTrace(); } } }}class ProxyCounter { static int sendLen = 0; static int recvLen = 0; public static void showStatistics() { System.out.println("sendLen = " + sendLen); System.out.println("recvLen = " + recvLen); }}// must close sockets after a transactionclass ConnectionHandler extends ProxyCounter implements Runnable { private Socket clientSocket; private Socket serverSocket; private static final int bufferlen = 1024*1024; public ConnectionHandler(Socket clientSocket) { this.clientSocket = clientSocket; } public void run() { // receive request from clientSocket, // extract hostname, // create a serverSocket to communicate with the host // count the bytes sent and received try { byte[] buffer = new byte[bufferlen]; int count = 0; InputStream inFromClient = clientSocket.getInputStream(); count = inFromClient.read(buffer); String request = new String(buffer, 0, count); System.out.println("request:\n"+request); String host = extractHost(request); System.out.println("host:\n"+host); // create serverSocket Socket serverSocket = new Socket(host, 80); // forward request to internet host OutputStream outToHost = serverSocket.getOutputStream(); outToHost.write(buffer, 0, count); outToHost.flush(); sendLen += count; showStatistics(); // forward response from internet host to client InputStream inFromHost = serverSocket.getInputStream(); OutputStream outToClient = clientSocket.getOutputStream(); while (true) { count = inFromHost.read(buffer); System.out.println("count:"+count); if (count < 0) break; outToClient.write(buffer, 0, count); outToClient.flush(); recvLen += count; showStatistics(); } } catch (IOException e) { e.printStackTrace(); } finally { try { if(clientSocket != null)clientSocket.close(); if(serverSocket != null)serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } private String extractHost(String request) { int start = request.indexOf("Host: ") + 6; int end = request.indexOf('\n', start); String host = request.substring(start, end - 1); return host; }}
參考:http://my.oschina.net/u/158589/blog/64643
用戶端測試:
public class MyProxyClient { public static void main(String[] args) throws Exception { Socket socket = new Socket("localhost",8989); OutputStream out = socket.getOutputStream(); out.write("GET / HTTP/1.1\nHost: www.baidu.com \n\n".getBytes()); out.flush(); InputStream in = socket.getInputStream(); byte[] arr = FileUtil.readAsByteArray(in); System.out.println(new String(arr)); socket.close(); }}
關於javaProxy 伺服器設定的,參考:http://blog.csdn.net/mebusw/article/details/6372714