原标题:JavaWeb之监听器和过滤器
JavaWeb中,监听器是一种组件,能够监听项目的启动和停止,用户会话的创建和销毁,以及各种组件的添加、更新和删除,能够通过监听对象的状态改变,自动做出反应执行响应代码。
应用场景:启动网站后进行初始化、检测用户的数量等。
常用的监听器接口:
ServletContextListener监听项目的启动和停止
方法:
contextInitialized项目加载完成
contextDestroyed项目停止
HttpSessionListener监听用户会话的创建和销毁
sessionCreated每一个用户第一次访问时调用
sessionDestroyed每个用户退出系统后调用
监听器的配置:
方式1 web.xml
listener
listener-class包名+类名/listener-class
/listener
方式2注解
@WebListener
案例:监听网站的启动
/**
*项目的监听器
*@authorchenheng
*
*/
@WebListener
publicclassWebApplicationListenerimplementsServletContextListener{
//项目启动
@Override
publicvoidcontextInitialized(ServletContextEventsce) {
System.out.println(项目启动了!!!!);
//保存一些数据到项目中
sce.getServletContext().setAttribute(money, 999999);
}
//项目停止
@Override
publicvoidcontextDestroyed(ServletContextEventsce) {
System.out.println(项目停止了!!!!!);
}
}
案例:监听网站的用户数
/**
*会话监听器
*@authorchenheng
*
*/
@WebListener
publicclassUserListenerimplementsHttpSessionListener{
//用户会话创建
@Override
publicvoidsessionCreated(HttpSessionEventse) {
//把用户的数量保存到ServletContext(application)中
ServletContextapplication=se.getSession().getServletContext();
//获得用户的总数
Objectcount=application.getAttribute(count);
if(count==null){
//如果是第一个用户,没有总数,添加总数
application.setAttribute(count, 1);
System.out.println(第一个用户);
}else{
//如果不是第一个,就用户数量加1
application.setAttribute(count, (int)count+ 1);
System.out.println(新用户来了);
}
}
//用户会话销毁
@Override
publicvoidsessionDestroyed(HttpSessionEventse) {
ServletContextapplication=se.getSession().getServletContext();
Objectcount=application.getAttribute(count);
if(count!=null(int)count0){
application.setAttribute(count, (int)count- 1);
System.out.println(用户走了);
}
}
}
/**
*关闭Session的Servlet
*/
@WebServlet(/close.do)
publicclassCloseSessionServletextendsHttpServlet{
@Override
protectedvoiddoGet(HttpServletRequestreq, HttpServletResponseresp)throwsServletException, IOException {
//关闭Session
req.getSession().invalidate();
}
}
JSP页面:
%@page language=java contentType=text/html; charset=UTF-8
pageEncoding=UTF-8%
!DOCTYPEhtml PUBLIC-//W3C//DTD HTML 4.01 Transitional//ENhttp://www.w3.org/TR/html4/loose.dtd
html
head
metahttp-equiv=Content-Typecontent=text/html; charset=UTF-8
title测试/title
/head
body
当前网站在线人数:${count}br
ahref=java:location.href='close.do';退出/a
/body
/html
过滤器
能够对网站中的各种内容进行过滤(页面、Servlet、图片、文件),可以在网站内容请求和响应时进行一些操作,完成一些通用的功能。
过滤器链
在项目中可以创建多个过滤器,网站内容可能会经过多个过滤器,多个过滤器就形成了过滤器链。
实现方法:
1、实现Filter接口
init初始化
doFilter进行过滤
参数:
ServletRequest请求
ServletResponse响应
FilterChain过滤器链
//让请求通过,执行下一个过滤器,如果不执行这个方法,请求就被拦截
chain.doFilter(request, response);
destroy销毁
2、配置
web.xml
!--配置过滤器--
filter
filter-nameFilter1/filter-name
filter-classcom.qianfeng.filters.Filter1/filter-class
/filter
filter-mapping
filter-nameFilter1/filter-name
url-pattern/*/url-pattern
/filter-mapping
解释:*代表所有的网站内容都过这个过滤器,可以指定被过滤的内容,如:
url-pattern/test1.jsp/url-pattern
url-pattern/test2.jsp/url-pattern
注解:
@WebFilter({/*})
@WebFilter({/test1.jsp,/test2.jsp})
过滤器执行的顺序:
如果是注解配置的,按名字顺序进行执行
如果是web.xml配置的,按过滤器filter定义的顺序
案例:表单重复提交问题
把表单数据多次提交给服务器
问题:1、加大服务器的负担2、多次插入重复的数据
可能出现重复提交的情况:
1、提交表单后,用forward跳转到其它页面,刷新页面
2、提交表单后,服务器还没有响应前,多次刷新页面
3、提交表单后,服务器还没有响应前,多次点击提交按钮
4、提交表单后,跳转后点击返回,点击提交
解决方法:
1、进入表单页面前,在过滤器中创建Token(令牌)随机字符串,保存到Session中。
2、在表单中添加一个隐藏域,值是Token字符串,会和表单一起提交服务器
3、提交服务器后,将表单中Token和Session中Token进行比较,如果相同就正常提交表单,否则就是重复提交。
4、如果能够成功提交后,把Session中的Token去掉。
/**
*生成令牌的过滤器
*/
@WebFilter({/resubmit.jsp})
publicclassTokenFilterimplementsFilter{
@Override
publicvoiddoFilter(ServletRequestrequest, ServletResponseresponse, FilterChainchain)
throwsIOException, ServletException {
//产生随机字符串
Stringtoken= UUID.randomUUID().toString();
//保存到Session中
HttpServletRequestres= (HttpServletRequest)request;
res.getSession().setAttribute(token,token);
//执行后面的过滤器
chain.doFilter(request,response);
}
@Override
publicvoidinit(FilterConfigfilterConfig)throwsServletException{}
@Override
publicvoiddestroy() {}
}
/**
*模拟添加数据的Servlet
*/
@WebServlet(/add.do)
publicclassAddUserServletextendsHttpServlet{
@Override
protectedvoiddoPost(HttpServletRequestreq, HttpServletResponseresp)throwsServletException, IOException {
//判断表单中的token是否和Session中的token一样
Stringtoken1= (String)req.getSession().getAttribute(token);
Stringtoken2=req.getParameter(token);
if(!token1.equals(token2)){
//如果不相同,就是重复提交
System.out.println(这是重复提交);
return;
}
Stringname=req.getParameter(name);
Stringage=req.getParameter(age);
//模拟代码,成功插入数据库
System.out.println(name+,+age+插入到数据库);
//将Session中的token去掉
req.getSession().setAttribute(token,);
try{
Thread.sleep(1000);
}catch(InterruptedExceptione) {
e.printStackTrace();
}
req.getRequestDispatcher(test.jsp).forward(req,resp);
}
JSP页面:
%@page language=java contentType=text/html; charset=UTF-8
pageEncoding=UTF-8%
!DOCTYPEhtml PUBLIC-//W3C//DTD HTML 4.01 Transitional//ENhttp://www.w3.org/TR/html4/loose.dtd
html
head
metahttp-equiv=Content-Typecontent=text/html; charset=UTF-8
titleInsert title here/title
/head
body
formaction=add.domethod=post
inputtype=textname=nameplacehoder=输入姓名br
inputtype=textname=age placehoder=输入年龄br
inputtype=submitvalue=添加用户
!--将token放到隐藏域中--
inputtype=hiddenname=tokenvalue=${token}
/form
/body
/html
总结本章学习的监听器能够监听项目中各种对象的状态,如项目的启动和停止、用户会话的创建和销毁、会话属性的添加删除等,然后自动调用对应的方法,在实际工作中能完成缓存的提前加载,和项目的相关配置工作。而过滤器能过滤网站中的各种资源,给Servlet和JSP添加一些额外的功能,如:设置编码格式、对用户进行登录验证、解决重复提交问题等。返回搜狐,查看更多
责任编辑: