责任链模式-通过自定义过滤器过滤javascript代码和敏感字符。

1.背景:网页若被javascript代码篡改,将发生一些不好的事情,比如在网页中插入如下打广告代码:

<script>setInterval(function(){alert('代购驾照分,有意请联系QQ:12345678.(每隔两秒弹出一次)')},2000);</script>
原网页内容:Java学习经典案例,优秀代码集锦!请勿错过。

新网页内容:Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系QQ:13452456.(每隔两秒弹出一次)')},2000);</script>。

将新网页内容保存到一个html文件中,然后访问,效果如下(每隔两秒弹出一次广告):


2. 处理上述问题可以责任链模式,每个过滤器负责自己过滤的职责,如果有过滤任务,就过滤,不过滤就放行资源。

创建自定义过滤器过滤掉javascript代码和隐藏7位以上的QQ号(QQ号一般都比较长,隐藏7位以上长度的数字,可避免将其它数字也隐藏掉)

过滤器接口 MyFilter:

public interface MyFilter {
	/**
	 * @param word	过滤前字符
	 * @param ret	过滤后结果
	 * @param filter	自定义过滤器链
	 */
	public abstract void doFilter(String word,String[] ret,MyFilterChain filter);

}
过滤javascript代码的过滤器JavascriptFilter

/**
 * JavaScript过滤:过滤
 * 
 * @author kick
 */
public class JavascriptFilter implements MyFilter {
	@Override
	public void doFilter(String word, String[] ret, MyFilterChain filterChain) {
		if (ret.length > 0 && !"".equals(ret[0])) {
			word = ret[0];// 将上一次过滤后的结果作为本次的过滤数据(比如上一次进行了敏感词汇过滤,将去掉敏感词汇后的结果作为待过滤数据)
		}
		//本次过滤数据操作
		try {
			//当网页内容出现 <script> </script>关键字时才过滤小于号和打于号
			if (word.matches("^.*(</?script>).*$")) {//正则表达式,匹配<script>或</script>
				ret[0] = word.replaceAll("<", "<").replaceAll(">", ">")
						+ "\n-1.调用JavascriptFilter-网页中的javascript代码已替换";
			}
			filterChain.doFilter(word, ret, filterChain);//正常过滤后放行,让过滤器链执行下一个过滤器
		} catch (Exception e) {
			e.printStackTrace();
			return;//过滤时发生异常,不执行后续过滤器,直接返回
		}
	}
}

 隐藏含有QQ关键字的文本中连续7位及以上的数字

/**
 * 敏感词汇过滤(当存在大小写QQ关键字并且含有连续7位及以上数字时,将数字隐藏)
 * @author kick
 */
public class SensitiveFilter implements MyFilter {
	@Override
	public void doFilter(String word, String[] ret, MyFilterChain filterChain) {
		if (ret.length > 0 && !"".equals(ret[0])) {
			word = ret[0];//将上一次过滤结果作为本次过滤数据
		}
		try {
			if (word.contains("QQ") || word.contains("qq")) {
				ret[0] = word.replaceAll("\\d{7,}", "*******")
						+ "\n-2.调用SensitiveFilter-网页中含有qq数字,已将7位以上连续数字隐藏";
			}
			filterChain.doFilter(word, ret, filterChain);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
	}
}

过滤器链

/**
 * 过滤器链:可添加多个过滤器,并使用它们的过滤功能
 * @author kick
 */
public class MyFilterChain implements MyFilter{//实现MyFilter接口,在遵循MyFilter方法规范下扩展了过滤功能,简单说就是可以使用过滤功能了
	private List<MyFilter> filters =new ArrayList<MyFilter>();//过滤器链,存储所有过滤器
	int index=-1;//定位过滤器执行位置
	
	/**
	 * 向过滤器链添加过滤器
	 * @param filter 待添加的过滤器
	 * @return 过滤器链本身(不返回值也可以,返回本身,主要是为了链式编程,在添加多个过滤器时再次访问本身的某个方法(添加或移除),
	 * 不明白的看后续测试代码)
	 */
	public MyFilterChain addFilter(MyFilter filter) {
		filters.add(filter);
		return this;
	}
	
	/**
	 * 在过滤器链中移除已添加的过滤器
	 * @param filter 已在过滤器链中的过滤器
	 * @return 过滤器链本身(同上,用于移除多个过滤器时的链式编程)
	 */
	public MyFilterChain removeFilter(MyFilter filter){
		filters.remove(filter);
		return this;
	}

	@Override
	public void doFilter(String word,String[] ret,MyFilterChain filterChain) {
		if(index < filters.size()-1){
			index++;
			filters.get(index).doFilter(word, ret, this);
		}else{
			index = -1;
		}
	}
}

3.模拟测试

使用字符串badHtml模拟被篡改的网页内容

使用字符串noQQHtml模拟只有javascript代码,而无QQ关键字时,过滤器仍能正常运行,且只过滤javascript代码,而不隐藏其中7位及以上的数字。

	public static void main(String[] args) {
		String badHtml="Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系QQ:13452456.(每隔两秒弹出一次)')},2000);</script>";
		String noQQHtml="Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系:13452456.(每隔两秒弹出一次)')},2000);</script>";
		MyFilter javascriptFilter = new  JavascriptFilter();
		MyFilter sensitiveFilter = new SensitiveFilter();
		MyFilterChain filterChain = new MyFilterChain();
		
		filterChain.addFilter(javascriptFilter)
			.addFilter(sensitiveFilter);
		
		String[] returnHtml={""};//过滤后字符串接收数组
		filterChain.doFilter(badHtml,returnHtml,filterChain);
		System.out.println("过滤前网页内容:\n"+badHtml);
		System.out.println("过滤后网页内容:\n"+returnHtml[0]);
		System.out.println("-------------------------------------------");
		String[] noQQReturn={""};//过滤后字符串接收数组
		filterChain.doFilter(noQQHtml, noQQReturn, filterChain);
		System.out.println("无QQ号过滤前网页内容:\n"+noQQHtml);
		System.out.println("无QQ号过滤后网页内容:\n"+noQQReturn[0]);
	}

测试结果:

过滤器顺序跟过滤器链中集合元素顺序有关(先添加哪个过滤器就先执行哪个过滤功能)

过滤前网页内容:
Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系QQ:13452456.(每隔两秒弹出一次)')},2000);</script>
过滤后网页内容:
Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系QQ:*******.(每隔两秒弹出一次)')},2000);</script>
-1.调用JavascriptFilter-网页中的javascript代码已替换
-2.调用SensitiveFilter-网页中含有qq数字,已将7位以上连续数字隐藏
-------------------------------------------
无QQ号过滤前网页内容:
Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系:13452456.(每隔两秒弹出一次)')},2000);</script>
无QQ号过滤后网页内容:
Java学习经典案例,优秀代码集锦!请勿错过。<script>setInterval(function(){alert('代购驾照分,有意请联系:13452456.(每隔两秒弹出一次)')},2000);</script>
-1.调用JavascriptFilter-网页中的javascript代码已替换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenick

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值