项目上有个小需求,要限制访问者的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. Java反射机制剖析(三)-简单谈谈动态代理

    通过Java反射机制剖析(一)和Java反射机制剖析(二)的学习,已经对反射有了一定的了解,这一篇通过动态代理的例子来进一步学习反射机制. 1.     代理模式 代理模式就是为其他对象提供一种代理来 ...

  2. 【持续集成】GIT+jenkins+snoar——jenkins发布php、maven项目

    一.持续集成 1.1 什么是持续集成? continuous integration (CI),持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员,每天至少集成一次,也就意味着 ...

  3. Git添加远程库和从远程库中获取(新手傻瓜式教学)

    一.    Git添加远程库 1.在本地新建一个文件夹,在该文件夹使用Git工具,运行$ git init,将该文件夹变为本地Git仓库,同时会生成一个隐藏的.git文件夹. 2.在该文件夹中用Not ...

  4. Django学习报错记录

    1. 运行manage.py任务  makemigrations时,报错: doesn't declare an explicit app_label and isn't in an applicat ...

  5. Linux盘符绑定槽位

    服务器下的硬盘主有机械硬盘.固态硬盘以及raid阵列,通常内核分配盘符的顺序是/dev/sda./dev/sdb- -.在系统启动过程中,内核会按照扫描到硬盘的顺序分配盘符(先分配直通的,再分配阵列) ...

  6. iOS开发之 Lottie -- 炫酷的动效

    动效在软件开发中非常常见,炫酷的动画能提升应用的B格,然而由设计师的设计转化成程序猿GG的代码是个非常"痛苦"的过程.对于复杂动画,可能要花费很多时间去研究和实现.Lottie 的 ...

  7. [oracle]Oracle数据库安全管理

    目录 +  1.数据库安全控制策略概述 +  2.用户管理 +  3.资源限制与口令管理 +  4.权限管理 +  5.角色管理 +  6.审计 1.数据库安全控制策略概述 安全性是评估一个数据库的重 ...

  8. crontab表达式执行时间计算,crontab在线测试

    熟悉Unix和Linux的朋友都知道Crontab表达式,通过crontab指令可以周期性调用或执行某个程序.   但是大家写完crontab表达式后,心里总是担心表达式写的不对,可以又没法去验证.比 ...

  9. “织梦”CMS注入高危漏洞情况

    "织梦"CMS注入高危漏洞情况 作者:    时间:2014-04-17   "织梦"CMS是由上海卓卓网络科技有限公司研发的一款网站建站系统软件,又称&quo ...

  10. nodeJS之TCP模块net

    前面的话 TCP服务在网络应用中十分常见,目前大多数的应用都是基于TCP搭建而成的.net模块提供了一个异步网络包装器,用于TCP网络编程,它包含了创建服务器和客户端的方法.本文将详细介绍nodeJS ...