美文网首页
回顾下Servlet(2)2018-08-06

回顾下Servlet(2)2018-08-06

作者: Seetheworl_6675 | 来源:发表于2018-08-06 23:33 被阅读0次

一:Session管理:

必要性:

 http 是无状态的,在默认的情况下Web服务器是不知道一个Http请求是来自初次用户,还是来自之前已经访问过的用户。所以就当用户登入后是没必要再次登入。应用程序需要记住哪些用户是登入过的。

保持状态的4种方法:

1、URL重写:Session的追踪技术,需要将一个或者多个的token作为一个查询字符串添加到一个URL中。
2、隐藏域:将值保存在HTML页面的隐藏域中当用户提交表单时,隐藏域中的值也传送到服务器中。
3、cookie:cookie是作为Http标头嵌入的,所以传输过程是Http协议处理的当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。但是用户可以通过修改浏览器设置来拒绝接受Cookie。
4、HttpSession:HttpSession 保存的值不发送到客户端,Servelt容器会为它创建一个唯一的表识符,并将这个表识符作为token发送给浏览器,一般是作为一个JSESSIONID的cookie,或者作为一个jsessionid参数添加到URL后面。后续请求浏览器会将这个token发送回服务器。

二:Servlet的监听器

三个不同级别的监听对象:ServletContext、HttpSession、ServletRequest

ServletContext的监听器:

 1、ServletContextListener:能监听ServletContext一生中的两个关键事件:初始化(创建)和撤销;

public interface ServletContextListener extends EventListener {
    //ServletContext初始化时调用
    public void contextInitialized(ServletContextEvent sce);
   
   //ServletContext被撤销时调用
    public void contextDestroyed(ServletContextEvent sce);
}
//事件
public class ServletContextEvent extends java.util.EventObject {

    private static final long serialVersionUID = 1L;

    public ServletContextEvent(ServletContext source) {
        super(source);
    }

    public ServletContext getServletContext() {
        return (ServletContext) super.getSource();
    }
}

 2、ServletContextAttributeListener:当ServletContext范围内的属性被添加删除,替换时,这些对应的监听器将会被触发。

public interface ServletContextAttributeListener extends EventListener {
   //添加
    public void attributeAdded(ServletContextAttributeEvent scae);
   //删除
    public void attributeRemoved(ServletContextAttributeEvent scae);
    //替换
    public void attributeReplaced(ServletContextAttributeEvent scae);
}
//事件
public interface ServletContextAttributeListener extends EventListener {
  
    public void attributeAdded(ServletContextAttributeEvent scae);

  
    public void attributeRemoved(ServletContextAttributeEvent scae);

  
    public void attributeReplaced(ServletContextAttributeEvent scae);
}
Session监听器

 HttpSessionListener:用来监听HttpSession对象的创建和销毁。

public interface HttpSessionListener extends EventListener {
    //创建时调用
    public void sessionCreated(HttpSessionEvent se);
  //销毁时调用
    public void sessionDestroyed(HttpSessionEvent se);
}
//事件
public class HttpSessionEvent extends java.util.EventObject {
    private static final long serialVersionUID = 1L;
    
  public HttpSessionEvent(HttpSession source) {
        super(source);
    }

    public HttpSession getSession() {
        return (HttpSession) super.getSource();
    }
}

 2、HttpSessionAttributeListener:当Session中的属性被添加删除,替换时,这些对应的监听器将会被触发。

public interface HttpSessionAttributeListener extends EventListener {

   //添加
    public void attributeAdded(HttpSessionBindingEvent se);

   //移除
    public void attributeRemoved(HttpSessionBindingEvent se);

   //替换
    public void attributeReplaced(HttpSessionBindingEvent se);
}

//事件
public class HttpSessionBindingEvent extends HttpSessionEvent {

    private static final long serialVersionUID = 1L;

    private final String name;

    private final Object value;

    public HttpSessionBindingEvent(HttpSession session, String name) {
        super(session);
        this.name = name;
        this.value = null;
    }

    public HttpSessionBindingEvent(HttpSession session, String name,
            Object value) {
        super(session);
        this.name = name;
        this.value = value;
    }

    @Override
    public HttpSession getSession() {
        return super.getSession();
    }

    public String getName() {
        return name;
    }

    public Object getValue() {
        return this.value;
    }
}

 3、HttpSessionActivationListener:实现此接口的JavaBean,可以感知自己被活化(从硬盘到内存)和钝化(从内存到硬盘)的过程。

案例:

public class Person implements Serializable, HttpSessionActivationListener {
    private String name;

    public Person(String name) {
        super();
        this.name = name;
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        System.out.println(this + "保存到硬盘了...");
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println(this + "从硬盘读取并活化了...");
    }

    @Override
    public String toString() {
        return "Perosn [name=" + name + "]---"+super.toString();
    }
}

 4、HttpSessionBindingListener对象实现了HttpSessionBindingListener接口,当这个对象被绑定到Session中或者从session中被删除时,Servlet容器会通知这个对象;

案例:

public class UsersOnlineCountListener implements HttpSessionBindingListener {
    int uid;
    public int getUid() {
       return uid;
    }
    public void setUid(int uid) {
       this.uid = uid;
    }
    @Override
    public void valueBound(HttpSessionBindingEvent arg0) {
        System.out.println(uid+"登录了"+new Date());
    }
    @Override
    public void valueUnbound(HttpSessionBindingEvent arg0) {
       System.out.println(uid+"下线了"+new Date());
    }
}
ServletRequest的监听器:

 ServletReqeustListener:用来监听ServletReqeust对象的创建和销毁。在Servlet容器中是通过池来重用ServletRequest的,创建ServletRequest花费的时间是从池中获取ServletRequest的时间,ServletRequest销毁相当于把ServletRequest还回池中的时间。

public interface ServletRequestListener extends EventListener {
    //销毁
    public void requestDestroyed (ServletRequestEvent sre);
  //初始化
    public void requestInitialized (ServletRequestEvent sre);
}
//事件
public class ServletRequestEvent extends java.util.EventObject {
    private static final long serialVersionUID = 1L;

    private final transient ServletRequest request;

    public ServletRequestEvent(ServletContext sc, ServletRequest request) {
        super(sc);
        this.request = request;
    }

    public ServletRequest getServletRequest() {
        return this.request;
    }

    public ServletContext getServletContext() {
        return (ServletContext) super.getSource();
    }
}

  ServletRequestAttributeListener:当ServletRequest中的属性被添加删除,替换时,这些对应的监听器将会被触发。

public interface ServletRequestAttributeListener extends EventListener {
     //添加
    public void attributeAdded(ServletRequestAttributeEvent srae);

  //移除
    public void attributeRemoved(ServletRequestAttributeEvent srae);

   //替换
    public void attributeReplaced(ServletRequestAttributeEvent srae);
}

三:过滤器Filter

过滤器主要接口: Filter、FilterConfig、FilterChain

Filter
public interface Filter {

     //Servlet启动服务时,Servlet容器会调用初始化代码
    public void init(FilterConfig filterConfig) throws ServletException;

    //每次http请求,filter进行拦截都会执行
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;

    //过滤器终止服务
    public void destroy();

}

过滤器拦截流程:

1、当客户端发生请求后,在HttpServletRequest 到达Servlet 之前,过滤器拦截客户的HttpServletRequest 。
2、根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。
3、在过滤器中调用doFilter方法,对请求放行。请求到达Servlet后,对请求进行处理并产生HttpServletResponse发送给客户端。
4、在HttpServletResponse 到达客户端之前,过滤器拦截HttpServletResponse 。
5、根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。
6、最后,HttpServletResponse到达客户端。

FilterConfig(过滤器的配置)
四、FilterChain

 在一个Web应用程序中可以注册多个Filter程序,每个Filter程序都可以对一个或一组Servlet程序进行拦截。FilterChain其实就是一条过滤器链

Servlet容器的初始化

 容器的初始化的核心是javax.servlet.ServletContainerInitializer接口,

package javax.servlet;
 
import java.util.Set;
 
/**
 * 目的:Servlet容器初始化(ServletContainerInitializer初始化器)
 * 
 * <p>web容器启动时,调用该接口的实现(初始化器),
 * 初始化已被注册的servlets、filters、listeners。
 * 
 * <p>{@link javax.servlet.annotation.HandlesTypes HandlesTypes}注解
 * 来实现该接口,注解的类作为onStartup()方法的参数传入。
 * 
 * <p>没有@HandlesTypes注解或没有指定应用程序类匹配的注解时,容器{@link #onStartup}必须是个null集合
 * 
 * <p>实现该接口就必须在对应的jar包的META-INF/services
 * 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,
 * 该文件内容指定该接口的具体实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。
 * 
 * 实现机制:
 * Tomcat容器的ServletContainerInitializer机制的实现,主要交由Context容器
 * 和ContextConfig监听器共同实现,ContextConfig监听器负责在容器启动时读取每个web
 * 应用的WEB-INF/lib目录下包含的jar包的META-INF/services/javax.servlet.
 * ServletContainerInitializer,以及web根目录下的META-INF/services/
 * javax.servlet.ServletContainerInitializer,通过反射完成这些
 * ServletContainerInitializer的实例化,然后再设置到Context容器中,最后
 * Context容器启动时就会分别调用每个ServletContainerInitializer的onStartup方法,
 * 并将感兴趣的类作为参数传入。
 * 参考资料:http://blog.csdn.net/wangyangzhizhou/article/details/52013779
 *
 * @author TCM
 * @create 2017年10月24日上午9:55:01
 * @see javax.servlet.annotation.HandlesTypes
 * @since Servlet 3.0
 */
public interface ServletContainerInitializer {
 
    /**
     * 启动ServletContainerInitializer具体实例后,并设置到ServletContext中
     * @param c 实现该接口的具体实现类
     * @param ctx ServletContext
     * @throws ServletException if an error has occurred
     */
    public void onStartup(Set<Class<?>> c, ServletContext ctx)
        throws ServletException; 
}

1、Servlet容器启动会扫描,当前应用里面每一个jar包的
ServletContainerInitializer的实现
2、提供ServletContainerInitializer的实现类;
必须绑定在,META-INF/services/javax.servlet.ServletContainerInitializer
文件的内容就是ServletContainerInitializer实现类的全类名;
3、可以给ServletContainerInitializer 的实现类添加@HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup方法作为参数传入。

相关文章

网友评论

      本文标题:回顾下Servlet(2)2018-08-06

      本文链接:https://www.haomeiwen.com/subject/jrogvftx.html