• 前面是通过实现 Servlet接口来完成servlet程序的编写,但是开发中一般不这么用

    HttpServlet

    类关系图

    image.png

  • httpServlet 相当于在servelt基础上进行了扩写,提供了一系列的方法。

    继承HttpServlet来编写Servlet�

  • 继承HttpServlet 并根据业务重写doGet,doPost方法 ```java package com.addicated.servlet_02;

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

public class servlet02 extends HttpServlet {

  1. /*
  2. * @Author shihu
  3. * @Description //TODO doGet 在get请求的时候调用
  4. * @Date 10:52 下午 2021/9/9
  5. * @Param [req, resp]
  6. * @return void
  7. **/
  8. @Override
  9. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  10. System.out.println("servlet 02 中的 get请求被调用");
  11. }
  12. /*
  13. * @Author shihu
  14. * @Description //TODO 同理 post请求的时候进行调用
  15. * @Date 10:52 下午 2021/9/9
  16. * @Param [req, resp]
  17. * @return void
  18. **/
  19. @Override
  20. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  21. System.out.println("servlet 02 中的 post 请求被调用");
  22. }

}

  1. <a name="MQQnJ"></a>
  2. ## 为什么有doGet,doPost
  3. - 来看一段代码
  4. ```java
  5. public class servlet_01 implements Servlet {
  6. @Override
  7. public void init(ServletConfig servletConfig) throws ServletException {
  8. // 获取servletname
  9. System.out.println(servletConfig.getServletName()); // 用来获取该servlet程序在web.xml 中配置的别名
  10. // 获取web.xml 中对一个servlet程序配置的初始化变量
  11. System.out.println(servletConfig.getInitParameter("url"));
  12. // 获取servletcontext对象
  13. ServletContext servletContext = servletConfig.getServletContext();
  14. }
  15. @Override
  16. public ServletConfig getServletConfig() {
  17. return null;
  18. }
  19. /*
  20. * @Author shihu
  21. * @Description //TODO 专门用来处理请求和响应
  22. * @Date 10:01 下午 2021/9/9
  23. * @Param [servletRequest, servletResponse]
  24. * @return void
  25. **/
  26. @Override
  27. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  28. // 当前存在问题,就是所有请求都会走service
  29. // servletRequest 的父类中有getMethod方法 用来得到前端页面传来请求的类型
  30. // 但是其本身并没有getMethod方法,这时候使用多太特性,向下转型,父类转子类
  31. HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
  32. // 调用父类中的getMethod方法拿到请求类型和
  33. String method = httpServletRequest.getMethod();
  34. // 之后通过对method判断进行分别调用
  35. if ("GET".equals(method)){
  36. //get 代码
  37. doGet();
  38. }else if ("POST".equals(method)){
  39. // post 代码
  40. doPost();
  41. }
  42. // 但是上面这样写代码 如果请求中的逻辑很多的话,不方便维护。所以封装出来doGet doPost
  43. System.out.println("hello addicated this is a servlet");
  44. }
  • 一开始我们进行实现servlet接口的时候,有一个service方法,service方法是用来处理各种请求的,但是在servlet中并没有对服务进行分发,换句话说,也就是不管get 或者是post patch delete请求,都会发到service。
  • 然后只能是通过方法名来进行判断进行请求分发,因此httpservlet中,专门为此进行了请求分发的方法支持。见下图

image.png

IDEA 创建servlet

  • idea对servlet有特化支持

image.pngimage.png

  • annotedClass 最好不要勾选,勾选之后会自动添加注解,在web.xml中会看不到servlet程序的相关注册
  • 此方法创建的servlet程序在web.xml中会自动完成注册,但是mapping并不会自动完成,仍然需要手动,

      <servlet-mapping>
          <servlet-name>ContextServlet</servlet-name>
          <url-pattern>/ContextServlet</url-pattern>
      </servlet-mapping>
    

    ServletConfig 对象

  • 从类名可得知,这是一个servlet程序的配置信息类

  • servlet程序哈servletconfig对象都是tomcat负责创建,我们负责使用
    servlet程序默认是第一次访问的时候创建,servletConfig 是每个servlet程序创建时,就创建一个对应的servletConfig对象 ,这句话的隐含意义其实是
    一个servletconfig对象,对应的是一个servlet类,
  • a serveltConfig类的三大作用
    1 ,可以获取servlet程序的别名 servlet-name的值
    servletConfig.getServletName()
    2 ,获取初始化参数 init-param
    servletCongfig.getInitParam()
    3 ,获取 servletcontext 对象 ```java public class servlet_01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
    // 获取servletname
    System.out.println(servletConfig.getServletName());  // 用来获取该servlet程序在web.xml 中配置的别名
    // 获取web.xml 中对一个servlet程序配置的初始化变量
    System.out.println(servletConfig.getInitParameter("url"));
    // 获取servletcontext对象
    ServletContext servletContext = servletConfig.getServletContext();
}
<a name="qmyw0"></a>
## 继承HttpServlet类创建的类获取Config对象则更为简便
```java
   public ServletConfig getServletConfig() {
         return this.config;
     }
     # 上面这个方法实际上是 GenericServlet 类下方法 ,因httpServlet继承了该类,所以可以直接调用
     另外 ,如果在继承httpservlet之后,重写掉了 init方法,则一定要调用父类的init方法,
     否则则获取不到servletConfig对象,
     原理为
        子类重写父类方法会完全代替掉父类的方法,导致没有对serveltConfig进行初始化,引起npe
        genericServlet 下的init方法
           public void init(ServletConfig config) throws ServletException {
                this.config = config;
                this.init();
            }

image.png

ServletContext对象

  • 1 是一个接口,表示servlet上下文对象
    2 一个工程 只有一个servletContext对象实例
    3 servletContext 对象是一个域对象
    4 servletContext 是在 web工程部署启动的时候创建,在web工程停止的时候销毁
  • 什么是域对象?

    可以像map一样存储数据的对象<br />      这里的域 指的是存储数据的操作范围<br />      存数据            | 取数据       | 删除数据<br />map    put             |  get         | remove<br />域对象  setAttribute     | getAttribute  |removeAttribute
    

    context对象的作用

    1 获取web.xml 中配置的上下文参数 context-param
    2 获取当前工程路径 格式:/工程路径
    3 获取工程部署后在服务器硬盘上的绝对路径
    4 像map一样存取数据 ```java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      ServletConfig servletConfig = getServletConfig();
      ServletContext servletContext = servletConfig.getServletContext();
      //        1 获取web.xml 中配置的上下文参数 context-param
      Object username = servletContext.getInitParameter("username");
      System.out.println(username);
      //        2 获取当前工程路径 格式:/工程路径
      String contextPath = servletContext.getContextPath();
      System.out.println(contextPath);
      //        3 获取工程部署后在服务器硬盘上的绝对路径
      String realPath = servletContext.getRealPath("/");
      System.out.println(realPath);
    

    } — web.xml

<context-param>
    <param-name>username</param-name>
    <param-value>context</param-value>
</context-param>

```