web.xml配置

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>

Tips:

如果自定义实现的Filter需要一个构造函数怎么办? 在配置Filter时没有提供这个配置项。
这时我们就可以使用DelegatingFilterProxy,它会去spring中根据Filter名字找bean,这样我们初始化Filter bean就可以了。

四. 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>
原文地址:https://www.cnblogs.com/Sicwen/p/10595506.html