Servlet

一、什么是Servlet?

Servlet是在服务器上运行的小程序,也就是一个Java类,但比较特殊,不需要new,自动就可以运行。也有创建、垃圾回收和销毁过程。Servlet是JavaWeb的三大组件之一(Servlet、Filter、Listener),它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:

  • 接收请求数据;
  • 处理请求;
  • 完成响应。

例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理。Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servlet接口。Servlet对象驻留在服务器内存中。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

 

1、编写一个Servlet程序

       写一个java类,实现Servlet接口,实现了该接口,该类就不是普通的类了。

Servlet不再是烦恼 随笔 第1张

 

 

package servletdemo;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/servlet")
public class servletDemo implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Hello Servlet");

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

  

部署应用到tomcat服务器。

Servlet不再是烦恼 随笔 第2张

 

Servlet不再是烦恼 随笔 第3张

 

 测试:http://localhost:8080/MyMavenHome_war/servlet  在IDEA控制台输出 hello servlet,初体验成功!

Servlet不再是烦恼 随笔 第4张

 

 

二、Servlet的生命周期

实例化-->初始化-->服务->销毁

      出生:(实例化-->初始化)第一次访问Servlet就出生了(默认情况下)。(说明我可以改变它的出生时机,比如让servlet在服务器启动时就创建)

      活着:(服务)应用活着,servlet就活着。(Servlet是单实例,其中的service()方法是多线程的。)

      死亡:(销毁)应用被卸载了,servlet就销毁了。

package servletdemo;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/servlet")
public class servletDemo implements Servlet {

    //Servlet生命周期的方法:实例化方法(new 对象,无参构造)
    //在servlet第一次被访问时调用
    public servletDemo() {
        System.out.println("*******servletDemo执行了");
    }

    //Servlet生命周期的方法:初始化方法
    //在servlet第一次被访问时调用
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("*********init执行了");

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    //Servlet生命周期的方法:服务方法
    //每次访问时都会被调用
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("*******service执行了");
    }


    @Override
    public String getServletInfo() {
        return null;
    }

    //Servlet生命周期的方法:销毁方法
    //当应用被卸载时调用
    @Override
    public void destroy() {
        System.out.println("*******destroy执行了");
    }
}

  

Servlet不再是烦恼 随笔 第5张

 

三、实现Servlet的方式

实现Servlet有三种方式:

  •  实现javax.servlet.Servlet接口;
  • 继承javax.servlet.GenericServlet类;
  • 继承javax.servlet.http.HttpServlet类;

自定义Servlet类的继承结构,如下图:

Servlet不再是烦恼 随笔 第6张

 

 

 

 1、实现javax.servlet.Servlet接口(参见:编写一个servlet程序)

 2、继承javax.servlet.GenericServlet类(抽象类)(适配器模式)

    GenericServlet类(抽象类)已经实现了Servlet接口,我们用哪个方法就调用哪方法,不用再去全部实现了,哪怕是全部的空实现。

Servlet不再是烦恼 随笔 第7张

 

 

3、继承javax.servlet.http.HttpServlet(抽象类)(模板方法设计模式)

    模板是HttpServlet类中的私有service()方法(开发中常用方式)     HttpServlet类(抽象类)继承了GenericServlet类(抽象类)  
package servletdemo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/servlet1")
public class servlet extends HttpServlet {
    //具体实现1
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("******MydoGet*******");
        System.out.println(req.getRemoteAddr());
    }

    //具体实现2
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("*******MydoPost******");
    }

}

  Servlet不再是烦恼 随笔 第8张

 

 

 

     注意: 不要重写父类Httpservlet中的service()方法,因为该方法会调用Httpservlet中私有的service()方法,

          而该私有的service()方法会根据不同的提交表单的方式,会调用相应的doGet()、doPost()、doHead()等方法。

          我们去重写这些不同的表单提交的方法即可。

       Servlet(接口) --> GenericServlet(抽象类/适配器) --> HttpServlet(功能抽象类/模板) --> (继承HttpServlet,具体实现类,重写其功能)  

四、Servlet的线程安全

    整个生命周期是单实例,每次访问时为多线程。

      一:单实例变成多实例,但过时了,因为耗费资源多,服务器压力大。

      二:加线程锁,但数据会重复出现(没有同步机制),且运行效率低。

      三:解决线程安全问题的最佳办法:不要写全局变量,而写局部变量(即改变变量的作用域)。  

五、ServletContext对象(重要)

    ServletContext: 代表的是整个应用。一个应用只有一个ServletContext对象。单实例。

    作用:

  1、作为域对象使用

    即在一定范围内(当前应用),使多个Servlet通过ServletContext对象实现数据共享。因为当前应用中会有很多java类,很多Servlet。

    常用方法:

      public void setAttribute(String name, Object value) // ServletContext对象的map集合中添加数据

      public Object getAttribute(String name)  // ServletContext对象的map集合中取数据

      public void rmoveAttribute(String name)  // 根据name移除数据   Servlet不再是烦恼 随笔 第9张

Servlet不再是烦恼 随笔 第10张

 

Servlet不再是烦恼 随笔 第11张

2获取全局配置信息:

 方法:public String getInitParamenter(String name) // 根据配置文件中的key得到value

 

3、读取简单的资源文件(即只包含key=value的形式):

    方法:public String getRealPath(String path)// 根据资源名称得到资源的绝对路径,可以得到当前应用任何位置的任何资源。

 4、实现Servlet的请求转发:

    方法:public RequestDispatcher getRequestDispatcher(String path) //参数表示要跳转到哪去

Servlet不再是烦恼 随笔 第12张

Servlet不再是烦恼 随笔 第13张

 

Servlet不再是烦恼 随笔 第14张

 

5、依赖和关联

      如果是通过参数传过来的对象,就叫依赖。

     通过方法得到的对象,就叫关联。

Servlet不再是烦恼 随笔 第15张

 

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄