web中执行顺序,加载context-param参数 -> 按声明顺序执行listener -> 执行filter链 -> 执行servlet
一. context-param
context-param用来设置属性值,在listener,filter,servlet中都可以读取到该值
<!--自定义属性-->
<context-param>
?<param-name>customName</param-name>
?<param-value>customValue</param-value>
</context-param>
<!--ContextLoaderListener会读取contextConfigLocation属性-->
<context-param>
?<param-name>contextConfigLocation</param-name>
?<param-value>classpath:applicationContext.xml</param-value>
</context-param>
二. listener
在servlet-api中提供了ServletContextListener和ServletRequestListener两种监听器
下面我们自定义一个Listener,实现ServletContextListener接口,在该方法中获取context-param配置的属性值
public class SomeListener implements ServletContextListener { ???@Override ???public void contextInitialized(ServletContextEvent sce) { ???????System.out.println("SomeListener.contextInitialized"); ???????ServletContext sc = sce.getServletContext(); ???????String value = sc.getInitParameter("customName"); ???????System.out.println("get customName value: " + value); ???} ???@Override ???public void contextDestroyed(ServletContextEvent sce) { ???????System.out.println("SomeListener.contextDestroyed"); ???}}
在web.xml中配置listener
?<listener> ???<listener-class>com.xxx.listener.SomeListener</listener-class> ?</listener>
使用spring web中的ContextLoaderListener,该类同样实现了ServletContextListener接口
执行该Listener时,默认会读取/WEB-INF/applicationContext.xml文件
可以通过context-param中的contextConfigLocation属性修改读取文件的位置
?<listener> ???<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> ?</listener>
三. filter
实现Filter接口,在初始化时可以获取到context-param中的参数信息,也可以获取到filter中的init-param信息
在doFilter时可以做一些过滤操作,比如Shiro中的认证授权操作。
public class SessionFilter implements Filter { ???@Override ???public void init(FilterConfig filterConfig) throws ServletException { ???????System.out.println("SessionFilter.init"); ???????String filterValue = filterConfig.getInitParameter("filterKey"); ???????System.out.println("SessionFilter get filterKey: " + filterValue); ???????String customValue = filterConfig.getServletContext().getInitParameter("customName"); ???????System.out.println("SessionFilter get customValue: " + customValue); ???} ???@Override ???public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ???????//do somthing ???????if(request instanceof HttpServletRequest){ ???????????HttpServletRequest httpRequest = (HttpServletRequest) request; ???????????Cookie[] cookies = httpRequest.getCookies(); ???????????for (Cookie cookie : cookies) { ???????????????if ("JSESSIONID".equals(cookie.getName())) { ???????????????????String sessionId = cookie.getValue(); ???????????????????System.out.println("sessionId is: " + sessionId); ???????????????} ???????????} ???????} ???????chain.doFilter(request,response); ???} ???@Override ???public void destroy() { ???????System.out.println("SessionFilter.destroy"); ???}}
配置web.xml
url-pattern4中匹配规则
- 以 / 开头和以 /* 为结尾的是路径匹配
- 以 *. 开头的是扩展名匹配,比如 *.dao 匹配以dao为结尾的资源
- 只有 / 是定义default servlet,当请求的url和url-pattern没有匹配的时候,把请求发送default servlet
- 精确匹配如: /a/b/c
所以Filter中的url-pattern要使用 /* 而不能使用 /
?<filter> ???<filter-name>sessionFilter</filter-name> ???<filter-class>com.xxx.filter.SessionFilter</filter-class> ???<init-param> ?????<param-name>filterKey</param-name> ?????<param-value>filterValue</param-value> ???</init-param> ?</filter> ?<filter-mapping> ???<filter-name>sessionFilter</filter-name> ???<url-pattern>/*</url-pattern> ?</filter-mapping>
四. servlet
当请求经过filter过滤后,就会交给servlet处理,servlet是一个接口,其中service()是最终要调用的方法
如下我们继承HttpServlet,并重写他的service方法,在service方法中会传进来HttpServletRequest和HttpServletResponse
public class HelloServlet extends HttpServlet {
???@Override
???public ServletConfig getServletConfig() {
???????System.out.println("HelloServlet.getServletConfig");
???????return super.getServletConfig();
???}
???@Override
???public void init() throws ServletException {
???????System.out.println("HelloServlet.init");
???}
???@Override
???protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
???????HttpSession session = req.getSession();
???????session.setAttribute("username","sicwen");
???????session.setAttribute("password","123");
???????req.getRequestDispatcher("hello.jsp").forward(req,resp);
???????System.out.println("HelloServlet.service");
???}
???@Override
???public void destroy() {
???????System.out.println("HelloServlet.destroy");
???}
}
在web.xml中配置
?<servlet> ???<servlet-name>hello</servlet-name> ???<servlet-class>com.xxx.servlet.HelloServlet</servlet-class> ?</servlet> ?<servlet-mapping> ???<servlet-name>hello</servlet-name> ???<url-pattern>/hello</url-pattern> ?</servlet-mapping>
web.xml配置
原文地址:https://www.cnblogs.com/Sicwen/p/10595506.html