设置常用过滤器-站点黑名单、内容压缩

设置站点黑名单的过滤器

功能描述

不允许从禁用的站点(IP)访问当前应用,也不允许从禁用的站点链接到当前应用。
       
为了简单起见,设置禁用站点时,暂不支持使用通配符。只是抛砖引玉了。
       
比如:禁止其他的网站引用本站的图片资源,只需在此基础上稍作修改即可。

使用方法

在 java web 项目的 web.xml
文件中添加如下代码。


<!--设置站点黑名单的过滤器配置  开始 -->
<filter>
<filter-name>BannedAccessFilter</filter-name>
<filter-class>com.hmw.filter.BannedAccessFilter</filter-class>
<init-param>
<description>需要禁用的站点,一个站点占用一行</description>
<param-name>bannedSites</param-name>
<param-value>
192.168.1.101
192.168.1.102
www.csdn.net
</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>BannedAccessFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--设置站点黑名单的过滤器配置 结束 -->

过滤器源码


package com.hmw.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.StringTokenizer;

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;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/**
* 设置禁用站点(黑名单)的过滤器
*/
public class BannedAccessFilter implements Filter {
static final Logger logger = Logger.getLogger(BannedAccessFilter.class);

private HashSet bannedSiteTable;

/**
* 将配置的禁用站点列表初始化到一个 HashSet 中
*/
@Override
public void init(FilterConfig config) throws ServletException {
bannedSiteTable = new HashSet();
String bannedSites = config.getInitParameter("bannedSites");
// Default token set: white space.
StringTokenizer tok = new StringTokenizer(bannedSites);
while (tok.hasMoreTokens()) {
String bannedSite = tok.nextToken();
bannedSiteTable.add(bannedSite);
logger.info("Banned " + bannedSite);
}
}

/**
* 如果请求来自被禁用的站点,或是从被禁用的站点链接过来的,则拒绝访问。
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
logger.debug("BannedAccessFilter: Filtering the Request...");

HttpServletRequest req = (HttpServletRequest) request;
String requestingHost = req.getRemoteHost();
String referringHost = getReferringHost(req.getHeader("Referer"));

String bannedSite = null;
boolean isBanned = false;
if (bannedSiteTable.contains(requestingHost)) {
bannedSite = requestingHost;
isBanned = true;
} else if (bannedSiteTable.contains(referringHost)) {
bannedSite = referringHost;
isBanned = true;
}

if (isBanned) {
showWarning(response, bannedSite);
} else {
chain.doFilter(request, response);
}

logger.debug("BannedAccessFilter: Filtering the Response...");
}

@Override
public void destroy() {
}

/**
* 根据 URL 链接地址,取得该链接地址所在的站点
* @param refererringURLString URL链接地址
* @return 该 URL 链接地址所在的站点,如果传入的参数不是一个符合URL规范的字符串,则返回 <CODE>null</CODE>
*/
private String getReferringHost(String refererringURLString) {
if(StringUtils.isBlank(refererringURLString))
return null;

try {
URL referringURL = new URL(refererringURLString);
return referringURL.getHost();
} catch (MalformedURLException mue) { // Malformed
return null;
}
}

/**
* 如果用户是从禁用站点访问的该应用,或是从禁用站点链接过来的,则调用此方法将警告信息展现给用户。
* @param response HTTP请求响应对象
* @param bannedSite 禁止的站点
* @throws ServletException
* @throws IOException
* @author <A href="mailto:[email protected]">何明旺</A>
*/
private void showWarning(ServletResponse response, String bannedSite) throws ServletException, IOException {
String htmlCode = "";
htmlCode += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
htmlCode += "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
htmlCode += " <head>";
htmlCode += " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
htmlCode += " <title>禁止访问</title>";
htmlCode += " </head>";
htmlCode += " <body>";
htmlCode += " <h1>禁止访问</h1>";
htmlCode += " <p>对不起,您无法访问该资源,因为您的站点已经被列入我们的黑名单!</p>";
htmlCode += " <p>您的站点是:<strong>" + bannedSite + "</strong></p>";
htmlCode += " </body>";
htmlCode += "</html>";

response.setContentType("text/html");
PrintWriter out = null;
try{
out = response.getWriter();
out.println(htmlCode);
}finally{
if(out != null){
out.flush();
out.close();
}
}

/*
* 也可以使用下面的方法直接转发或重定向到指定的警告页面
* 转发:
* ((HttpServletRequest)request).getRequestDispatcher("/warn.html").forward(request, response);
* 重定向:
* ((HttpServletResponse)response).sendRedirect("webAppContext/warn.html");
*/
}
}

将响应数据进行压缩处理的过滤器


功能描述


如果浏览器支持 gzip 压缩格式的数据,则将响应的数据使用
gzip 压缩后再输出。

使用方法

在 java web 项目的 web.xml
文件中添加如下代码。


<!--压缩过滤器的配置  开始 -->
<filter>
<filter-name>CompressionFilter</filter-name>
<filter-class>com.hmw.filter.CompressionFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>CompressionFilter</filter-name>
<servlet-name>/LongServlet</servlet-name>
</filter-mapping>
<!--压缩过滤器的配置 结束 -->

过滤器源码


CompressionFilter.java
?package com.hmw.filter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.zip.GZIPOutputStream;

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;
import javax.servlet.http.HttpServletResponse;

/**
* 压缩过滤器 <BR>
* 如果浏览器支持 gzip 压缩格式的数据,则将响应的数据使用 gzip 压缩后再输出。
* */
public class CompressionFilter implements Filter {

@Override
public void init(FilterConfig config) throws ServletException {
}

/**
* 如果浏览器不支持 gzip 压缩,则不做直接放行(不做压缩处理)<BR>
* 反之,将HTTP响应头的编码设置为 <CODE>gzip</CODE>,然后将响应数据使用 gzip 进行压缩处理。
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;

if (!isGzipSupported(req)) { // Invoke resource normally.
chain.doFilter(req, res);
return;
}

// 将响应头信息中的内容编码设置为 gzip
res.setHeader("Content-Encoding", "gzip");

// 调用资源,使用 CharArrayWrapper 包装输出
CharArrayWrapper responseWrapper = new CharArrayWrapper(res);
chain.doFilter(req, responseWrapper);
// 取得存放输出数据的 char 型数组
char[] responseChars = responseWrapper.toCharArray();

// 将响应数据压缩后存入一个 byte 型的数组,然后输出到
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
GZIPOutputStream zipOut = new GZIPOutputStream(byteStream);
OutputStreamWriter tempOut = new OutputStreamWriter(zipOut);
// 将原来的响应数据压缩后写入二字节输出流
tempOut.write(responseChars);
// 关闭输出流
tempOut.close();

// 更新响应头信息中 Content-Length 的值。
res.setContentLength(byteStream.size());
// 将压缩后的数据发送至客户端
OutputStream realOut = res.getOutputStream();
byteStream.writeTo(realOut);
}

@Override
public void destroy() {
}

/**
* 检测浏览器是否支持 Gzip 压缩
*
* @param req HTTP 请求对象
* @return 如果浏览器支持 Gzip 压缩,则返回 true,反之,则返回 false
*/
private boolean isGzipSupported(HttpServletRequest req) {
String browserEncodings = req.getHeader("Accept-Encoding");
return ((browserEncodings != null) && (browserEncodings.indexOf("gzip") != -1));
}
}
CharArrayWrapper.java
?package com.hmw.filter;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
* A response wrapper that takes everything the client would normally output and
* saves it in one big character array.
*/
public class CharArrayWrapper extends HttpServletResponseWrapper {
private CharArrayWriter charWriter;

/**
* Initializes wrapper.
* <P>
* First, this constructor calls the parent constructor. That call is
* crucial so that the response is stored and thus setHeader, *setStatus,
* addCookie, and so forth work normally.
* <P>
* Second, this constructor creates a CharArrayWriter that will be used to
* accumulate the response.
*/
public CharArrayWrapper(HttpServletResponse response) {
super(response);
charWriter = new CharArrayWriter();
}

/**
* When servlets or JSP pages ask for the Writer, don‘t give them the real
* one. Instead, give them a version that writes into the character array.
* The filter needs to send the contents of the array to the client (perhaps
* after modifying it).
*/
@Override
public PrintWriter getWriter() {
return new PrintWriter(charWriter);
}

/**
* Get a String representation of the entire buffer.
* <P>
* Be sure <B>not</B> to call this method multiple times on the same
* wrapper. The API for CharArrayWriter does not guarantee that it
* "remembers" the previous value, so the call is likely to make a new
* String every time.
*/
@Override
public String toString() {
return charWriter.toString();
}

/** Get the underlying character array. */
public char[] toCharArray() {
return charWriter.toCharArray();
}
}

替换禁用语(指定关键字)


功能描述


将请求响应中所有的禁用关键字替换掉之后再输出。

使用方法

在 java web 项目的 web.xml
文件中添加如下代码。


<!--替换关键字的过滤器配置  开始 -->
<filter>
<filter-name>StopWordsFilter</filter-name>
<filter-class>com.hmw.filter.StopWordsFilter</filter-class>
<init-param>
<description>需要禁用的关键字,一个关键字占一行</description>
<param-name>keys</param-name>
<param-value>
QQ
百度
七一五
</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>StopWordsFilter</filter-name>
<servlet-name>*.jsp</servlet-name>
</filter-mapping>
<!--替换关键字的过滤器 结束 -->

过滤器源码


ReplaceKeyWordFilter.java
?package com.hmw.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;

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.HttpServletResponse;

/**
* 替换关键字的滤器 <BR>
* */
public class StopWordsFilter implements Filter {
private Set keyWords = new HashSet();

/**
* 将需要进行替换的关键字添加到一个定义好的 Set 中
*/
@Override
public void init(FilterConfig config) throws ServletException {
String keys = config.getInitParameter("keys");
StringTokenizer tokenizer = new StringTokenizer(keys);
String token = null;
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if(token != null && token.length() > 0){
keyWords.add(tokenizer.nextToken());
}
}
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws ServletException, IOException {
CharArrayWrapper responseWrapper = new CharArrayWrapper(
(HttpServletResponse) response);
// 调用请求资源(使用自己包装的 responseWrapper)
chain.doFilter(request, responseWrapper);
// 取得响应字符串
String responseString = responseWrapper.toString();
// 将需要替换的关键字用“**”替换掉
Iterator iter = keyWords.iterator();
while (iter.hasNext()) {
responseString = replace(responseString, iter.next(), "**");
}

// 修改响应头信息中的 Content-Length
response.setContentLength(responseString.length());
PrintWriter out = response.getWriter();
out.write(responseString);
}

@Override
public void destroy() {
}

/**
* 将字符串中的所有的指定子字符串替换掉
* @param mainString 需要进行替换的字符串
* @param orig 需要被替换的子串
* @param replacement 替换后的新串
* @return 返回替换后的字符串
*/
public static String replace(String mainString, String orig, String replacement) {
String result = "";
int oldIndex = 0;
int index = 0;
int origLength = orig.length();
while ((index = mainString.indexOf(orig, oldIndex)) != -1) {
result = result + mainString.substring(oldIndex, index) + replacement;
oldIndex = index + origLength;
}
result = result + mainString.substring(oldIndex);
return result;
}
}
CharArrayWrapper.java
?package com.hmw.filter;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
* A response wrapper that takes everything the client would normally output and
* saves it in one big character array.
*/
public class CharArrayWrapper extends HttpServletResponseWrapper {
private CharArrayWriter charWriter;

/**
* Initializes wrapper.
* <P>
* First, this constructor calls the parent constructor. That call is
* crucial so that the response is stored and thus setHeader, *setStatus,
* addCookie, and so forth work normally.
* <P>
* Second, this constructor creates a CharArrayWriter that will be used to
* accumulate the response.
*/
public CharArrayWrapper(HttpServletResponse response) {
super(response);
charWriter = new CharArrayWriter();
}

/**
* When servlets or JSP pages ask for the Writer, don‘t give them the real
* one. Instead, give them a version that writes into the character array.
* The filter needs to send the contents of the array to the client (perhaps
* after modifying it).
*/
@Override
public PrintWriter getWriter() {
return new PrintWriter(charWriter);
}

/**
* Get a String representation of the entire buffer.
* <P>
* Be sure <B>not</B> to call this method multiple times on the same
* wrapper. The API for CharArrayWriter does not guarantee that it
* "remembers" the previous value, so the call is likely to make a new
* String every time.
*/
@Override
public String toString() {
return charWriter.toString();
}

/** Get the underlying character array. */
public char[] toCharArray() {
return charWriter.toCharArray();
}
}

设置常用过滤器-站点黑名单、内容压缩,码迷,mamicode.com

时间: 2024-11-02 00:16:37

设置常用过滤器-站点黑名单、内容压缩的相关文章

设置常用的过滤器-不适用缓存、登陆过滤器

设置不使用缓存的过滤器 功能描述 将HTTP响应头信息中的缓存参数设置为不进行缓存. 使用方法 在 java web 项目的 web.xml 文件中添加如下代码. <!--设置不使用缓存的过滤器配置 开始 --> <filter> <filter-name>ClearCacheFilter</filter-name> <filter-class>com.hmw.filter.ClearCacheFilter</filter-class>

Linux常用命令大全 --- 文件备份和压缩命令

在linux中,常用的文件压缩工具有gzip.bzip2.zip . bzip2是最理想的压缩工具,它提供了最大限度的压缩.zip 兼容性好windows也支持 1.bzip2 命令 在shell 提示下输入命令: 压缩文件:bzip2 filename //文件即会被压缩,并被保存为 filename.bz2 解压文件:bunzip2 filename.bz2 //filename.bz2会被删除,而以filename代替 bzip2 filename.bz2 file1 file2 file

Nginx演练(3)配置内容压缩

如果对HTTP熟悉的话,对request-response请求过程应该很熟悉. 比如访问"www.jd.com",一个完整页面的访问,往往会经过很多次的HTTP请求共同完成,这中间会涉及到浏览器并发数.具体片段如图 客户端请求的资源内容有多种,jpg,css,js,html等.不同文件类型,对应不同MIME_TYPE.每个文件都要通过网络传输到客户端,才能被浏览器渲染,进而展现给用户.想必大家都有给朋友发送文件的经历吧,不管是QQ传输,还是Email传送.如果一个文件过大,想节省点传输

设置SharePoint部门站点各个文件夹的权限

最近跟客户设置了下部门站点文件夹的权限,现整理一下实现步骤: 1. Site actions –> site permissions: 停止继承,并把部门所有员工都授予Read权限: 2. 在Shared Documents下面有几个文件夹(一级目录),保持继承关系: 3. 在二级目录设置权限,停止继承关系,删除原来所有继承下来的帐号(当前操作的帐号除外),并授予相关人员为owner(full control),read,write权限. 4. 有的帐号对所有站点的文件夹都有Read的权限,这时

07 http内容压缩

一:http内容压缩 思考: Content-Length在之前的学习中,我们知道,代表返回的主体的长度 但此处,为什么返回的主体长度和content-length不一致呢? 原因在于: Content-Encoding: gzip 这个响应头信息在作用. 原理: 为了提高网页在网络上的传输速度,服务器对主体信息进行压缩. 如常见的 gzip压缩,deflate压缩, compress压缩,以及google chrome正在推的sdch压缩. 压缩的过程是这样 如何在apache启用压缩功能?

VBScript设置和获取剪切板内容的方法

Automation中经常需要程序和剪切板交互,还在使用键盘一个一个input?内容多的话,岂不是太慢了,使用剪切板的黏贴复制,so fast,so easy--具体需要调用Microsoft Forms 2.0 Object Library的对象和方法,用它轻松实现设置和获取剪切板的内容,下面写了2个设置和获取剪切板内容的函数,需要的时候直接调用~  'operating clipboard Function setClipboard(str)     'setting clipboard's

java Web常用过滤器

一.使浏览器不缓存页面的过滤器   import javax.servlet.*;   import javax.servlet.http.HttpServletResponse;   import java.io.IOException;     /*** 用于的使 Browser 不缓存页面的过滤器*/  public class ForceNoCacheFilter implements Filter {     public void doFilter(ServletRequest re

jQuery.ajax() 如何设置 Headers 中的 Accept 内容

其实很简单,首先如果是常见类型,则请直接设置 dataType 属性 $.ajax({ dataType: "json", type: "get", success: function (data) { } }); 设置 dataType 后,会去 accepts 属性(此属性会预置一些常用类型)中直接拿相应的类型添加到 Accept 中. 如果想自己自定义 jQuery 中没有的 Accept 内容,可以手动设置 accepts 属性,使用 键值对 存储,然后再设

织梦开启二级域名(多站点)内容页图片无法显示的解决方法

用织梦建站时,有时候我们会给某栏目绑定二级域名,并开启织梦Dedecms开启多站点支持.但这样该栏目的文章中的图片就会无法显示了,这主要是因为织梦默认状况下,文章中调用图片的路径是相对路径,我们绑定了二级域名,导致图片路径错误,不能正常访问到图片. 解决方法很简单,思路就是让文章内容中的图片路径都用绝对路径调用.我们要做的操作主要针对两部分文章,第一部分是已经生成的文章图片路径更改.第二部分是让新生成的图片路径默认成绝对路径. 一.把已经生成的文章中的图片路径改成绝对路径 1.进入织梦后台--核