项目上有个小需求,要限制访问者的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. 利用JavaScript数组动态写入HTML数据节点

    如果想要使用数组来写入HTML数据,绝对需要的是一个Key值,由Key来引导遍历数组各项:此外,使用DOM原生方法写入文档,用同一个CSS样式渲染它们,这样可以极大地减少开发时间和减少维护成本,此方法 ...

  2. Linux Set Command

    1. set -e "Exit immediately if a simple command exits with a non-zero status." When this o ...

  3. 我必须得告诉大家的MySQL优化原理

    本文转载自http://www.jianshu.com/p/d7665192aaaf 说起MySQL的查询优化,相信大家积累一堆技巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段 ...

  4. iOS crash日志分析

    iOS crash日志分析 一. 寻找crash文件:手机崩溃后的ips或者crash文件(ips文件可以直接修改成crash文件,直接改后缀名就可以了),这里说下如何拿到crash文件 1. 把运行 ...

  5. (高级篇 Netty多协议开发和应用)第十章-Http协议开发应用(基于Netty的HttpServer和HttpClient的简单实现)

    1.HttpServer package nettyHttpTest; import io.netty.bootstrap.ServerBootstrap; import io.netty.chann ...

  6. struts2.1.6教程四_2、ActionContext 、ValueStack 、Stack Context

    ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext.getContext() Va ...

  7. 纯CSS3实现loading正在加载。。。

    场景分析:随着我司专职前端切图人员离职,切图的活重新落到我们小组团队成员的日常任务list里面,加上我们小组 7个前端 基本都是后台转的前端 (赶鸭子上架 前端现在需求量大 没办法) 加上自己也将就一 ...

  8. 【Netty】ChannelHandler和ChannelPipeline

    一.前言 前面学习了Netty的ByteBuf,接着学习ChannelHandler和ChannelPipeline. 二.ChannelHandler和ChannelPipeline 2.1 Cha ...

  9. Promise (2) 基本方法

    "I'm Captain Jack Sparrow" 加勒比海盗5上映,为了表示对杰克船长的喜爱,昨天闪现了几次模仿船长的走路姿势(哈哈哈,简直妖娆). 为了周天能去看电影,要赶紧 ...

  10. 【Windows 10 应用开发】如何防止应用程序被截屏

    今天老周只想跟大伙们分享一个小技巧,是的,小小的技巧,很简单,保证你能学会的,要是学不会,可以考虑跳泰山. 有些时候,我们可能会想到不要让应用程序界面上显示的内容被截屏,要阻止应用界面呈现在截图上,可 ...