Servlet进阶API与过滤器与监听器.docx
《Servlet进阶API与过滤器与监听器.docx》由会员分享,可在线阅读,更多相关《Servlet进阶API与过滤器与监听器.docx(31页珍藏版)》请在冰点文库上搜索。
![Servlet进阶API与过滤器与监听器.docx](https://file1.bingdoc.com/fileroot1/2023-5/1/4bd0b08d-0cf3-4cae-b03e-0a71deb2702a/4bd0b08d-0cf3-4cae-b03e-0a71deb2702a1.gif)
Servlet进阶API与过滤器与监听器
Servlet进阶API、过滤器与监听器
1、Servlet进阶API
每个Servlet都必须由web容器读取Servlet设置信息(无论使用标注还是web.xml)、
初始化等,才可以真正成为一个Servlet。
对于每个Servlet的设置信息,web容器会为
其生成一个ServletConfig作为代表对象,你可以从该对象取得Servlet初始参数,以及
代表整个web应用程序的ServletContext对象。
1.Servlet、ServletConfig与GenericServlet
在Servlet接口上,定义了与Servlet生命周期及请求服务相关的init()、service()与
destroy()三个方法。
每一次请求来到容器时,会产生HttpServletResponse与
HttpServletResponse对象,并在调用service()方法时当作参数传入。
在Web容器启动后,会读取Servlet设置信息,将Servlet类加载并实例化,并为每
个Servlet设置信息产生一个Servletconfig对象,而后调用Servlet接口的init()方法
并将发生的ServletConfig对象当作参数传入。
这个过程只会在创建Servlet实例后
发生一次。
ServletConfig即每个Servlet设置的代表对象,容器会为每个Servlet设置信息产生
一个Servlet及ServletConfig实例。
GenericServlet同时实现了Servlet及Servlet-Config。
GenericServlet主要的目的,就
是将初始Servlet调用init()方法传入的ServletConfig封装起来:
privatetransientServletConfigconfig;
publicvoidinit(SetvletConfigconfig)throwsServletException{
this,config=config;
this.init();
}
publicvoidinit()throwsServletException{}
GenericServlet在实现Servlet的init()方法时,也调用了另一个无参数的init()方法,
在编写Servlet时,如果有一些初始时所要运行的动作,可以重新定义这个无参数
的init()方法,而不是直接重新定义有ServletConfig参数的init()方法。
当有一些对象实例化后所要运行的操作,必须定义构造器。
在编写Servlet时,若
想要运行与web应用程序资源相关的初始化动作,则要重新定义init()方法。
GenericServlet也包括了Servlet与ServletConfig所定义方法的简单实现,实现内
容主要是通过ServletConfig来取得一些相关信息。
例:
publicServletConfiggetServletConfig(){
returnconfig;
}
publicStringgetInitParameter(Stringname){
returngetServletConfig().getInitParameter(name);
}
publicEnumerationgetInitParameterNames(){
returngetServletConfig().getInitParameterNames();
}
publicServletContextgetServletContext(){
returngetServletConfig().getServletContext();
}
所以在继承HttpServlet实现Servlet时,就可以通过这些方法来取得所要相关信
息,而不用直接意识到ServletConfig的存在。
GenericServlet还定义了log()方法。
这个方法主要是通过ServletContext的log()
方法来运行日志功能。
不过因为这个日志功能简单,实际上很少使用这个log()
方法,而会使用功能更强大的日志API。
如果是使用Tomcat,ServletContext
的log()方法所保存的日志文件会存放在Tomcat目录的logs目录下。
2.使用ServletConfig
ServletConfig相当于个别Servlet的设置信息代表对象,这意味着可以从ServletConfig
中取得Servlet设置信息。
ServletConfig定义了getInitParameter()、getInitParameterNames()
方法,可以取得设置Servlet时的初始参数。
若要使用标注设置个别Servlet的初始参数,可以在@WebServlet中使用@WebInitParam
设置initParams属性。
例:
......
@WebServlet(name="SevletConfigDemo",urlPatterns={"/conf"},
initParams={
@WebInitParam(name="Param1",value="value1"),...})
publicclassServletConfigDemoextendsHttpServlet{
privateStringParam1;
......
publicvoidinit()throwsServletException{
Param1=getServletConfig().getInitParameter("Param1");
......}
.....}
若要在web.xml中设置个别Servlet的初始参数,可以在标签中使用
等标签进行设置,web.xml中的设置会覆盖标注的设置。
例:
ServletConfigDemo
com.weibo.ServletConfigDemo
Param1
URL
Param2
URL
......
由于ServletConfig必须在Web容器将Servlet实例化后,调用有参数的init()方法
再将之传入,是与Web应用程序资源相关的对象,所以在继承HttpServlet后,通
常会重新定义无参数的init()方法以进行Servlet初始参数的取得。
GenericServlet
定义了一些方法,将ServletConfig封装起来,便于取得设置信息,所以取得Servlet
初始参数的代码也可以改写为:
例:
......
@WebServlet(name="SevletConfigDemo",urlPatterns={"/conf"},
initParams={
@WebInitParam(name="Param1",value="value1"),...})
publicclassServletConfigDemoextendsHttpServlet{
privateStringParam1;
......
publicvoidinit()throwsServletException{
Param1=getInitParameter("Param1");
......}
.....}
Servlet初始参数通常作为常数设置,可以将一些Servlet程序默认值使用标设为初
始参数,之后若想变更那些信息,可以创建web.xml进行设置,以覆盖标注设置,
而不用进行修改源代码、重新编译、部署的操作。
3.使用ServletContext
ServletContext接口定义了运行Servlet的应用程序环境的一些行为与观点,可以使
用ServletContext实现对象来取得所请求资源的URL、设置与储存属性、应用程序
初始参数,甚至动态设置Servlet实例。
当整个Web应用程序加载Web容器之后,容器会生成一个ServletContext对象作
为整个应用程序的代表,并设置给ServletConfig,只要通过ServletConfig的
getServletContext()方法就可以取得ServletContext对象。
1.getRequestDispatcher()
用来取得RequestDispatcher实例,使用时路径的指定必须以"/"作为开关,
这个斜杠代表应用程序环境根目录。
取得RequestDispatcher实例之后,就可以进
行请求的转发(Forward)或包含(Include)。
例:
context.getRequestDispatcher("/pages/some.jsp").forward(request,response);
以"/"作为开头有时称为环境相对(Context-relative)路径,没有以"/"作为
开头则称为请求相对(Request-relative)路径。
实际上HttpServletRequest的
getRequestDispatcher()方法在实现时,若是环境相对程序,则直接委托給ServletContext
的getRequestDispatcher();若是请求相对路径,则转换为环境相对路径,再委托给
ServletContext的getRequestDispatcher()来取得RequestDispatcher。
2.getResourcePaths()
如果想要知道Web应用程序的某个目录中有哪些文件,则可以使用
getResourcePaths()方法。
例:
for(Stringavatar:
getServletContext().getResourcePaths("/")){.....}
3.getResourceAsStream()
如果想在Web应用程序中读取某个文件的内容,则可以使用getResourceAsStream()
方法,使用时指定路径必须以"/"作为开头,表示相对于应用程序环境根目录,
或者相对是/WEB-INF/lib中JAR文件里META-INF/resources的路径,运行结果会
返回InputStream实例,接着就可以运用它来读取文件内容。
注意与java.io下的File、FileReader、FileInputStream等与文件读取相关的类。
使
用这些类时,用相对路径时,此时路径不是相对于Web应用程序根目录,而是相
对于启动Web容器时的命令执行目录。
以Tomcat来说,若在Servlet中执行以下:
out.println(newFile("filename").getAbsolutePath());
则会显示filename是位于Tomcat目录下的bin目录中,例如:
X:
\......\Tomcat\bin\filename这样的路径
每个Web应用程序都会有一个相对应的ServletContext,针对"应用程序"初始化
时需用到一些参数数据,可以在web.xml中设置应用程序初始参数,通常这会结合
ServletContextListener来做。
2、应用程序事件、监听器
1.ServletContext事件、监听器
ServletContext是“生命周期监听器”,如果想要知道何时Web应用程序已经初始
化或即将结束销毁,可以实现ServletContext。
packagejavax.servlet;
importjava.util.EventListener;
publicinterfaceServletContextListenerextendsEventListener{
publicvoidcontextInitialized(ServletContextEventsce);//实现应用资源准备
publicvoidcontextDestroyed(ServletContextEventsce);//释放应用程序资源
}
————————————————————————————————————
@WebListener//①
publicclassContextParameterReaderimplementsServletContextListener{//②
publicvoidcontextInitalized(ServletContextEventsce){
ServletContextEventcontext=sce.getServletContent();//③
Stringavatars=context.getInitParameter(“AVATAR”);//④
context.setAttribute(“avatars”,avatars);//⑤
}
publicvoidcontextDestroyed(ServletContextEventsce){}
}
ServletContextListener可以直接使用@WebListener标注①,而且必须实现
ServletContextListener接口②,这样容器就会在启动时加载并运行对应的方法。
当
容器调用contextInitalized()或contextDestroyed()时,会传入ServletContext-Event,
其封装了ServletContext,可以通过ServletContextEvent的getServletContext()方法
取得ServletContext③,通过ServletContext的getInitParameter()方法来读取初始参
数④,因此Web应用程序初始参数被称为ServletContext初始参数。
在整个Web应用程序生命周期,Servlet需共享的资料可以设置为ServletContext
属性。
因为ServletContext在Web应用程序存活期间都会一直存在。
可以通过ServletContext的setAttribute()方法设置对象为ServletContext属性⑤,
之后可通过ServletContext的getAttribute()方法取出该属性。
若要移除属性,则通
过ServletContext的removeAttribute()方法。
如需设置初始参数,可以在web.xml中设置:
....
....
————————————————————————————————————
如果设置了web.xml那么代码只需要这样修改:
@WebServlet(“/avatar”)//仅设置URL模式
publicclassAvatarextendsHttpServlet{
privateStringAVATAR_DIR;
@Override
publicvoidinit()throwsServletException{
AVATAR_DIR=(String)getServletContext().getAttribute(“avatars”);//取得属性
}
.......
}
2.ServletContextAttributeListener
ServletContextAttributeListener是“监听属性改变的监听器”,如果想要对象被
设置、移除或替换ServletContext属性,可以收到通知以进行一些操作,则可
以实现ServletContextAttributeListener。
publicinterfaceServletContextAttributeListenerextendsEventListener{
publicvoidattributeAdded(ServletContextAttributeEventscab);
publicvoidattributeRemoved(ServletContextAttributeEventscab);
publicvoidattributeReplaced(ServletContextAttributeEventscab);
}
当在ServletContext中添加属性、移除属性或替换属性时,相对应的方法就会被
调用。
如果希望容器在部署应用程序时,实例化实现ServletContextAttributeListener
的类并注册给应用程序,同样也是在实现类上标注@WebListener,并实现
ServletContextAttributeListener接口。
......
@WebListener()
publicinterfaceServletContextAttributeListenerimplementsEventListener{
.....
}
另一种方式是在web.xml中设置:
.....
包名加类名
.....
2.HttpSession事件、监听器
与HttpSession相关的监听器有四个:
HttpSessionListener、HttpSessionAttributeListener、
HttpSessionBindingListener与HttpSessionActivationListener。
1.HttpSessionListener
HttpSessionListener是“生命周期监听器”,如果想要在HttpSession对象创建或
结束时,做些相对应动作,则可以实现HttpSessionListener。
publicinterfaceHttpSessionListenerextendsEventListener{
publicvoidsessionCreated(HttpSessionEventse);
publicvoidsessionDestroyed(HttpSessionEventse);
}
在HttpSession对象初始化或结束前,分别调用sessionCreated()与sessionDestroyed()
方法,可以通过传入的HttpSessionEvent,使用getSession()取得HttpSession,以针
对会话对象作出相对应的创建或结束处理操作。
对于用户在注销前小心关闭浏览器,没有确实运行注销操作,那么数据库中代表登
录与否的字段就不会被重置。
为此,可以实现HttpSessionListener,由于HttpSession
有其存活期限,当容器销毁某个HttpSession时,就会调用sessionDestroyed(),就
可以在当中判断要重置哪个用户数据库中代表登录与否的字段。
例如:
......
@WebListener()
publicclassResetLoginHelperimplementsHttpSessionListener{
@Override
publicvoidsessionCreated(HttpSessionEventse){}
@Override
publicvoidsessionDestroyed(HttpSessionEventse){
HttpSessionsession=se.getSession();
Stringuser=session.getAttribute(“login”);
//修改数据库字段为注销状态
}
}
如果在实现HttpSessionListener的类上标注@WebListener,则容器在部署应用程序
时,会实例化并注册给应用程序。
另一个方式是在web.xml中设置:
.....
包名加类名
.....
2.HttpSessionAttributeListener
HttpSessionAttributeListener是“属性改变监听器”,当在会话对象中加入属性、
移除属性或替换属性时,相对应的AttributeAdded()、attributeRemoved()与
attributeReplaced()方法就会被调用,并分别传入HttpSessionEvent。
publicinterfaceHttpSessionAttributeListenerextendsEventListener{
publicvoidattributeAdded(HttpSessionBindingEventscab);
publicvoidattributeRemoved(HttpSessionBindingEventscab);
publicvoidattributeReplaced(HttpSessionBindingEventscab);
}
HttpSessionbindingEvent有个getName()方法,可以取得属性设置或移除时指定
名称,而getValue()可以取得属性设置或移除时的对象。
如果希望容器在部署应用程序时,实例化实现HttpSessionAttributeListener的
类并注册给应用程序,则同样也是实现类上标注@WebListener:
......
@WebListener()
publicinterfaceHeablimplementsHttpSessionAttributeListener{
.....
}