项目上有个小需求,要限制访问者的IP,屏蔽未授权的请求。该场景使用过滤器来做再合适不过了。

SecurityFilter.java:

public class SecurityFilter implements Filter {

    private Log log = LogFactory.getLog(SecurityFilter.class);
private List<String> whitelist = new ArrayList<String>();
private List<String> regexlist = new ArrayList<String>();
private static final String _JSON_CONTENT = "application/json; charset=UTF-8";
private static final String _HTML_CONTENT = "text/html; charset=UTF-8";
private static final String _403_JSON = "{'code': '403', 'msg': '访问被拒绝,客户端未授权!'}";
private static final String _403_HTML = "<html><body><div style='text-align:center'><h1 style='margin-top: 10px;'>403 Forbidden!</h1><hr><span>@lichmama</span></div></body></html>"; @Override
public void destroy() {
} @Override
public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletrequest;
HttpServletResponse response = (HttpServletResponse) servletresponse;
if (isSecurityRequest(request)) {
filterchain.doFilter(request, response);
} else {
log.info("拒绝来自[" + request.getRemoteAddr() + "]的访问请求:" + request.getRequestURI());
response.setStatus(403);
if (isAjaxRequest(request)) {
response.setContentType(_JSON_CONTENT);
response.getWriter().print(_403_JSON);
} else {
response.setContentType(_HTML_CONTENT);
response.getWriter().print(_403_HTML);
}
}
} @Override
public void init(FilterConfig filterconfig) throws ServletException {
String allowedIP = filterconfig.getInitParameter("allowedIP");
if (allowedIP != null && allowedIP.length() > 0) {
for (String item : allowedIP.split(",\\s*")) {
// 支持通配符*
if (item.contains("*")) {
String regex = item.replace(".", "\\.").replace("*", "\\d{1,3}");
regexlist.add(regex);
} else {
whitelist.add(item);
}
}
}
} /**
* 判断当前请求是否来自可信任的地址
*
* @param request
* @return
*/
private boolean isSecurityRequest(HttpServletRequest request) {
String ip = request.getRemoteAddr();
for (String item : whitelist) {
if (ip.equals(item))
return true;
}
for (String item : regexlist) {
if (ip.matches(item))
return true;
}
return false;
} /**
* 判断请求是否是AJAX请求
* @param request
* @return
*/
private boolean isAjaxRequest(HttpServletRequest request) {
String header = request.getHeader("X-Requested-With");
if (header != null && header.length() > 0) {
if ("XMLHttpRequest".equalsIgnoreCase(header))
return true;
}
return false;
}
}

web.xml增加配置:

    <filter>
<filter-name>securityFilter</filter-name>
<filter-class>com.lichmama.webdemo.filter.SecurityFilter</filter-class>
<init-param>
<param-name>allowedIP</param-name>
<param-value>192.168.5.*</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

尝试访问,结果如下:

*如何在Filter中获取Response的内容?这个问题之前还真没思考过,搜索了下得知如下方法可行:

1.实现一个PrintWriterWrapper,用于替换ServletResponse中的Writer

package com.lichmama.webdemo;

import java.io.PrintWriter;
import java.io.Writer; public class PrintWriterWrapper extends PrintWriter { private StringBuilder buff; public PrintWriterWrapper(Writer writer) {
super(writer);
buff = new StringBuilder();
} @Override
public void write(int i) {
super.write(i);
buff.append(i);
} @Override
public void write(char[] ac, int i, int j) {
super.write(ac, i, j);
buff.append(ac, i, j);
} @Override
public void write(char[] ac) {
super.write(ac);
buff.append(ac);
} @Override
public void write(String s, int i, int j) {
super.write(s, i, j);
buff.append(s, i, j);
} @Override
public void write(String s) {
super.write(s);
buff.append(s);
} @Override
public void flush() {
super.flush();
buff.delete(0, buff.length());
} public String getContent() {
return buff.toString();
}
}

2.实现一个ResponseWrapper,用于替换过滤链(FilterChain)中的ServletResponse:

package com.lichmama.webdemo;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper; public class ResponseWrapper extends HttpServletResponseWrapper { private PrintWriterWrapper writer; public ResponseWrapper(HttpServletResponse response) {
super(response);
} @Override
public PrintWriter getWriter() throws IOException {
if (writer == null)
writer = new PrintWriterWrapper(super.getWriter());
return writer;
} }

3.编写Filter实现获取Response的内容捕获:

package com.lichmama.webdemo.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.HttpServletResponse; import com.lichmama.webdemo.PrintWriterWrapper;
import com.lichmama.webdemo.ResponseWrapper; public class TestFilter implements Filter { @Override
public void init(FilterConfig filterconfig) throws ServletException {
} @Override
public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)
throws IOException, ServletException {
ResponseWrapper responsewrapper = new ResponseWrapper((HttpServletResponse) servletresponse);
filterchain.doFilter(servletrequest, responsewrapper);
PrintWriterWrapper writerWrapper = (PrintWriterWrapper) responsewrapper.getWriter();
// TODO retrieve content from PrintWriterWrapper
String content = writerWrapper.getContent();
} @Override
public void destroy() {
} }

that's it~

javaweb利用filter拦截请求的更多相关文章

  1. javaweb利用filter拦截未授权请求

    项目上有个小需求,要限制访问者的IP,屏蔽未授权的请求.该场景使用过滤器来做再合适不过了. SecurityFilter.java: public class SecurityFilter imple ...

  2. AOP与Filter拦截请求打印日志实用例子

    相信各位同道在写代码的时候,肯定会写一些日志打印,因为这对往后的运维而言,至关重要的. 那么我们请求一个restfull接口的时候,哪些信息是应该被日志记录的呢? 以下做了一个基本的简单例子,这里只是 ...

  3. Java继承Exception自定义异常类教程以及Javaweb中用Filter拦截并处理异常

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6403033.html 在项目中的应用见: https://github.com/ygj0930/CoupleS ...

  4. 利用Filter和拦截器,将用户信息动态传入Request方法

    前言: 在开发当中,经常会验证用户登录状态和获取用户信息.如果每次都手动调用用户信息查询接口,会非常的繁琐,而且代码冗余.为了提高开发效率,因此就有了今天这篇文章. 思路: 用户请求我们的方法会携带一 ...

  5. 利用Filter解决跨域请求的问题

    1.为什么出现跨域. 很简单的一句解释,A系统中使用ajax调用B系统中的接口,此时就是一个典型的跨域问题,此时浏览器会出现以下错误信息,此处使用的是chrome浏览器. 错误信息如下: jquery ...

  6. JavaWeb之Filter过滤器

    原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可以锻炼锻炼.言归正传,过滤器从字面理解她的话有拦网.过滤的功 ...

  7. [JavaWeb] Servlet Filter

    作用: Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息. 可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet.Servle ...

  8. JavaWeb—过滤器Filter

    1.Filter简介 Filter称之为过滤器,是用来做一些拦截的任务.比如客户端请求服务器的某个资源时(可以是Servlet.JSP.HTML等等),我们可以拦截.当服务器返回资源给客户端的时候,我 ...

  9. JavaWeb 之 Filter:过滤器

    一.Filter 概述 1.概念 web 中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能. 2.作用 一般用于完成通用的操作.如:登录验证.统一编码处理.敏感字符等功能 ...

随机推荐

  1. swift学习 - collectionView

    swift CollectionView学习 效果图: 源码: ContModel.swift import UIKit class ContModel: NSObject { var title:S ...

  2. struts2.1.6教程十二、总结

    本教程对struts2的基本知识进行了一些说明,关于struts2的更多详细内容应参看struts2的官方文档及提供的app实例. 下面对struts2的基本执行流程作一简要说明,此流程说明可以结合官 ...

  3. Linux下让一个程序开机自动启动

    1.chkconfig但是要在脚本中满足一定的条件(/etc/init.d/)下存在相关服务 2.将启动的程序写入到/etc/rc.local 选择建议: /etc/rc.local可以作为开机启动程 ...

  4. python面向对象的编程

    self相当于在实例化类的过程中传入参数,实例化对象本身 静态方法,静态字段属于类,动态字段,动态方法输入每一个实例化的对象 类实例化的过程把一些属性,方法封装到一个实例化对象当中 动态字段,动态方法 ...

  5. ActiveMQ 学习第二弹

    经历了昨天的初识 ActiveMQ,正好今天下班有点事耽搁了还没法回家,那就再学习会 ActiveMQ 吧!现在官网的文档没啥好看的了,毕竟是入门学习,太深奥的东西也理解不了.然后看官网上有推荐书籍& ...

  6. iptables实用教程(一):基本概念和原理

    概述 iptables是linux自带的防火墙软件,用于配置IPv4数据包过滤或NAT(IPv6用ip6tables). 在linux上,防火墙其实是系统内核的一部分,基于Netfilter构架,基本 ...

  7. GCTF2017部分write up

    Misc stage1 拿到题看到是一张图片隐写 用神器Stegsolve看看发现左上角藏着一张二维码 截下来,不能直接扫,需要反色处理一下 扫出来是一串十六进制 看头几个十六进制数发现是pyc文件 ...

  8. java中计算两个时间差

    java计算时间差及比较时间大小 比如:现在是2004-03-26 13:31:40 过去是:2004-01-02 11:30:24 我现在要获得两个日期差,差的形式为:XX天XX小时XX分XX秒 方 ...

  9. C/C++输入两个任意日期求相隔天数

    将两个日期转换成与一个指定日期(例1970-01-01)之间的差然后计算 思路: 两个日期相隔天数的计算,首先可以将两个日期转换成time_t(从指定日期至1970年1月1日0时0分0秒相隔的秒数), ...

  10. 获取当前 系统时间 + 获取当前URL 键值;

    一://系统当前时间 function show(){ var mydate = new Date(); var str = "" + mydate.getFullYear() + ...