Servlet 学习笔记

Servlet 概念

Servlet( Server Applet ),全称Java Servlet是运行在Web服务器或应用服务器上的程序,是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层

个人理解Servlet就是作为客户端界面和服务器端中间层的处理程序。

作用主要是
  1. 接受用户端(浏览器)的Request请求数据
  2. 处理请求并生成结果,可能需要访问数据库。
  3. 返回Response响应到用户端。

Servlet生命周期

1.init()方法,Servlet 通过调用 init () 方法进行初始化。

init()方法只在第一次创建Servlet时被调用一次,在后续每次用户请求时不再调用。

2. service()方法,Servlet 调用 service() 方法来处理客户端的请求。

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

doGet() 和 doPost() 方法是每次服务请求中最常用的方法。

2.1 doGet()方法

GET 请求来自于:1. 一个 URL 的正常请求,2. 一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

GET调用会在URL里显示正传送给SERVLET的数据,这在系统的安全方面可能带来一些问题,比如用户登录,表单里的用户名和密码需要发送到服务器端, 若使用Get调用,就会在浏览器的URL中显示用户名和密码。

2.2 doPost()方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

Post通过HTTP post机制,将表单内的信息放在Form中传递给服务器。好处是可以隐藏传送给服务器的任何数据。Post适合发送大量的数据

3. destroy()方法,Servlet 通过调用 destroy() 方法终止(结束)。

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。
destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

4. 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

实现Servlet接口的三种方式

1. Servlet接口

Servlet 类提供了五个方法,其中三个生命周期方法和两个普通方法。
但是通过实现Servlet接口来编写Servlet必须要实现接口中定义的所有方法,还需要自己手动的维护ServletConfig这个对象的引用,所以基本不会用这种方法实现Servlet。

以下是Servlet接口代码:

package javax.servlet;

import java.io.IOException;

public interface Servlet {
	 //生命周期方法:当Servlet第一次被创建对象时执行该方法,该方法在整个生命周期中只执行一次
    void init(ServletConfig var1) throws ServletException;
        
	//生命周期方法:对客户端响应的方法,该方法会被执行多次,每次请求该servlet都会执行该方法
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    
	//生命周期方法:当Servlet被销毁时执行该方法
    void destroy();
    
    //两个普通方法
	ServletConfig getServletConfig();
	
    String getServletInfo();
    
	
}

1.1 ServletRequest接口
public interface ServletRequest {
  
    int getContentLength();//返回请求主体的字节数
 
    String getContentType();//返回主体的MIME类型
 
    String getParameter(String var1);//返回请求参数的值
 
}

getParameter是在ServletRequest中最常用的方法,可用于获取查询字符串的值。

例:URL = "http://localhost:8080/ProjectName/FormName?username=root&password=123”
利用**getParameter(“username”)**即可得到username的值为root

1.2 ServletResponse接口
public interface ServletResponse {
    String getCharacterEncoding();
 
    String getContentType();
 
    ServletOutputStream getOutputStream() throws IOException;
 
    PrintWriter getWriter() throws IOException;
 
    void setCharacterEncoding(String var1);
 
    void setContentLength(int var1);
 
    void setContentType(String var1);
 
    void setBufferSize(int var1);
 
    int getBufferSize();
 
    void flushBuffer() throws IOException;
 
    void resetBuffer();
 
    boolean isCommitted();
 
    void reset();
 
    void setLocale(Locale var1);
 
    Locale getLocale();
}

其中getWriter方法,它返回了一个可以向客户端发送文本的的Java.io.PrintWriter对象。

在发送HTML之前,应该先调用setContentType(“text/html;charset=UTF-8”)方法

  • 将“text/html”作为一个参数传入,告诉浏览器响应的内容类型为HTML,需要以HTML的方法解释响应内容而不是普通的文本
  • 加上“charset=UTF-8”改变响应的编码方式以防止发生中文乱码现象。

2. GenericServlet类

GenericServlet 是一个抽象类,为Servlet接口中的所有方法提供了默认的实现。通过继承该类,实现Servlet只需要更改自己的需要的部分。

在 GenericServlet 中,主要完成了以下任务:

  • 将 init() 中的 ServletConfig 参数赋给了一个内部的ServletConfig引用从而来保存ServletConfig对象,可以由 getServletConfig()方法获得;
  • 为Servlet 所有方法提供默认实现;
  • 可以直接调用 ServletConfig 中的方法;

如果继承GenericServlet类的话,我们必须重写 service() 方法来对处理请求。

GenericServlet类的基本结构

abstract class GenericServlet implements Servlet,ServletConfig{
 
   //GenericServlet通过将ServletConfig赋给类级变量
   private ServletConfig Config;
 
   public void init(ServletConfig servletConfig) throws ServletException {

      this.servletConfig=servletConfig;

      /*自定义不带参数的init()的原因是?见下方*/
      this.init();
   }
   
   //自定义的init()方法,可以由子类覆盖  
   public void init(){
  
   }
 
   //实现service()空方法,并且声明为抽象方法,强制子类必须实现service()方法 
   public abstract void service(ServletRequest request,ServletResponse response) 
     throws ServletException,java.io.IOException{
   }
 
   //实现空的destroy方法
   public void destroy(){ }
}

自定义不带参数init()方法的原因:
如果在类中覆盖了GenericServlet抽象类的init(ServletConfig servletConfig)方法,那么程序员就必须手动的去维护ServletConfig对象了,这样会给程序员带来很大的麻烦。

这个不带参数的 init() 方法,是在ServletConfig对象被赋给ServletConfig引用后,由第一个带参数的init(ServletConfig servletconfig)方法调用的,那么这意味着,当程序员如果需要覆盖这个GenericServlet的初始化方法,则只需要覆盖那个不带参数的init( )方法就好了,此时,servletConfig对象仍然有GenericServlet保存着。

3. HttpServlet类

HttpServlet 也是一个抽象类,它进一步继承并封装了 GenericServlet,使得使用更加简单方便,由于是扩展了 Http 的内容,所以还需要使用 HttpServletRequest 和 HttpServletResponse,这两个类分别是 ServletRequest 和 ServletResponse 的子类。

开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。

abstract class HttpServlet extends GenericServlet{
 
   //HttpServlet类中的service()方法
   protected void service(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse){
        //该方法通过httpServletRequest.getMethod()判断请求类型,
        //并调用以下方法之一:doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete
        //其中doGet() doPost()是最常用的
        //所以,通过继承HttpServlet类,不再需要覆盖service方法,只需要覆盖doGet或者doPost就好了。
        //以下具体实现省略
   }
 
   //必须实现父类GenericServlet的service()方法
   public void service(ServletRequest servletRequest,ServletResponse servletResponse){
      HttpServletRequest request;
      HttpServletResponse response;
      try{
         request=(HttpServletRequest)servletRequest;
         response=(HttpServletResponse)servletResponse;
      }catch(ClassCastException){
         throw new ServletException("non-http request or response");
      }
      //调用自己的service()方法
      this.service(request,response);
   }
}

HttpServlet有两个特性是GenericServlet所不具备的:

  1. 不用覆盖service方法,而是覆盖doGet()或者doPost()方法。在少数情况,还会覆盖其他的5个方法。
  2. 使用的是HttpServletRequest和HttpServletResponse对象。

3.1 HttpServletRequest接口

HttpServletRequest扩展于ServletRequest接口,并添加了几个方法。
因为Request代表请求,所以我们可以通过该对象分别获得HTTP请求的请求行,请求头和请求体。

String getContextPath();//返回请求上下文的请求URI部分

Cookie[] getCookies();//返回一个cookie对象数组

String getHeader(String var1);//返回指定HTTP标题的值

String getMethod();//返回生成这个请求HTTP的方法名称

String getQueryString();//返回以GET方式提交,URL地址后的参数字符串

HttpSession getSession();//返回与这个请求相关的会话对象	

3.2 HttpServletResponse接口

HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。
由于HTTP请求消息分为状态行,响应消息头,响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。

void addCookie(Cookie var1);//给这个响应添加一个cookie

void addHeader(String var1, String var2);//给这个请求添加一个响应头

void sendRedirect(String var1) throws IOException;//发送一条响应码,讲浏览器跳转到指定的位置

void setStatus(int var1);//设置响应行的状态码


参考资料:
菜鸟教程Servlet
JavaWeb——Servlet(全网最详细教程包括Servlet源码分析)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值