Servlet: 狭义上servlet是Java语言提供的接口,广义上认为是实现Servlet接口的类。 Servlet API下包含四个包分别是 servlet:包含定义servlet和servlet容器(Tomcat、JBoss、Jetty)之间契约的类和接口 servelet.http: 包含定义Http Servlet与Servlet容器之间的关系 servlet.annotation: 包含定义Servlet、Filter、Linstener的标注,它还被标注元件定义元数据 servlet.description: 包含提供程序化登录Web应用程序的配置信息的类型 Servlet接口的源码: public interface Servlet { void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); // 会返回由Servlet容器传给init()方法的ServletConfig对象。 void destroy(); } ServletConfig类的源码: public interface ServletConfig { String getServletName();
ServletContext getServletContext(); String getInitParameter(String var1); Enumeration<String> getInitParameterNames(); } Servlet接口定义了Servlet与servlet容器之间的契约,这个契约是:Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。 在一个应用程序中,每种Servlet类型只能有一个实例。 用户请求致使Servlet容器(如Tomcat)调用servlet的service()方法,并传入一个ServletReuest对象和ServletResponse对象, 这两个对象都是有Servlet容器(如Tomcat)封装好的,不需要我们去实现,我们可以直接使用这两个对象。 对于每一个应用程序,Servlet还会创建一个ServletContext对象,用来封装上下文的环境信息,每一个应用程序只能有一个ServletContext, 每一个Servlet对象也都有一个封装的Servlet配置的ServletConfig对象。 GenericServlet抽象类实现了Servlet接口和ServletConfig接口 GenericServlet抽象类相比于直接实现Servlet接口,有以下几个好处: 1.为Servlet接口中的所有方法提供了默认的实现,不再需要把所有的方法都自己实现了。 2.提供方法,包围ServletConfig对象中的方法。 3.将init()方法中的ServletConfig参数赋给了一个内部的ServletConfig引用从而来保存ServletConfig对象,不需要自己去维护ServletConfig了。 然而,虽然GenricServlet是对Servlet一个很好的加强,但是也不经常用,因为他不像HttpServlet那么高级。 HttpServlet: HttpServlet有两个特性是GenericServlet所不具备的: 1.不用覆盖service方法,而是覆盖doGet或者doPost方法。在少数情况,还会覆盖其他的5个方法。 2.使用的是HttpServletRequest和HttpServletResponse对象。 HttpServletResponse接口: 继承自ServletResponse接口,专门封装HTTP响应消息,由于Http请求分为状态行、响应消息头、响应消息体三部分, 所以在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。 方法: PrintWriter getWriter():获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中, 随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。 ServletOutputStream getOutputStream():获得字节流(ServletOutputStream类型),通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节, 再由Tomcat服务器将字节内容组成Http响应返回给浏览器。因为它可以直接输出字节数组中的二进制数据,因此要输出二进制响应的正文,就需要使用getOutputStream()方
法。 虽然response对象的getOutSream()和getWriter()方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。 response的乱码问题: response缓冲区的默认编码是iso8859-1,此码表中没有中文。所以需要更改response的编码方式: response.setCharacterEncodig("utf-8") 通过更改response的编码方式为UTF-8,任然无法解决乱码问题,因为发送端服务端虽然改变了编码方式为UTF-8, 但是接收端浏览器端仍然使用GB2312编码方式解码,还是无法还原正常的中文, 因此还需要告知浏览器端使用UTF-8编码去解码。 response.setHeader("Content-Type", "text/html;charset=utf-8") 上面通过调用两个方式分别改变服务端对于Response的编码方式以及浏览器的解码方式为同样的UTF-8编码来解决编码方式不一样发生乱码的问题。 实际应用中只需要调用response.setContentType("text/html;charset=UTF-8")即可,该方法包含上述两个方法的调用。 ServletContextListener ServletContex翻译成中文是Servlet上下文或者叫Servlet全局。其实ServletContext就是一个“域对象”,它存在于整个应用中,并在整个应用中有且仅有一份。 他表示了当前整个应用的状态,可以理解为某个时刻的servletContext代表了这个应用在某个时刻的一张快照,这张快照包含了有关应用的许多信息,应用的所有组件 都可以从ServletContext获取当前应用的状态信息。 小结:当Servlet容器启动时,ServletContext对象被初始化, 当ServletContext创建时我们可以创建applicationContext对象,当ServletContext销毁时,我们可以销毁applicationContext对象。