一、过滤器Filter简介
filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理。
编写步骤
1)编写一个过滤器的类实现Filter接口
2)实现接口中尚未实现的方法(着重实现doFilter方法)
3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)
API详解
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
1、init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行
2、doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法,注意 这里的request和response没有http 需要强制转换。
3、destory():代表是filter销毁方法 当filter对象销毁时执行该方法
Filter的执行顺序由xml文件中mapping的顺序决定。
Filter对象的生命周期:
Filter何时创建:服务器启动时就创建该filter对象
Filter何时销毁:服务器关闭时filter销毁
filter的过滤过程
filter配置方法 与servlet类似
路径也可以用servlet的名字替代
dispatcher:访问的方式(了解)
REQUEST:默认值,代表直接访问某个资源时执行filter
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转时执行filter
二、总结Filter的作用
1)公共代码的提取
2)可以对request和response中的方法进行增强(装饰者模式/动态代理)
3)进行权限控制
1、自动登陆案例
此时已写好登陆的框架,添加一个自动登陆的复选框。如果登陆成功 则将用户名和密码为客户端写一个cookie,编写一个filter,使得访问所以页面的时候先检测有无cookie,有则尝试登陆。此时filter不是作为筛选,而是作为功能的增强。
web层servlet方法如下
public class ServletLogin extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); //解析中文
//获取 信息
String username = request.getParameter("username");
String password = request.getParameter("password");
String autoLoginin = request.getParameter("autoLogin"); //获得是否自动登陆 勾选为on 不勾选为null
//登陆成功 重定向到首页 失败则转发到本页面显示
user user = null ;
try {
user = new service().Login(username,password);
} catch (SQLException e) {
e.printStackTrace();
}
if(user!=null) //登陆成功 重定向:如果用转发下次请求即丢失登陆信息 同时改变地址栏信息提示用户
{
//判断是否勾选了自动登陆 为客户端写一个cookie 储存用户名和密码
if(autoLoginin.equals("on"))
{
String username_code = URLEncoder.encode(username, "UTF-8");// 如果要往cookie中存入中文信息,先进行编码,获取时再解码
Cookie cusername = new Cookie("cusername", username_code);
Cookie cpassword = new Cookie("cpassword", user.getPassword());
cusername.setMaxAge(60*60);
cpassword.setMaxAge(60*60);
cusername.setPath(request.getContextPath());
cpassword.setPath(request.getContextPath());
response.addCookie(cusername);
response.addCookie(cpassword);
}
HttpSession session = request.getSession(); //存入user信息,以便主页显示其用户名
session.setAttribute("user",user);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
//登陆失败 转发到本页面,并且输出信息
else
{
request.setAttribute("loginInfo", "账号或者密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
filter代码如下
public class AutoLogin implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//自动登陆增强 配置/* 每个资源都先访问这里,如果cookie中有信息则尝试登陆
HttpServletRequest req=(HttpServletRequest)request;
Cookie[] cookies = req.getCookies();
String username = null;
String password = null;
if(cookies!=null)
{
for(Cookie cookie:cookies)
{
if("cusername".equals(cookie.getName()))
{
username=cookie.getValue(); //获取用户名信息,后进行转码
username = URLDecoder.decode(username, "UTF-8");
}
if("cpassword".equals(cookie.getName()))
password=cookie.getValue();
}
}
if(password!=null&&username!=null)
{
//尝试登陆
user user = null ;
try {
user = new service().Login(username,password);
} catch (SQLException e) {
e.printStackTrace();
}
if(user!=null) //登陆成功 写入session 以便后续网站获取显示
{
HttpSession session = req.getSession();
session.setAttribute("user",user);
}
}
//无论登陆是否成功 均进行放行
chain.doFilter(request, response);
}
public void destroy() {
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
servlet中代码句
String username_code = URLEncoder.encode(username, “UTF-8”);
是为了将cookie中写入中文信息,先将中文按utf-8码表编码。而后在filter中代码
username = URLDecoder.decode(username, “UTF-8”);
重新将信息进行解码。
2、修改全局乱码
可以用filter对request进行编码设置,如果方法为post,当然只用简单的一句代码即可解决。当如果提交方法为get,为了每次获取信息都进行编码再解码,编写一个filter使用装饰者模式增强get方法。
其中HttpServletRequestWrapper 为专门用来实现装饰者模式的类,直接覆写其中的方法即可。
public class encoding implements Filter {
class EnhanceRequest extends HttpServletRequestWrapper { //专门用来继承的类,可以只覆写其中几个方法 如果用实现接口,则每个方法都实现
private HttpServletRequest request = null;
public EnhanceRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
@Override //覆写需要的方法
public String getParameter(String name) {
String parameter = request.getParameter(name);
try {
parameter = new String(parameter.getBytes("ISO8859-1"),"UTF-8"); //重新编码再解码 获得中文
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return parameter;
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
EnhanceRequest enhanceRequest = new EnhanceRequest((HttpServletRequest) request);
chain.doFilter(enhanceRequest, response); //传入增强类,则后面所调用的方法都是该增强类的方法
}
public void destroy() {}
public void init(FilterConfig fConfig) throws ServletException {}
}