java之过滤器Filter (应用场景)
filter在开发中的常见应用:
* 1.filter可以目标资源执行之前,进行权限检查,检查用户有无权限,如有权限则放行,如没有,则拒绝访问
* 2.filter可以放行之前,对request和response进行预处理,从而实现一些全局性的设置。
* 3.filter在放行之后,可以捕获到目标资源的输出,从而对输出作出类似于压缩这样的设置
一、解决全网站的乱码:
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp; request.setCharacterEncoding("UTF-8"); //这个编码只能解决Post提交,不能解决get方式的提交,所以需要对request中getParameter
//方法增强
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8"); chain.doFilter(new MyRequest(request), response); //request.getparameter("password");
} /*
1.写一个类,实现与被增强对象相同的接口
2.定义一个变量,记住被增强对象
3.定义一个构造方法,接收被增强对象
4.覆盖想增强的方法
5.对于不想增强的方法,直接调用被增强对象(目标对象)的方法
*/ class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) { String value = this.request.getParameter(name);
if(!request.getMethod().equalsIgnoreCase("get")){
return value;
} if(value==null){
return null;
} try {
return value = new String(value.getBytes("iso8859-1"),request.getCharacterEncoding());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} } }
二,实现自动登录
实现用户自动登陆的过滤器
在用户登陆成功后,发送一个名称为user的cookie给客户端,cookie的值为用户名和md5加密后的密码。编写一个AutoLoginFilter,这个filter检查用户是否带有名称为user的cookie来,如果有,则调用dao查询cookie的用户名和密码是否和数据库匹配,匹配则向session中存入user对象(即用户登陆标记),以实现程序完成自动登陆。
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp; //1.先检查用户是否已登陆,没登陆才自动登陆
User user = (User) request.getSession().getAttribute("user"); if(user!=null){
chain.doFilter(request, response);
return;
} //2.没登陆,再执行自动登陆逻辑 //看用户有没有带自动登陆的cookie
Cookie autoLoginCookie = null;
Cookie cookies[] = request.getCookies(); for(int i=0;cookies!=null && i<cookies.length;i++){
if(cookies[i].getName().equals("autologin")){
autoLoginCookie = cookies[i];
}
}
if(autoLoginCookie==null){
chain.doFilter(request, response);
return;
} //用户带了自动登陆的cookie,则先检查cookie的有效期
String values[] = autoLoginCookie.getValue().split("\\:");
if(values.length!=3){
chain.doFilter(request, response);
return;
}
long expirestime = Long.parseLong(values[1]);
if(System.currentTimeMillis()>expirestime){
chain.doFilter(request, response);
return;
} //代表cookie时间有效,再检查cookie的有效性
String username = values[0];
String client_md5 = values[2]; BusinessService service = new BusinessService();
user = service.findUser(username);
if(user==null){
chain.doFilter(request, response);
return;
}
////autologin=username:expirestime:md5(password:expirestime:username)
String server_md5 = md5(user.getUsername(),user.getPassword(),expirestime);
if(!server_md5.equals(client_md5)){
chain.doFilter(request, response);
return;
} //执行登陆
request.getSession().setAttribute("user", user);
chain.doFilter(request, response); } private String md5(String username,String password,long expirestime){ try{
String value = password + ":" + expirestime + ":" + username;
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(value.getBytes());
BASE64Encoder encode = new BASE64Encoder();
return encode.encode(md5);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String username = request.getParameter("username");
String password = request.getParameter("password"); BusinessService service = new BusinessService();
User user = service.login(username, password);
if(user==null){
request.setAttribute("message", "用户名或密码错误!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
} request.getSession().setAttribute("user", user);
int expirestime = Integer.parseInt(request.getParameter("time"));
//给客户机发送自动登陆的 cookie
//autologin=username:expirestime:md5(password:expirestime:username)
Cookie cookie = makeCookie(user, expirestime);
response.addCookie(cookie);
response.sendRedirect("/login/index.jsp");
} public Cookie makeCookie(User user,int expirestime){
long currenttime = System.currentTimeMillis();
String cookieValue = user.getUsername() + ":" + (currenttime+expirestime*1000) + ":" + md5(user.getUsername(), user.getPassword(), (currenttime+expirestime*1000));
Cookie cookie = new Cookie("autologin",cookieValue);
cookie.setMaxAge(expirestime);
cookie.setPath("/login");
return cookie;
} private String md5(String username,String password,long expirestime){ try{
String value = password + ":" + expirestime + ":" + username;
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(value.getBytes());
BASE64Encoder encode = new BASE64Encoder();
return encode.encode(md5);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
三,禁止浏览器缓存所有动态页面的过滤器:
有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下:
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头。
Expires数据头:值为GMT时间值,为-1指浏览器不要缓存页面
Cache-Control响应头有两个常用值:
no-cache指浏览器不要缓存当前页面。
max-age:xxx指浏览器缓存页面xxx秒。
四,控制浏览器缓存页面中的静态资源的过滤器:
有些动态页面中引用了一些图片或css文件以修饰页面效果,这些图片和css文件经常是不变化的,所以为减轻服务器的压力,可以使用filter控制浏览器缓存这些文件,以提升服务器的性能。
private Map<String,byte[]> map = new HashMap(); public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp; //1.得到用户想访问的资源(uri)
String uri = request.getRequestURI(); //2.看map集合中是否保存了该资源的数据
byte b[] = map.get(uri); //3.如果保存了,则直接取数据打给浏览器
if(b!=null){
response.getOutputStream().write(b);
return;
} //4.如果没有保存数据,则放行让目标资源执行,这时还需写一个response的包装类,捕获目标资源的输出
MyResponse my = new MyResponse(response);
chain.doFilter(request, my);
byte data[] = my.getBuffer(); //5.以资源uri为关键字,打资源的数据保存map集合中,以备于下次访问
map.put(uri, data); //6.输出数据给浏览器
response.getOutputStream().write(data); } class MyResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream bout = new ByteArrayOutputStream();
private PrintWriter pw; private HttpServletResponse response;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyServletOutputStream(bout); //myresponse.getOutputStream().write("hahah");
} @Override
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(bout,response.getCharacterEncoding()));
return pw;
}
public byte[] getBuffer(){
if(pw!=null){
pw.close();
}
return bout.toByteArray();
}
} class MyServletOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bout;
public MyServletOutputStream(ByteArrayOutputStream bout){
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b);
} }
五、使用Decorator模式包装request对象,实现html标签转义功能(Tomcat服务器中提供了转义html标签的工具类)
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp; chain.doFilter(new MyRequest(request), response); //request.getParameter("resume"); //<script> } class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) { String value = this.request.getParameter(name);
if(value==null){
return null;
}
return filter(value);
} public String filter(String message) { if (message == null)
return (null); char content[] = new char[message.length()];
message.getChars(0, message.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '&':
result.append("&");
break;
case '"':
result.append(""");
break;
default:
result.append(content[i]);
}
}
return (result.toString()); }
}
六、压缩响应信息
服务器发给浏览器的数据时,先进行压缩,然后在发出,(注意filter要拦截的对象,都会压缩,所以要在web.xml中配置好想要拦截的对象)。
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
MyResponse myresponse = new MyResponse(response); chain.doFilter(request, myresponse); //response.getwriter response.getOutputStream //取出缓冲的数据压缩后输出
byte out[] = myresponse.getBuffer(); //得到目标资源的输出
byte gzipout[] = gzip(out);
response.setHeader("content-encoding", "gzip");
response.setHeader("content-length", gzipout.length + "");
response.getOutputStream().write(gzipout);
} public byte[] gzip(byte b[]) throws IOException{ ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(bout);
gout.write(b);
gout.close();
return bout.toByteArray();
} class MyResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream bout = new ByteArrayOutputStream();
private PrintWriter pw; private HttpServletResponse response;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyServletOutputStream(bout); //myresponse.getOutputStream().write("hahah");
} @Override
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(bout,response.getCharacterEncoding()));
return pw;
}
public byte[] getBuffer(){
if(pw!=null){
pw.close();
}
return bout.toByteArray();
}
} class MyServletOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bout;
public MyServletOutputStream(ByteArrayOutputStream bout){
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b);
} }
七、敏感词过滤(z注意词库中词语的格式:例如:傻逼|1 后面的1表示识别词库中的等级 ,禁用词为1,审查词为2,替换词为3)
private List<String> banWords = new ArrayList();//禁用词,例如:傻逼|1
private List<String> auditWords = new ArrayList();//审查词 例如: 中共|2
private List<String> replaceWords = new ArrayList();//替换词 例如: 色情|3 public void init(FilterConfig filterConfig) throws ServletException {
try{
String path = WordsFilter.class.getClassLoader().getResource("cn/xxx/xxx").getPath();//地址表词库存放在那个包下面
File files[] = new File(path).listFiles();
for(File file : files){
if(!file.getName().endsWith(".txt")){//表示词库的后缀名文件
continue;
}
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while((line=br.readLine())!=null){
String s[] = line.split("\\|");
if(s.length!=2){
continue;
}
if(s[1].trim().equals("1")){
banWords.add(s[0].trim());
} if(s[1].trim().equals("2")){
auditWords.add(s[0].trim());
} if(s[1].trim().equals("3")){
replaceWords.add(s[0].trim());
}
}
}
System.out.println("haha");
}catch (Exception e) {
throw new RuntimeException(e);
} } public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp; //检查提交数据是否包含禁用词
Enumeration e = request.getParameterNames();
while(e.hasMoreElements()){
String name = (String) e.nextElement();
String data = request.getParameter(name);
for(String regex : banWords){
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(data);
if(m.find()){
request.setAttribute("message", "文章中包括非法词汇,请检查后再提交!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
}
} //检查审核词 //检查替换词
chain.doFilter(new MyRequest(request), response); } class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) { String data = this.request.getParameter(name);
if(data==null){
return null;
}
for(String regex : auditWords){//检查审核词
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(data);
if(m.find()){
String value = m.group(); //找出客户机提交的数据中和正则表达式相匹配的数据
data = data.replaceAll(regex, "<font color='red'>" + value + "</font>");
}
} for(String regex : replaceWords){//检查替换词
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(data);
if(m.find()){
data = data.replaceAll(regex, "*******");
}
} return data;
}
}
java之过滤器Filter (应用场景)的更多相关文章
- java之过滤器Filter
Java三大器之过滤器(Filter)的工作原理和代码演示 一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对w ...
- java Web 过滤器Filter详解
简介 Filter也称之为过滤器,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊 ...
- java中过滤器Filter的使用总结【转载】
1.看了别人写的,觉得获益匪浅,转载下为以后的使用 java中Filter的使用
- Java 中的 Filter 过滤器详解
Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件 ...
- java Servlet中的过滤器Filter
web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...
- Java中的Filter过滤器
Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件 ...
- Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java基础95 过滤器 Filter
1.filter 过滤器的概述 filter过滤器:是面向切面编程的一种实现策略,在不影响原来的程序流程的前提下,将一些业务逻辑切入流程中,在请求达到目标之前进行处理,一般用于编码过滤.权限过滤... ...
- java过滤器Filter笔记
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet, 静 ...
随机推荐
- Java与算法之(10) - 希尔排序
希尔排序是插入排序的一种,是直接插入排序的改进版本. 对于上节介绍的直接插入排序法,如果数据原来就已经按要求的顺序排列,则在排序过程中不需要进行数据移动操作,即可得到有序数列.但是,如果最初的数据是按 ...
- HTML/CSS/JavaScript学习笔记【持续更新】
HTML <font> 标签 定义和用法 <font> 规定文本的字体.字体尺寸.字体颜色. 实例 规定文本字体.大小和颜色: <font size="3&qu ...
- AtCoder Grand Contest 016
在雅礼和衡水的dalao们打了一场atcoder 然而窝好菜啊…… A - Shrinking 题意:定义一次操作为将长度为n的字符串变成长度n-1的字符串,且变化后第i个字母为变化前第i 或 i+1 ...
- js取整并保留两位小数的方法
js 四舍五入函数 toFixed(),里面的参数 就是保留小数的位数.注意 toFixed()方法只针对数字类型,如果是字符类型需要使用Number()等方法先转换数字类型再使用 document. ...
- [国嵌笔记][021-022][ARM处理器工作模式]
[ARM处理器工作模式] 处理器工作模式 1.User(urs):用户模式,linux应用程序运行在用户模式 2.FIQ(fiq):快速中断模式 3.IRQ(irq):中断模式 4.Superviso ...
- js获取不带单位的像素值
所谓获取不带单位的像素值就是获取比如元素的宽度.高度.字体大小.外边距.内边距等值但是去掉像素单位. 比如:某一个元素的宽度是100px,现在我要获取这个这个值但是不带单位“px”,对于这种问题你会怎 ...
- SQL语句order by两个字段同时排序。
ORDER BY 后可加2个字段,用英文逗号隔开.理解:对两个字段都排序,并不是之排序其中的一个字段: f1用升序, f2降序,sql该这样写 ORDERBY f1, f2 DESC 也可以这样 ...
- 在js中怎样获得checkbox里选中的多个值?
https://zhidao.baidu.com/question/203897221.html 思路:利用name属性值获取checkbox对象,然后循环判断checked属性(true表示被选中, ...
- 获取select中的值
分别使用javascript原生的方法和jquery方法<select id="test" name=""> <option value=&q ...
- ecshop_标签大全
admin 后台功能 -------templates后台模板 data 上传文件.SQL备份文件.配置项 ------sqldata 数据库备份文件 ------config.php配置文件 inc ...