过滤器 Filter 应用场景 统一编码处理、登录验证
init: 初始化方法 destroy: 销毁方法
* doFilter: 方法拦截。 FilterChain他是一个接口 。 FilterConfig对象来获取
拦截所有资源的配置是: /*
* @param request 请求对象 response 响应对象 chain 过滤器链对象
* @throws IOException ServletException
package com.itheima.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
* 解决中文乱码的过滤器 配置过滤器的注解: @WebFilter
@WebFilter(urlPatterns = "/*", //配置拦截的规则
dispatcherTypes = DispatcherType.REQUEST,//配置拦截行为
initParams = @WebInitParam(name = "encoding",value = "UTF-8")//配置初始化参数
)
public class CharacterEncodingFilter implements Filter {
private FilterConfig filterConfig;
//初始化方法 filterConfig ServletException
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//使用过滤器的配置对象读取初始化参数
String encoding = filterConfig.getInitParameter("encoding");
//1.设置请求对象的字符集
request.setCharacterEncoding(encoding);
//2.设置响应对象的正文类型和字符集
response.setContentType("text/html;charset="+encoding);
//3.放行
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
* 在Filter中的url-pattern支持下面的匹配方式:
1. 精确匹配:直接匹配到某个资源上
2. 路径匹配:匹配某个目录,要求以/开头,以`*`结尾
3. 后缀匹配:根据后缀匹配,要求以`*.`开头
* 登录的Servlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final String RIGHT_USERNAME = "泰斯特";
private static final String RIGHT_PASSWORD = "1234";
/**
* 登录操作 * @param req resp ServletException IOException
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.解决乱码问题
//req.setCharacterEncoding("UTF-8");
//resp.setContentType("text/html;charset=UTF-8");
//2.获取请求参数,用户名,密码和验证码
String username = req.getParameter("username");
String password = req.getParameter("password");
String formCode = req.getParameter("code");
//3.取出会话共享区域中存放的验证码
HttpSession session = req.getSession();
String sessionCode = (String)session.getAttribute("sessionCode");
//4.判断验证码是否匹配
if(!formCode.equals(sessionCode)){
//把错误信息存入共享区域,并且跳转回登录页面
req.setAttribute("errorMsg","验证码不匹配,请检查后重新输入");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
return;
}
//5.用户名和密码的判断
if(!RIGHT_USERNAME.equals(username)){
//把错误信息存入共享区域,并且跳转回登录页面
req.setAttribute("errorMsg","用户名或者密码不匹配,请检查后重新输入");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
return;
}
if(!RIGHT_PASSWORD.equals(password)){
//把错误信息存入共享区域,并且跳转回登录页面
req.setAttribute("errorMsg","用户名或者密码不匹配,请检查后重新输入");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
return;
}
//6.当代码走到此处,就表示验证码,用户名和密码都校验通过了,那么此时就应该是登录成功
//当登录成功之后,我们应该删除验证码
session.removeAttribute("sessionCode");
//把登录成功的信息存入了
session.setAttribute("loginSuccessName",username);
resp.sendRedirect(req.getContextPath()+"/index.jsp");
}
}
* 用于生成验证码的Servlet
@WebServlet("/captcha")
public class CaptchaServlet extends HttpServlet {
* 生成验证码 req resp ServletException
* @throws IOException
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.创建生成验证码的对象
LineCaptcha lineCaptcha = new LineCaptcha(200,30,4,10);
//2.取出生成验证码
String code = lineCaptcha.getCode();
//3.把取到的验证码存入会话共享区域
HttpSession session = req.getSession();
session.setAttribute("sessionCode",code);
//4.把验证码写到浏览器端
lineCaptcha.write(resp.getOutputStream());
}
}
未登录状态下不能被访问-检查登录的过滤器
@WebFilter("/*")
public class CheckLoginFilter implements Filter {
private FilterConfig filterConfig;
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//把和协议无关的请求和响应对象,转成和协议相关的
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
//判断哪些资源可以不拦截,直接放行 首页面,登录页面,登录操作和获取验证码操作(/captcha)
//再把字符串数组转成list集合
List<String> pathArray = new ArrayList();
pathList.add("/index.jsp");
pathList.add("/");
pathList.add("/login.jsp");
pathList.add("/captcha");
pathList.add("/login");
//获取应用域对象
ServletContext servletContext = filterConfig.getServletContext();
//从应用域中获取不需要拦截的路径
String[] pathArray = (String[])servletContext.getAttribute("pathList");
//取出当前访问的URI
String uri = request.getRequestURI();
System.out.println(uri);
//判断当前的uri是不是和pathList里的一致,一致就直接放行
for(String path : pathArray){
if(uri.equals(path)){
//不需要判断是否已经登录了,那么就直接放行
chain.doFilter(request,response);
//后面的验证不用走了
return;
}
}
//如果不是上面路径列表中的,就需要判断是否已经登录了
HttpSession session = request.getSession();
Object loginSuccessName = session.getAttribute("loginSuccessName");
if(loginSuccessName == null){
//没有登录,让他去登录
response.getWriter().write("游客无权浏览,3秒后前往登录页面");
response.setHeader("Refresh","3;URL=/login.jsp");
return;
}
//如果登录了,就放行
chain.doFilter(request,response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//给filterConfig赋值
this.filterConfig = filterConfig;
}
@Override
public void destroy() {
}
}