过滤器
过滤器相当于就是一个屏障,可以设置使所有请求都必须经过过滤器,然后才能访问资源。
客户端→(←)过滤器→(←)被请求资源,不管是请求还是响应都必须经过过滤器,过滤器可以有无数个,只要有一个不让通过的话,那就通过不了。
一:如何写过滤器?
(1)在com.kaishengit.web下建一个子包叫com.kaishengit.web.filter(这个是习惯性的,可选的)
(2)写一个类,让该类实现javax.servlet.Filter接口
package com.kaishengit.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;
public class New implements Filter{
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
所有的过滤器都得实现Filter方法,所以得实现方法里面的destroy()方法,init()方法,和doFilter()方法,但因为destroy()和init()一般比较少用,为了避免在每个过滤器中都实现这两个方法,可以写一个抽象类如AbstractFilter先实现Filter接口,然后让所有的过滤器都继承自这个抽象方法,这样在过滤器中只需要重写doFilter()方法即可,减少了代码量,这种设计模式叫做适配器模式。
(3)在配置文件web.xml中配置Filter,如:
<!--/*表示所有的文件都得经过过滤器,若是/.jspx,则只有 servlet文件需要经过过滤器-->
<filter>
<filter-name>LoginValidateFilter</filter-name>
<filter-class>com.kaishengit.web.filter.LoginValidateFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginValidateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(4)容器启动时会初始化过滤器,此时构造方法和init()会被调用
二:过滤器的使用场景
(1)表单输入的中文转码问题处理
package com.kaishengit.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncodingFilter extends AbstractFilter{
//设置默认的字符集,避免用户忘了配置Filter文件设置字符集导致出现乱码
private String encoding = "UTF-8";
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
chain.doFilter(request,response);
}
//从配置文件中取值,因为init()方法在服务器启动时就会调用,所以如果里面有值的话就将配置的字符集作为字符集,如果没有的话就使用默认的
public void init(FilterConfig filterConfig) throws ServletException{
String value = filterConfig.getInitParameter("encoding");
if(value != null && !"".equals(value)){
encoding = value;
}
}
}
注:在配置文件中是这样配置的,这样是键为encoding,值为UTF-8,这样设置的原因是不把字符集写死,避免有些地区需要改的时候没法改。
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.kaishengit.web.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
(2)登陆验证
package com.kaishengit.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.kaishengit.entity.User;
public class LoginValidateFilter extends AbstractFilter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
//将父类ServletRequest强制转换为子类HttpServletRequest,后面需要用到子类对象的属性
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//uri指的是所请求的相对路径,而url指的是绝对路径,queryString指的是最后面的参数,
例:http://localhost/prod/prod.jspx?m=add,其中:http://localhost/prod/prod.jspx (绝对路径);
/prod/prod.jspx(相对路径);m=add(后面的参数)
String uri = request.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/")+1);
String end = uri.substring(uri.lastIndexOf(".")+1);
System.out.println("uri:"+uri);
if("".equals(uri) || "index.jsp".equals(uri) || "login.jspx".equals(uri)){
chain.doFilter(request, response); //若请求的是登陆页则直接放行
} else if("js".equals(end) || "css".equals(end) || "html".equals(end) || "png".equals(end)){
chain.doFilter(request, response); //若请求的是以js,css,html,png等格式结尾的直接放行
}else {
HttpSession session = request.getSession();
User user = (User) session.getAttribute("User");
if(user == null){
//若是未登录用户访问,获取用户所想要访问的页面
//因为request.getRequestURL()返回的是一个StringBuffer型,所以要加toString()
String url = request.getRequestURL().toString();
String queryString = request.getQueryString();
if(queryString != null){
url = url + "?" + queryString;
}
session.setAttribute("where", url);
response.sendRedirect("login.jspx?code=10001");
} else {
//如果是已登录的用户,则直接放行
chain.doFilter(request, response);
}
}
}
}