servlet学习

75 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,[点击查看活动详情]

创建Servlet步骤

  1. 搭建web工程环境

  2. 创建class MyFirstServlet实现javax.servlet.Servlet接口

  3. service():处理请求,做出响应

  4. 在web.xml中,注册MyFirstServlet

    <servlet>
        <servlet-name>MyFirstServlet</servlet-name>
        <!--标识类全类名,目的让服务器创建当前Servlet-->
        <servlet-class>com.atguigu.servlet.MyFirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyFirstServlet</servlet-name>
        <!--为servlet设置虚拟URL-->
        <url-pattern>/MyFirstServlet</url-pattern>
    </servlet-mapping>
    

2. Servlet工作原理

  • 请求MyFirstServlet
  • 在web.xml中【中】查找指定url
  • 通过映射到【全类名】
  • 执行MyFirstServlet中的相应方法

3. Servlet生命周期【面试题】

  • 构造器

    • 执行时机:第一次接收请求时,执行。
    • 执行次数:在整个生命周期中,只执行一次。【Servlet单例】
  • init()

    • 执行时机:第一次接收请求时,执行构造器之后,执行。
    • 执行次数:在整个生命周期中,只执行一次。
  • service()

    • 执行时机:每次接收请求,都会执行。
    • 执行次数:在整个生命周期中,只执行多次。
  • destroy()

    • 执行时机:在关闭服务器或重启服务器时,执行。
    • 执行次数:在整个生命周期中,只执行一次。

当Servlet第一次接收请求时,Servlet容器【web容器|web服务器】创建Servlet【执行构造器】,之后执行init()方法,进行初始化操作。最后执行service()方法,处理请求,做出响应。【以后再次接收请求,只执行service()方法】。当关闭或重启服务器时,执行destroy()方法,销毁Servlet。

  • Servlet生命周期_扩展

    • 如在web.xml中做如下配置

      <!--设置Servlet创建时机:启动服务器时创建Servlet
              index:设置Servlet被创建优先级【int类型且正整数,最小值1】
                  数值越小,优先级越高
      ​
      -->
      <load-on-startup>1</load-on-startup>
      
    • 此时,Servlet生命周期,如下调整

      • 构造执行时机为:启动服务后,执行
      • init()执行时机为:启动服务器,执行构造器后,执行。
      • 其他方法,无变化。

4. ServletConfig与ServletContext对象

4.1 ServletConfig

  • 概述:该对象相当于封装了Servlet配置信息,每个Servlet都有唯一对应的ServletConfig对象

  • 作用:

    • 获取当前Servlet名称:servletConfig.getServletName()

    • 获取ServletContext对象:servletConfig.getServletContext()

    • 获取当前Servlet初始化参数:servletConfig.getInitParameter()

      • web.xml中配置初始化参数

        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/dbname</param-value>
        </init-param>
        

4.2 ServletContext对象【Servlet上下文对象】

  • 概述:该对象代表当前web应用,每个web应用程序都有唯一对象的ServletContext对象。【该对象在启动服务时,被web服务器创建。】

  • 作用:

    1. 获取上下文路径【带/项目名,eg:/day05_tomcat_http_servlet】

      String contextPath = servletContext.getContextPath();
      
    2. 获取真实路径【d:/xxx(文件上传&文件下载)】

      String realPath = servletContext.getRealPath("/index.html");
      
    3. 获取上下文初始化参数

      <context-param>
          <param-name>stuName</param-name>
          <param-value>caixukun</param-value>
      </context-param>
      
      String stuName = servletContext.getInitParameter("stuName");
      
    4. 域对象【web域,共4个域对象】

5. 最终创建Servlet方式

之前创建Servlet方式不足

  1. 实现Servlet接口的实现类中,方法比较冗余【只需要service()】
  2. 没有提示注册Servlet
  • EndServlet : HttpServlet : GenericServlet : Servlet

  • GenericServlet作用

    1. 提供获取ServletConfig和ServletContext对象方法

      • getServletConfig()
      • getServletContext()
    2. 将service()方法,抽象化

      @Override
      public abstract void service(ServletRequest req, ServletResponse res)
              throws ServletException, IOException;
      
  • HttpServlet作用

    1. override service()【重写service()】

      @Override
      public void service(ServletRequest req, ServletResponse res)
          throws ServletException, IOException {
      ​
          HttpServletRequest  request;
          HttpServletResponse response;
      ​
          try {
              request = (HttpServletRequest) req;
              response = (HttpServletResponse) res;
          } catch (ClassCastException e) {
              throw new ServletException("non-HTTP request or response");
          }
          service(request, response);
      }
      
    2. overload service()【重载service()】

      protected void service(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException, IOException {
      ​
          String method = req.getMethod();
          if("GET".eq(method)){
              doGet(req,resp);
          }else if("POST".eq(method)){
              doPost(req,resp);
          }else if(){
              //PUT  |  DELETE
              
          }...
          
      }
      

6. request【请求】与response【响应】对象

6.1 request

  • 类型:HttpServletRequest

  • 概述:request相当于浏览器向服务器发送请求报文,封装到request对象。该对象由服务器创建,并以参数的形式发送到service()方法中,最终传入doGet()或doPost()方法中。

  • 作用:

    1. 获取请求参数

      什么参数

      1. ?后面内容:

      2. 表单中参数:name属性值

        <form action="EndServlet" method="post">
            用户名:<input id="username" type="text" name="username" value="" /><br>
            密码:<input id="pwd" type="password" name="password" value="123"/><br>
            <input id="btnSub" type="submit" value="登录" >
        </form>
        
      • request.getParameter():获取单个请求参数
      • request.getParameterValues():获取多个请求参数
    2. 获取请求头中的信息

      • request.getHeader("User-Agent|Cookie|Referer")
    3. 获取URL信息【http://localhost:8080/day06_servlet/

      • 获取协议:request.getScheme()
      • 获取服务器名称:request.getServerName()
      • 获取服务器端口:request.getServerPort()
      • 获取上下文路径【带/项目名】:request.getContextPath()
    4. 转发请求【路径跳转】

      //1. 获取转发器
      RequestDispatcher requestDispatcher = request.getRequestDispatcher("login_success.html");
      //2. 执行转发
      requestDispatcher.forward(request,response);
      
    5. 域对象【共四个,ServletContext|request】

6.2 response

  • 类型:HttpServletResponse

  • 概述:response相当于服务器向浏览器做出响应报文,封装到response对象。该对象由服务器创建,并以参数的形式发送到service()方法中,最终传入doGet()或doPost()方法中。

  • 作用:

    1. 获取响应流,响应数据

      • PrintWriter writer = response.getWriter();
      • writer.writer();|writer.print()
    2. 设置响应头

      • response.setHeader("Content-Type","text/html;charset=UTF-8");
    3. 重定向【路径跳转】

      • response.sendRedirect("url");