欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

9、Servlet开发

程序员文章站 2022-07-12 14:35:56
...

一、Servlet简介

 

  • Servlet是sun公司提供的一门用于开发动态web资源的技术。
  • Sun公司在其API中提供了一个servlet接口,用户若想开发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
  • -----编写一个Java类,实现servlet接口。
  • -----把开发好的Java类部署到web服务器中。

二、Servlet的运行过程

 

  • Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
  • --1、Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
  • --2、装载并创建该Servlet的一个实例对象
  • --3、调用Servlet实例对象的init()方法。将ServletConfig对象传入
  • --4、创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  • --5、WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

三、Servlet继承结构及常用类

 

Servlet

|--GenericServlet

|--HttpServlet

 

  1. Servlet
    /**
     * javax.servlet.Servlet
     * 定义所有 servlet 都必须实现的方法。
     * servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
     * 要实现此接口,可以编写一个扩展 javax.servlet.GenericServlet 的一般 servlet,
     * 或者编写一个扩展 javax.servlet.http.HttpServlet 的 HTTP servlet。
     * 此接口定义了初始化 servlet 的方法、为请求提供服务的方法和从服务器移除 servlet 的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:
     * 1,构造 servlet,然后使用 init 方法将其初始化。 
     * 2,处理来自客户端的对 service 方法的所有调用。
     * 3,从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它
     */
    public interface Servlet{
    	//由 servlet 容器调用,指示将该 servlet 放入服务。 
    	void init(ServletConfig config)
              throws ServletException;
              
    	//由 servlet 容器调用,以允许 servlet 响应某个请求。
    	void service(ServletRequest req,
                 ServletResponse res)
                 throws ServletException,
                        IOException;
                        
    	//由 servlet 容器调用,指示将从服务中取出该 servlet。
    	void destroy();
    	
    	//返回 ServletConfig 对象,该对象包含此 servlet 的初始化和启动参数。返回的 ServletConfig 对象是传递给 init 方法的对象。
    	ServletConfig getServletConfig();
    	
    	//返回有关 servlet 的信息,比如作者、版本和版权
    	String getServletInfo();                    
    }
     
  2. GenericServlet
    GenericServlet:实现了Servlet接口,提供了对Servlet接口的默认实现,其中大部分的方法都做了默认实现,只有service方法没有实现是一个抽象方法。
    /**
     * javax.servlet.GenericServlet
     * 定义一般的、与协议无关的 servlet。
     */
    public abstract class GenericServlet{
    	//返回包含指定初始化参数的值的 String,如果参数不存在,则返回 null
    	public String getInitParameter(String name){}
    	//以 String 对象的 Enumeration 的形式返回 servlet 的初始化参数的名称,如果 servlet 没有初始化参数,则返回一个空的 Enumeration
    	public java.util.Enumeration<E> getInitParameterNames(){}
    }
     
  3. HttpServlet
    HttpServlet:抽象类,此类在GenericServlet类的基础上提供了针对HTTP协议的增强的方法,其中service方法中判断请求的方式再去调用对应的doXXX方法。
    自己不要去覆盖service方法,而将代码卸载doXXX方法中,如果是get方式提交数据写在doGet中,post方式提交的数据写在doPost中
    /**
     * javax.servlet.http.HttpServlet
     * 提供将要被子类化以创建适用于 Web 站点的 HTTP servlet 的抽象类。HttpServlet 的子类至少必须重写一个do方法
     * 几乎没有理由重写 service 方法。service 通过将标准 HTTP 请求分发给每个 HTTP 请求类型的处理程序方法(上面列出的 doXXX 方法)来处理它们。
     * servlet 通常运行在多线程服务器上,因此应该意识到 servlet 必须处理并发请求并小心地同步对共享资源的访问。
     */
    public abstract class HttpServlet extends GenericServlet implements Serializable{
    	//共有7种do方法,分别为:doGet doPost doDelete doHead doOptions doTrace doPut
    	//由服务器调用(通过 service 方法),以允许 servlet 处理 GET 请求。 
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException{}
    	
    	//返回上次修改 HttpServletRequest 对象的时间
    	protected long getLastModified(HttpServletRequest req){}
    	
    	//将客户端请求分发给受保护的 service 方法。无需重写此方法。
    	public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException{}
    	
    	//接收来自 public service 方法的标准 HTTP 请求,并将它们分发给此类中定义的 doXXX 方法
    	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException{}
    }
     
  4. ServletConfig
    /**
     * javax.servlet.ServletConfig
     * servlet 容器使用的 servlet 配置对象,该对象在初始化期间将信息传递给 servlet。
     */
    public interface ServletConfig{
    	//返回包含指定初始化参数的值的 String,如果参数不存在,则返回 null。
    	public String getInitParameter(String name);
    	
    	//以 String 对象的 Enumeration 的形式返回 servlet 的初始化参数的名称,如果 servlet 没有初始化参数,则返回一个空的 Enumeration。
    	public java.util.Enumeration<E> getInitParameterNames();
    	
    	//返回对调用者在其中执行操作的 ServletContext 的引用。
    	public ServletContext getServletContext();
    	
    	//返回此 servlet 实例的名称
    	public String getServletName();	
    }
     
  5. ServletContext
    /**
     * javax.servlet.ServletContext
     * 定义一组方法,servlet 使用这些方法与其 servlet 容器进行通信,例如,获取文件的 MIME 类型、分发请求或写入日志文件。
     * 每个 Java 虚拟机的每个“Web 应用程序”都有一个上下文。
     */
    public interface ServletContext{
    		//将对象绑定到此 servlet 上下文中的给定属性名称,如果传递了 null 值,则效果将与调用 removeAttribute() 相同。
    		public void setAttribute(String name, Object object);
    		
    		//返回具有给定名称的 servlet 容器属性,如果不具有该名称的属性,则返回 null。
    		public Object getAttribute(String name);
    		
    		public void removeAttribute(String name);
    		
    		//返回包含此 servlet 上下文中可用属性的名称的 Enumeration
    		public java.util.Enumeration<E> getAttributeNames();
    		
    		//返回包含指定上下文范围初始化参数值的 String,如果参数不存在,则返回 null
    		public String getInitParameter(String name);
    		public java.util.Enumeration<E> getInitParameterNames();
    		
    		//返回 Web 应用程序的上下文路径。
    		public String getContextPath();
    		
    		//为给定虚拟路径返回包含实际路径的 String
    		public String getRealPath(String path);
    		
    		//返回一个 RequestDispatcher 对象,它充当位于给定路径上的资源的包装器。
    		public RequestDispatcher getRequestDispatcher(String path);
    		
    		//以 InputStream 对象的形式返回位于指定路径上的资源。
    		public java.io.InputStream getResourceAsStream(String path);
    		
    		//返回与此 ServletContext 相对应的 Web 应用程序的名称
    		public String getServletContextName();
    }
     
  6. HttpServletRequest
    /**
     * javax.servlet.http.HttpServletRequest
     * 扩展 javax.servlet.ServletRequest 接口,为 HTTP servlet 提供请求信息。 
     * servlet 容器创建 HttpServletRequest 对象,并将该对象作为参数传递给 servlet 的 service 方法(doGet、doPost,等等)。
     */
    public interface HttpServletRequest extends ServletRequest{
    		
    }
     
  7. HttpServletResponse
    /**
     * javax.servlet.http.HttpServletResponse
     * 扩展 ServletResponse 接口以提供特定于 HTTP 的发送响应功能。例如,该接口拥有访问 HTTP 头和 cookie 的方法。 
     * servlet 容器创建 HttpServletResponse 对象,并将该对象作为参数传递给 servlet 的 service 方法(doGet、doPost,等等)。
     */
    public interface HttpServletResponse extends ServletResponse{
    	//里面封装了很多的 状态码 字段,比如:下面的字段代表 200
    	static final int SC_OK
    	
    	//用给定名称和值添加响应头。此方法允许响应头有多个值。
    	public void addHeader(String name, String value);
    	//用给定名称和日期值添加响应头。该日期根据距历元时间的毫秒数指定。此方法允许响应头有多个值。
    	public void addDateHeader(String name, long date);
    	//用给定名称和整数值添加响应头。此方法允许响应头有多个值。 
    	public void addIntHeader(String name, int value);
    	
    	//用给定名称和值设置响应头。如果已经设置了头,则新值将重写以前的值
    	public void setHeader(String name, String value);
    	public void setDateHeader(String name, long date);
    	public void setIntHeader(String name, int value);
    	
    	//返回一个 boolean 值,指示是否已经设置指定的响应头。 
    	public boolean containsHeader(String name);
    	
    	//设置此响应的状态代码。
    	public void setStatus(int sc);
    	
    	//将指定 cookie 添加到响应。可多次调用此方法设置一个以上的 cookie。
    	public void addCookie(Cookie cookie);
    	
    	/**
    	 * 返回适用于在响应中编写二进制数据的 ServletOutputStream。servlet 容器不会编码二进制数据。 
    	 * 对 ServletOutputStream 调用 flush() 将提交响应。
    	 */
    	public ServletOutputStream getOutputStream() throws java.io.IOException;
    	
    	/**
    	 * 返回可将字符文本发送到客户端的 PrintWriter 对象。PrintWriter 使用 #getCharacterEncoding 返回的字符编码
    	 * 如果未知 getCharacterEncoding 中所述指定响应的字符编码(即该方法只返回默认值 ISO-8859-1),则 getWriter 会将字符编码更新到 ISO-8859-1。 
    	 * 对 PrintWriter 调用 flush() 将提交响应。 
    	 */
    	public java.io.PrintWriter getWriter() throws java.io.IOException;
    	
    	/**
    	 * 对指定 URL 进行编码,以便在 sendRedirect 方法中使用它,如果不需要编码,则返回未更改的 URL
    	 * 此方法的实现包含可以确定会话 ID 是否需要在 URL 中编码的逻辑。
    	 * 因为进行此确定的规则可能不同于用来确定是否对普通链接进行编码的规则,所以此方法与 encodeURL 方法是分开的。 
    	 * 发送到 HttpServletResponse.sendRedirect 方法的所有 URL 都应该通过此方法运行。否则,URL 重写不能用于不支持 cookie 的浏览器。 
    	 */ 
    	public String encodeRedirectURL(String url);
    	
    	/**
    	 * 通过将会话 ID 包含在指定 URL 中对该 URL 进行编码,如果不需要编码,则返回未更改的 URL。
    	 * 此方法的实现包含可以确定会话 ID 是否需要在 URL 中编码的逻辑。
    	 * 例如,如果浏览器支持 cookie,或者关闭了会话跟踪,则 URL 编码就不是必需的。
    	 * 通过将会话 ID 包含在指定 URL 中对该 URL 进行编码,如果不需要编码,则返回未更改的 URL。
    	 * 此方法的实现包含可以确定会话 ID 是否需要在 URL 中编码的逻辑。
    	 * 例如,如果浏览器支持 cookie,或者关闭了会话跟踪,则 URL 编码就不是必需的。 
    	 * 对于健壮的会话跟踪,servlet 发出的所有 URL 都应该通过此方法运行。
    	 * 否则,URL 重写不能用于不支持 cookie 的浏览器
    	 */
    	public String encodeURL(String url);
    	
    	/**
    	 * 使用指定重定向位置 URL 将临时重定向响应发送到客户端
    	 * 此方法可以接受相对 URL
    	 * 如果位置是相对的,没有前导 '/',则容器将相对于当前请求 URI 对其进行解释。
    	 * 如果位置是相对的,有一个前导 '/',则容器将相对于 servlet 容器根对其进行解释
    	 */
    	public void sendRedirect(String location) throws java.io.IOException;
    }