项目上有个小需求,要限制访问者的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. 侯捷STL学习(一)

    开始跟着<STL源码剖析>的作者侯捷真人视频,学习STL,了解STL背后的真实故事! 视频链接:侯捷STL 还有很大其他视频需要的留言 第一节:STL版本和重要资源 STL和标准库的区别 ...

  2. 几个常用的linux快捷键和shell知识

    1)   !$    !$是一个特殊的环境变量,它代表了上一个命令的最后一个字符串.如:你可能会这样:     $mkdir mydir     $mv mydir yourdir     $cd y ...

  3. sparklyr包:实现Spark与R的接口

    日前,Rstudio公司发布了sparklyr包.该包具有以下几个功能: 实现R与Spark的连接—sparklyr包提供了一个完整的dplyr后端 筛选并聚合Spark数据集,接着在R中实现分析与可 ...

  4. Java 命令后台运行jar包

    nohup  java -jar XX.jar >temp.text & nohup 客户端关闭,后台继续运行 & 客户端关闭,后台停止运行 temp.text 是存控制台文件 ...

  5. 傻瓜式安装nginx以及负载均衡配置

    概述 需求 做了一个对内的http api应用.由于只有一台服务器,考虑到升级问题(即升级时会造成几秒钟用户访问不了),决定搭一个nginx,公共端口:9999,部署2套应用,端口:9981,9982 ...

  6. 对yield 的理解

    最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结. yield 是一个类似于 return的语法,但是对于ret ...

  7. RSA加密算法

    class Program { static void Main(string[] args) { RSAPublicKey P = new RSAPublicKey(); P.Exponent = ...

  8. nginx反向代理cas-server之2:生成证书,centOS下使用openssl生成CA证书(根证书、server证书、client证书)

    前些天搭好了cas系统,这几天一致再搞nginx和cas的反向代理,一直不成功,但是走http还是测试通过的,最终确定是ssl认证证书这一块的问题,原本我在cas服务端里的tomcat已经配置了证书, ...

  9. 安装Mysql5.7并修改初始密码

    Centos 安装MySQL可以参考之前写的一篇文章 Centos7.3 安装Mysql5.7并修改初始密码 windows安装mysql5.7有两种方式 1.下载.msi安装文件直接根据界面提示进行 ...

  10. 初识webpack——webpack四个基础概念

    前面的话 webpack是当下最热门的前端资源模块化管理和打包工具.它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源.当webpack处理应用程序时,它会递归地构建一个依赖关系图表 ...