• 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>
  • 相关阅读:
    [学习笔记] 高维前缀和
    [模板] BEST 定理
    [HDU6765] Count on a Tree II Striking Back
    Codeforces Round #775 (Div. 1)
    Stream流:自定义的distinctByKey根据对象的属性进行去重
    代码优化:尽量采用懒加载的策略,即在需要的时候才创建
    volatile解决内存可见性的使用
    代码优化:String替换尽量少用正则表达式(replace()和replaceAll()的区别)
    内存可见性以及synchronized实现可见性
    代码优化:防止空指针异常 NPE ,是程序员的基本修养,注意 NPE 产生的场景:
  • 原文地址:https://www.cnblogs.com/Sicwen/p/10595506.html
Copyright © 2020-2023  润新知