Servlet规范
Servlet规范描述了HTTP请求及响应处理过程相关的对象及其作用。本文就来介绍下Servlet规范中一些重要的接口。
Servlet接口
Servlet规范的核心接口即是Servlet接口,它是所有Servlet类必须实现的接口。在Java Servelt API中已经提供了两个抽象类方便开发者实现Servlet类,分别是GenericServlet和HttpServlet, GenericServlet定义了一个通用的、协议无关的Servlet,而HttpServlet则定义了HTTP的Servlet,这两个抽象类可以使Servlet类复用很多共性功能。
Servlet的生命周期主要包括加载实例化、初始化、处理客户端请求、销毁。加载实例化主要由Web容器完成,而其他三个阶段则对应Servlet的init、service和destroy方法。
ServletRequest接口
ServletRequest接口的实现类封装了客户端请求的所有信息,如果使用HTTP协议通信则包括HTTP的请求行和请求头部。HTTP对应的请求对象类型是HttpServletRequest类。ServletRequest接口的实现类中的信息包括以下几部分。
-
一些HTTP请求头部的获取方法,如getHeader、getHeaders和getHeaderNames。
-
一些获取请求路径的方法,如getContextPath、getServletPath和getPathInfo,对于路径变量,其中requestURI=contextPath+servletPath+pathInfo,而getRealPath方法则是获取某个相对路径对应的文件系统路径。
-
获取Cookie的方法,如getCookies方法;提供了判断标识是否为HTTPS的方法,如isSecure方法。
-
获取客户端语言环境的方法,如getLocale和getLocales,它们对应HTTP的Accept-Language头部
-
获取客户端编码的方法,如getCharacterEncoding,对应HTTP协议的Content-Type头部。
ServletRequest接口的对象只在Servlet的service方法或过滤器的doFilter方法作用域内有效,除非启用了异步处理以调用ServletRequest接口对象的startAsync方法,此时request对象会一直有效,直到调用AsyncContext的complete方法。另外,Web容器通常会出于性能原因而不销毁ServletRequest接口的对象,而是重复利用ServletRequest接口对象。
ServletContext接口
ServletContext接口定义了运行所有Servlet的Web应用的视图。其提供的内容包括以下几个部分。
-
某个Web应用的Servlet全局存储空间,某Web应用对应的所有Servlet共有的各种资源和功能的访问。
-
获取Web应用的部署描述配置文件的方法,例如getInitParameter和getInitParameterNames。
-
添加Servlet到ServletContext里面的方法,例如addServlet。
-
添加Filter(过滤器)到ServletContext里面的方法,例如addFilter。
-
添加Listener(监听器)到ServletContext里面的方法,例如addListener。
-
全局的属性保存和获取功能,例如setAttribute、getAttribute、getAttributeNames和removeAttribute等
-
访问Web应用静态内容的方法,例如getResource和getResourceAsStream,以路径作为参数进行查询,此参数要以“/”开头,相对于Web应用上下文的根或相对于Web应用WEB-INF/lib目录下jar包的META-INF/resources。
所有Servlet及它们使用的类需要由一个单独的类加载器加载。每个实现ServletContext接口的对象都需要一个临时存储目录,Servlet容器必须为每个ServletContext分配一个临时目录,并可在ServletContext接口中通过javax.servlet.context.tempdir属性获取该目录。
ServletResponse接口
ServletResponse接口的对象封装了服务器要返回客户端的所有信息。如果使用HTTP,则包含了HTTP的响应行、响应头部和响应体。
为了提高效率,一般ServletResponse接口对响应提供了输出缓冲。其中,getBufferSize用于获取缓冲区大小;setBufferSize用于设置缓冲区大小;flushBuffer强制刷新缓冲区;resetBuffer将清空缓冲区中的内容,但不清空请求头部和状态码;isCommitted判断是否有任何响应字节已经返回给客户端;reset清空缓冲区内容,同时清空头部信息和状态码。
ServletResponse接口对应HTTP的实现对象为HttpServletResponse,可以通过setHeader和addHeader方法向HttpServletResponse中添加头部;可以通过sendRedirect将客户端重定向到另外一个地址;可以通过sendError将错误信息输出到客户端。
当ServletResponse接口关闭时,缓冲区中的内容必须立即刷新到客户端,ServletResponse接口只在Servlet的service方法或过滤器的doFilter方法的作用域内有效,除非它关联的ServletResponse接口调用了startAsync方法启用异步处理,此时ServletResponse接口会一直有效,直到调用AsyncContext的complete方法。另外,Web容器通常会出于性能原因而不销毁ServletResponse接口对象,而是重复利用ServletResponse接口对象。
Filter接口
Filter接口允许Web容器对请求和响应做统一处理。例如,统一改变HTTP请求内容和响应内容,它可以作用于某个Servlet或一组Servlet。
Web应用部署完成后,必须实例化过滤器并调用其init方法。当请求进来时,获取第一个过滤器并调用doFilter方法,接着传入ServletRequest对象、ServletResponse对象及过滤器链(FilterChain), doFilter方法负责过滤器链中下一个实体的doFilter方法调用。当容器要移除某过滤器时必须先调用过滤器的destroy方法。
可以用“@WebFilter”注解或部署描述文件定义过滤器,XML配置形式使用
会话
Servlet没有提出协议无关的会话规定,而是每个通信协议自己规定,HTTP对应的会话接口是HttpSession。Cookie是常用的会话跟踪机制,其中Cookie的标准名字必须为JSESSIONID。另外一种会话跟踪机制则是URL重写,即在URL后面添加一个jsessionid参数,当支持Cookie和SSL会话的情况下,不应该使用URL重写作为会话跟踪机制。
会话ID通过调用HttpSession.getId()获取,且能在创建后通过调用HttpServletRequest. changeSessionId()改变。HttpSession对象必须限定在ServletContext级别,会话里面的属性不能在不同ServletContext之间共享。
Servlet可将某对象以键值对形式保存到HttpSession中,处于同一个ServletContext和相同会话中的任意Servlet都可以使用会话中保存的对象。如果某些对象想要在保存到会话或从会话中移除时得到通知,可以让某个对象实现HttpSessionBindingListener接口,里面的valueBound和valueUnbound分别会在对应时刻触发。
Servlet容器默认会话的超时时间,可以通过HttpSession的getMaxInactiveInterval方法获取和setMaxInactiveInterval方法设置。
分布式环境中,会话的所有请求在同一时间必须仅被一个JVM处理,分布式容器迁移会话时会通知实现了HttpSessionActivationListener接口的所有会话属性。
注解
Web应用中,使用了注解的类只有被放到WEB-INF/classes目录中或WEB-INF/lib目录下的jar中,注解才会被Web容器处理。web.xml配置文件的
@WebServlet注解用于在Web项目中定义Servlet,它必须指定urlPatterns或value属性,默认的name属性为完全限定类名,@WebServlet注解的类必须继承javax.servlet.http.HttpServlet类。
@WebFilter注解用于在Web项目定义Filter,它必须指定urlPatterns、servletNames或value属性,默认的filterName属性为完全限定类名,使用@ WebFilter注解的类必须实现javax.servlet.Filter。
@WebInitParam注解用于指定传递到Servlet或Filter的初始化参数,它是WebServlet和WebFilter注解的一个属性。
@WebListener注解用于定义Web应用的各种监听器,使用@WebListener注解的类必须实现以下接口中的一个:
- javax.servlet.ServletContextListene
- javax.servlet.ServletContextAttributeListener
- javax.servlet.ServletRequestListener
- javax.servlet.ServletRequestAttributeListener
- javax.servlet.http.HttpSessionListener
- javax.servlet.http.HttpSessionAttributeListener
- javax.servlet.http.HttpSessionIdListener;
@MultipartConfig注解用于指定Servlet请求期望的是mime/multipart类型。
参考
本文摘录自
- 《Tomcat内核设计剖析》