最初有这个想法是因为最近某国外最大的开源技术网站被封,一时间我也找不到太好的代理,正好我知道一个国外的免费的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.youkuaiyun.com/sunyujia/
* </p>
*
* @author 孙钰佳
* @main sunyujia@yahoo.cn
* @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 {
}
}
web.xml
<?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才行,否则的话相对路径就不起作用了。不能实现相对路径的正常代理。