最初有这个想法是因为最近某国外最大的开源技术网站被封,一时间我也找不到太好的代理,正好我知道一个国外的免费的jsp空间(http://s43.eatj.com/index.jsp),于是想自己做个代理,这样速度快些,起初想使用比较专业的做法,但是发现那样的话需要开端口,在免费空间上开端口那是不可能的,于是就想到了URLConnection。
将待访问的网址请求到国外空间,然后在由国外的空间利用URLConnection访问目标网站,将返回的结果返回给浏览器,原理还是非常简单的,模仿其他在线代理网站首页放个iframe,利用网站的相对路径特性,使用URLConnection做非专业的代理其实也是很简单的,由于网页的展示是靠URLConnection返回的字符串,这样的话目标网站的相对路径就已经改变了。下面是实现代码:
<%@ page language="java" pageEncoding="GBK"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <div> <form action="MyJsp.jsp" target="proxyFrame"> URL:<input name="proxyUrl" value="http://sourceforge.net/projects/r2tech-eclipse" size="100" /> <input type="submit" value="提交"> </form> </div> <iframe name="proxyFrame" id="proxyFrame" height="100%" width="100%"></iframe> </body> </html>
<%@ page language="java" pageEncoding="GBK"%> <%@page import="java.net.*"%> <% request.setCharacterEncoding("GBK"); String url=(String)request.getAttribute("url"); URL theURL = new URL(url);/ URLConnection urlConnection = theURL.openConnection(); urlConnection.connect(); out.println(url); String content=com.syj.filter.IOUtil.readString(com.syj.filter.IOUtil.buildReader(urlConnection.getInputStream())); out.println(content); %>
package com.syj.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; /** * <p> * Title: * </p> * * <p> * Description: * </p> * * <p> * Copyright: 转载请注明出处http://blog.csdn.net/sunyujia/ * </p> * * @author 孙钰佳 * @main [email protected] * @date Jun 30, 2008 11:10:46 PM */ public class HttpProxy implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; try { String url = request.getParameter("proxyUrl"); String site = null; if (url != null) { int idx = url.replaceFirst("//", "xx").indexOf("/"); if (idx > 0) site = url.substring(0, idx); else site = url; request.getSession().setAttribute("site", site); } else { site = (String) request.getSession().getAttribute("site"); if (site != null) { String qs = request.getQueryString(); url = request.getServletPath() + (qs == null ? "" : ("?" + qs)); url.replaceAll("//", "/"); url = site + url; } } request.setAttribute("url", url); if (request.getServletPath().equals("/index.jsp") || request.getServletPath().equals("/MyJsp.jsp")) { chain.doFilter(request, response); return; } request.getSession().getServletContext().getRequestDispatcher( "/MyJsp.jsp").forward(request, response); } catch (Throwable e) { request.getSession().getServletContext().getRequestDispatcher( "/MyJsp.jsp").forward(request, response); } } public void init(FilterConfig filterConfig) throws ServletException { } }
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>HttpProxy</filter-name> <filter-class>com.syj.filter.HttpProxy</filter-class> </filter> <filter-mapping> <filter-name>HttpProxy</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
另注:如果要使用tomcat发布的话一定要配置为ROOT才行,否则的话相对路径就不起作用了。不能实现相对路径的正常代理。