javaweb中Filter(过滤器)的常见应用

作者:孤傲苍狼 时间:2023-07-10 23:57:36 

一、统一全站字符编码

通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题


package me.gacl.web.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.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

/**
* @ClassName: CharacterEncodingFilter
* @Description: 此过滤器用来解决全站中文乱码问题
*/
public class CharacterEncodingFilter implements Filter {

private FilterConfig filterConfig = null;
 //设置默认的字符编码
 private String defaultCharset = "UTF-8";

public void doFilter(ServletRequest req, ServletResponse resp,
     FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;
   HttpServletResponse response = (HttpServletResponse) resp;
   String charset = filterConfig.getInitParameter("charset");
   if(charset==null){
     charset = defaultCharset;
   }
   request.setCharacterEncoding(charset);
   response.setCharacterEncoding(charset);
   response.setContentType("text/html;charset="+charset);

MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(request);
   chain.doFilter(requestWrapper, response);
 }

public void init(FilterConfig filterConfig) throws ServletException {
   //得到过滤器的初始化配置信息
   this.filterConfig = filterConfig;
 }

public void destroy() {

}
}

/*
1.实现与被增强对象相同的接口
2、定义一个变量记住被增强对象
3、定义一个构造器,接收被增强对象
4、覆盖需要增强的方法
5、对于不想增强的方法,直接调用被增强对象(目标对象)的方法
*/

class MyCharacterEncodingRequest extends HttpServletRequestWrapper{

private HttpServletRequest request;
 public MyCharacterEncodingRequest(HttpServletRequest request) {
   super(request);
   this.request = request;
 }
 /* 重写getParameter方法
  * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String)
  */
 @Override
 public String getParameter(String name) {

try{
     //获取参数的值
     String value= this.request.getParameter(name);
     if(value==null){
       return null;
     }
     //如果不是以get方式提交数据的,就直接返回获取到的值
     if(!this.request.getMethod().equalsIgnoreCase("get")) {
       return value;
     }else{
       //如果是以get方式提交数据的,就对获取到的值进行转码处理
       value = new String(value.getBytes("ISO8859-1"),this.request.getCharacterEncoding());
       return value;
     }
   }catch (Exception e) {
     throw new RuntimeException(e);
   }
 }
}

web.xml文件中的配置如下:


<filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>me.gacl.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>charset</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

二、禁止浏览器缓存所有动态页面
有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秒。


package me.gacl.web.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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @ClassName: NoCacheFilter
* @Description: 禁止浏览器缓存所有动态页面
* @author: 孤傲苍狼
* @date: 2014-8-31 下午11:25:40
*
*/
public class NoCacheFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse resp,
     FilterChain chain) throws IOException, ServletException {
   //把ServletRequest强转成HttpServletRequest
   HttpServletRequest request = (HttpServletRequest) req;
   //把ServletResponse强转成HttpServletResponse
   HttpServletResponse response = (HttpServletResponse) resp;
   //禁止浏览器缓存所有动态页面
   response.setDateHeader("Expires", -1);
   response.setHeader("Cache-Control", "no-cache");
   response.setHeader("Pragma", "no-cache");

chain.doFilter(request, response);
 }

public void init(FilterConfig filterConfig) throws ServletException {

}

public void destroy() {

}
}

web.xml文件中的配置如下:


<filter>
  <filter-name>NoCacheFilter</filter-name>
  <filter-class>me.gacl.web.filter.NoCacheFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>NoCacheFilter</filter-name>
   <!--只拦截Jsp请求-->
  <servlet-name>*.jsp</servlet-name>
</filter-mapping>

三、控制浏览器缓存页面中的静态资源

有些动态页面中引用了一些图片或css文件以修饰页面效果,这些图片和css文件经常是不变化的,所以为减轻服务器的压力,可以使用filter控制浏览器缓存这些文件,以提升服务器的性能。


package me.gacl.web.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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @ClassName: CacheFilter
* @Description: 控制缓存的filter
*/
public class CacheFilter implements Filter {

private FilterConfig filterConfig;

public void doFilter(ServletRequest req, ServletResponse resp,
     FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;
   HttpServletResponse response = (HttpServletResponse) resp;

//1.获取用户想访问的资源
   String uri = request.getRequestURI();

//2.得到用户想访问的资源的后缀名
   String ext = uri.substring(uri.lastIndexOf(".")+1);

//得到资源需要缓存的时间
   String time = filterConfig.getInitParameter(ext);
   if(time!=null){
     long t = Long.parseLong(time)*3600*1000;
     //设置缓存
     response.setDateHeader("expires", System.currentTimeMillis() + t);
   }

chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {
   this.filterConfig = filterConfig;
 }

public void destroy() {

}
}

web.xml文件中的配置如下:


<!-- 配置缓存过滤器 -->
 <filter>
  <filter-name>CacheFilter</filter-name>
  <filter-class>me.gacl.web.filter.CacheFilter</filter-class>
   <!-- 配置要缓存的web资源以及缓存时间,以小时为单位 -->
  <init-param>
    <param-name>css</param-name>
    <param-value>4</param-value>
  </init-param>
  <init-param>
    <param-name>jpg</param-name>
    <param-value>1</param-value>
  </init-param>
  <init-param>
    <param-name>js</param-name>
    <param-value>4</param-value>
  </init-param>
  <init-param>
    <param-name>png</param-name>
    <param-value>4</param-value>
  </init-param>
</filter>
<!-- 配置要缓存的web资源的后缀-->
<filter-mapping>
  <filter-name>CacheFilter</filter-name>
  <url-pattern>*.jpg</url-pattern>
</filter-mapping>

<filter-mapping>
  <filter-name>CacheFilter</filter-name>
  <url-pattern>*.css</url-pattern>
</filter-mapping>

<filter-mapping>
  <filter-name>CacheFilter</filter-name>
  <url-pattern>*.js</url-pattern>
</filter-mapping>
 <filter-mapping>
  <filter-name>CacheFilter</filter-name>
  <url-pattern>*.png</url-pattern>
</filter-mapping>

四、实现用户自动登陆

思路是这样的:

1、在用户登陆成功后,发送一个名称为user的cookie给客户端,cookie的值为用户名和md5加密后的密码。
2、编写一个AutoLoginFilter,这个filter检查用户是否带有名称为user的cookie来,如果有,则调用dao查询cookie的用户名和密码是否和数据库匹配,匹配则向session中存入user对象(即用户登陆标记),以实现程序完成自动登陆。

核心代码如下:

处理用户登录的控制器:LoginServlet


package me.gacl.web.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.gacl.dao.UserDao;
import me.gacl.domain.User;
import me.gacl.util.WebUtils;

public class LoginServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {

String username = request.getParameter("username");
   String password = request.getParameter("password");

UserDao dao = new UserDao();
   User user = dao.find(username, password);
   if(user==null){
     request.setAttribute("message", "用户名或密码不对!!");
     request.getRequestDispatcher("/message.jsp").forward(request, response);
     return;
   }
   request.getSession().setAttribute("user", user);
   //发送自动登陆cookie给客户端浏览器进行存储
   sendAutoLoginCookie(request,response,user);
   request.getRequestDispatcher("/index.jsp").forward(request, response);
 }

/**
 * @Method: sendAutoLoginCookie
 * @Description: 发送自动登录cookie给客户端浏览器
 * @param request
 * @param response
 * @param user
 */
 private void sendAutoLoginCookie(HttpServletRequest request, HttpServletResponse response, User user) {
   if (request.getParameter("logintime")!=null) {
     int logintime = Integer.parseInt(request.getParameter("logintime"));
     //创建cookie,cookie的名字是autologin,值是用户登录的用户名和密码,用户名和密码之间使用.进行分割,密码经过md5加密处理
     Cookie cookie = new Cookie("autologin",user.getUsername() + "." + WebUtils.md5(user.getPassword()));
     //设置cookie的有效期
     cookie.setMaxAge(logintime);
     //设置cookie的有效路径
     cookie.setPath(request.getContextPath());
     //将cookie写入到客户端浏览器
     response.addCookie(cookie);
   }
 }

public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {

doGet(request, response);
 }

}

处理用户自动登录的过滤器:AutoLoginFilter


package me.gacl.web.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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.gacl.dao.UserDao;
import me.gacl.domain.User;
import me.gacl.util.WebUtils;

public class AutoLoginFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse resp,
     FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;
   HttpServletResponse response = (HttpServletResponse) resp;
   //如果已经登录了,就直接chain.doFilter(request, response)放行
   if(request.getSession().getAttribute("user")!=null){
     chain.doFilter(request, response);
     return;
   }

//1.得到用户带过来的authlogin的cookie
   String value = null;
   Cookie cookies[] = request.getCookies();
   for(int i=0;cookies!=null && i<cookies.length;i++){
     if(cookies[i].getName().equals("autologin")){
       value = cookies[i].getValue();
     }
   }

//2.得到 cookie中的用户名和密码
   if(value!=null){
     String username = value.split("\\.")[0];
     String password = value.split("\\.")[1];

//3.调用dao获取用户对应的密码
     UserDao dao = new UserDao();
     User user = dao.find(username);
     String dbpassword = user.getPassword();

//4.检查用户带过来的md5的密码和数据库中的密码是否匹配,如匹配则自动登陆
     if(password.equals(WebUtils.md5(dbpassword))){
       request.getSession().setAttribute("user", user);
     }
   }

chain.doFilter(request, response);
 }

public void destroy() {

}

public void init(FilterConfig filterConfig) throws ServletException {

}
}

如果想取消自动登录,那么可以在用户注销时删除自动登录cookie,核心代码如下:


package me.gacl.web.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CancelAutoLoginServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   //移除存储在session中的user
   request.getSession().removeAttribute("user");
   //移除自动登录的cookie
   removeAutoLoginCookie(request,response);
   //注销用户后跳转到登录页面
   request.getRequestDispatcher("/login.jsp").forward(request, response);
 }

/**
 * @Method: removeAutoLoginCookie
 * @Description: 删除自动登录cookie,
 * JavaWeb中删除cookie的方式就是新创建一个cookie,新创建的cookie与要删除的cookie同名,
 * 设置新创建的cookie的cookie的有效期设置为0,有效路径与要删除的cookie的有效路径相同
 * @param request
 * @param response
 */
 private void removeAutoLoginCookie(HttpServletRequest request, HttpServletResponse response) {
   //创建一个名字为autologin的cookie
   Cookie cookie = new Cookie("autologin","");
    //将cookie的有效期设置为0,命令浏览器删除该cookie
   cookie.setMaxAge(0);
   //设置要删除的cookie的path
   cookie.setPath(request.getContextPath());
   response.addCookie(cookie);
 }

public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   doGet(request, response);
 }
}

标签:javaweb,Filter,过滤器
0
投稿

猜你喜欢

  • Maven install 报错"程序包不存在"问题的解决方法

    2021-05-27 06:08:06
  • java LockSupport实现原理示例解析

    2023-05-14 06:43:05
  • OpenGL绘制三次Bezier曲线

    2022-04-23 18:18:14
  • Java编程常见内存溢出异常与代码示例

    2021-12-14 14:45:08
  • C++智能指针实例详解

    2021-12-18 00:38:59
  • C#实现顺序表(线性表)完整实例

    2022-06-04 15:42:31
  • 基于C#模拟实现回合制游戏

    2021-08-01 23:09:55
  • JAVA SPI特性及简单应用代码实例

    2021-11-11 14:54:54
  • Java多线程 ReentrantLock互斥锁详解

    2022-07-23 21:21:06
  • C#算法之散列表

    2022-07-30 19:05:52
  • Android 谷歌推荐的VR实现方式(分享)

    2022-01-01 10:22:44
  • C#泛型集合类System.Collections.Generic

    2023-02-24 19:21:18
  • C语言算法积累加tag的循环队列

    2022-09-21 16:05:30
  • android 横竖屏限制的配置方法

    2023-02-06 21:55:45
  • Java JVM运行时数据区(Run-Time Data Areas)

    2022-01-22 22:10:35
  • Springmvc Controller接口代码示例

    2023-11-28 10:13:25
  • Java实现简单员工管理系统

    2021-12-13 17:51:26
  • Android 自定义来电秀实现总结

    2023-12-17 07:52:32
  • C#实现redis读写的方法

    2023-07-13 16:21:35
  • 老生常谈 Java中的继承(必看)

    2023-06-21 11:59:51
  • asp之家 软件编程 m.aspxhome.com