JavaWeb三大组件-Servlet(一)

Servlet ①

1. 概念

什么是Servlet? 是JavaEE规范之一,规范就是接口。是JavaWeb三大组件之一。

是运行在Web服务器上的一个java小程序,可以 接受客户端发送来的请求,并响应数据给客户端

三大组件:Servlet程序,Filter过滤器,Listener监听器。


2. 实现Servlet

  • 创建一个动态的Web工程

  • 编写一个类去实现 Servlet 接口

  • 实现service()方法,处理请求并响应数据

  • web.xml去配置servlet程序的访问地址

HelloServlet.java

public class HelloServlet implements Servlet {

    public HelloServlet() {System.out.println("1.构造器方法!");}

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2.init方法");
    }

    /**
     * service方法是专门用来处理请求和响应的
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("3.service  ->  Hello Servlet 被访问了");
        
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod(); //获取请求方式  POST/GET
        if ("GET".equals(method)) {
            // 业务逻辑
            doGet();
        } else if ("POST".equals(method)) {
			// 业务逻辑
            doPost();
        }
    }

    public void doGet() {System.out.println("get请求");}

    public void doPost() {System.out.println("post请求");}

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

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

    @Override
    public void destroy() {System.out.println("4.destroy方法");}
}

web.xml配置文件

  • <servlet>:给Tomcat服务器配置servlet程序

    • <servlet-name>:给servlet程序起一个别名,一般是类名

    • <servlet-class>:指定servlet程序的全类名,加上包名

  • <servlet-mapping>:给servlet程序配置访问地址,就是在浏览器里面输入什么才执行servlet程序

    • <servlet-name> :和上面那个意义不同,作用:告诉服务器当前配置的地址给那个servlet程序使用
    • <url-pattern>:配置访问地址 (注意要以斜杠开头)
<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.sutong.service.HelloServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>HelloServlet</servlet-name>
    <!-- url-pattern标签:配置访问地址
         /hello  	
		'/':在服务器解析的时候,表示地址为 http://ip:port/工程路径  (工程路径是自己配置的, 我的是/dynamicobject)
        'hello':代表地址为: http://ip:port/工程路径/hello
         当启动tomcat时,idea会帮我们自动访问http://localhost:8080/dynamicobject/这个url,
         当我们在后面加上hello时,那个Servlet程序的service方法就会被调用到了,
		 hello只是这Servlet程序的代名词而已。
         -->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

3. Servlet生命周期

  • Ⅰ执行 Servlet 构造器方法

  • Ⅱ 执行 init 初始化方法

    前两个只是在第一次访问的时候创建Servlet程序会调用,刷新网页,重新进入网页都不会被调用了

  • Ⅲ 执行service 方法

    每次访问都会被调用,刷新/重新进入

  • Ⅳ 执行 destroy 销毁方法

    在web工程停止的时候才会执行


4. 另一种实现Servlet

  1. 以前我们是实现 Servlet接口,实现的service方法:

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("3.service  ->  Hello Servlet 被访问了");
    
        // ServletRequest 这个类不可以直接使用来获得提交方式,
        // 它的子类HttpServletRequest有方法可以用,即getMethod()
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod(); //获取请求方式  POST/GET
        if ("GET".equals(method)) {
            // 这里面的代码可能很多,包装成方法
            doGet(); // 自己写的
        } else if ("POST".equals(method)) {
            // 这里面的代码可能很多
            doPost();
        }
    }
    

  2. 在实际中我们很少自己直接实现 Servlet 接口,我们可以直接继承/扩展 Servlet接口的实现类 ⭐⭐

    一般都是继承 HttpServlet 类来实现 Servlet 程序 (HttpServlet实现了service()方法,实现了请求的分发处理)

    • Ⅰ 编写一个类去继承 HttpServlet
    • Ⅱ 根据业务需求重写 doGet() / doPost() 方法
    • Ⅲ 去web.xml 配置 Servlet程序的访问地址
    public class HelloServlet02 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
            System.out.println("get请求");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
            System.out.println("post请求");
        }
    }
    // 最后记得配置 web.xml文件,和上面一样
    

  3. 使用 IDEA 创建 Servlet 程序

    选择包名 | 右键 | New | Create New Servlet

    记得把下面的Create Java EE 6 annotated class去掉勾选,勾选上会使用高版本的注解功能,就不是使用web.xml文件配置了,创建完直接配置 servlet-mapping即可


5. Servlet的继承体系

javax.Servlet接口

只是负责定义Servlet程序的访问规范

​ ↓ (实现 )

GenericServlet抽象类

实现了Servlet接口,做了很多空实现。持有ServletConfig类的一个引用,并对ServletConfig的使用做了一些方法)

​ ↓ (继承)

HttpServlet抽象类

重点实现了service()方法,实现了请求的分发处理,先是req.getMethod(),根据请求发送调用对应方法,如果我们不重写doGet(),doPost() 方法,不重写就调用本类的话会抛异常method_get_not_supported/method_post_not_supported,即不支持Get/Post请求

​ ↓ (继承)

我们自己写的Servlet程序

根据业务的业务需要重写doGet() / doPost()方法,重写后就是支持了

在这里插入图片描述


6. ServletConfig类

从类名上看是 Servlet 程序的配置信息类。

作用:

  • 获取 ServletContext 对象 (下面讲)

  • 获取Servlet程序的别名,即web.xml里面的,servlet标签里servlet-name标签里的值

  • 获取初始化参数 init-param,即web.xml里面的,servlet标签里的init-param标签的值

    怎么配置servlet初始化参数??,形式:参数名-值 (如下)

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.sutong.service.HelloServlet</servlet-class>
    
        <!-- init-param标签:初始化参数,里面类似键值对,可以多对-->
        <init-param>
            <!-- 参数名-->
            <param-name>username</param-name>
            <!-- 参数值-->
            <param-value>root</param-value>
        </init-param>
    
        <!-- 例子-->
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/bjpowernode</param-value>
        </init-param>
    </servlet>
    


    Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。

    Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时就创建一个对应的 ServletConfig 对象,即一个Servlet程序对应一个ServletConfig

    (所以:ServletConfig 对象只能获取自己 servlet 标签里面的初始化参数)

    ⭐使用:

    1.实现Servlet 接口中的使用

    // 1.HelloServlet类 implements Servlet 
    // 实现Servlet接口init方法会ServletConfig参数
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("HelloServlet程序的别名是: " 
                           + servletConfig.getServletName());
        System.out.println("初始化参数username = " 
                           + servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url = " 
                           + servletConfig.getInitParameter("url"));
        System.out.println(servletConfig.getServletContext()); 
    }
    

    2.继承HttpServlet类中的使用

    HttpServlet的父类GenericServlet包装了ServletConfig的使用

    // 2.HelloServlet02类 extends HttpServlet
    // 直接使用,不需要.了,例如: getServletName()
    public void test01() {
        System.out.println(getServletName());
        System.out.println(getInitParameter("username")); 
        // 这个获取不到HelloServlet程序的初始化参数
        // 因为HelloServlet02程序的ServletConfig对象和HelloServlet程序的ServletConfig对象不是一个
    }
    
    // 注意: 如果我们想要重写init方法,第一句一定要加上super.init(config),否则直接用的话就会空指针异常
    //		 因为GenericServlet类(HttpServlet类继承了GenericServlet类)底层,
    //       在init方法里面对ServletConfig对象的使用进行了保存/封装,
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        System.out.println("自己重写了init方法...");
    }
    

7. ServletContext对象

  1. ServletContext 是一个接口,它表示 Servlet 上下文对象

  2. 一 个web工程,只会有一个ServletContext 对象实例

  3. ServletContext 对象是一个域对象

    域对象:是可以像Map 一样存取数据的对象,这里的域指的是存取数据的操作范围 - 即整个Web工程

    存数据取数据删除数据
    Mapput()get()remove()
    域对象setAttribute()getAttribute()removeAttribute()

ServletContext作用:

  • 获取 web.xml 中配置的上下文参数 context-param
  • 获取当前的工程路径。 格式: /工程路径
  • 获取工程部署后在服务器上的绝对路径
  • 像Map一样存储数据
<!-- 上下文参数,注意是配置在servlet标签外面!!,
	  因为一个工程只有一个ServletContext对象,属于整个web工程-->
<context-param>
    <!-- 键值对,K-V,可以多组-->
    <param-name>name</param-name>
    <param-value>context</param-value>
</context-param>

使用:

public class HelloServlet02 extends HttpServlet {
    // ...
    
    public void test02() {
        ServletContext context = getServletContext();

        // getInitParameter()获得context-param标签里面的内容
        // 注意这个方法名字虽然和ServletConfig类中的一样,但作用不同
        System.out.println("name对应的值为:" + context.getInitParameter("name")); // context
        System.out.println("当前工程路径:" + context.getContextPath());  //  /dynamicobject 

        // D:\JAVA练习\JavaWeb\dynamicobject\out\artifacts\dynamicobject_war_exploded\
        System.out.println("工程部署的绝对路径:" + context.getRealPath("/"));
        // D:\JAVA练习\JavaWeb\dynamicobject\out\artifacts\dynamicobject_war_exploded\css\1.css
        System.out.println("工程中1.css的绝对路径" + context.getRealPath("/css/1.css"));

        // context.getRealPath("/"); // 即文件部署路径
        // 而idea中的路径,是文件真实路径
        String contentType = context.getMimeType("path"); // 传入文件路径,可以得到对应的是Mime类型
    }


    // 注意ServletContext对象整个工程只有一个,在web工程部署启动时创建,在web工程停止的时候销毁
    public void test03() {
        ServletContext context = getServletContext();
        context.setAttribute("key1", "value1");
        System.out.println("Context中获取域数据key1 = " + context.getAttribute("key1"));
    }
}

工程部署的绝对路径时,为什么传入一个斜杠?

因为 / 会被服务器解析为 http://ip:port/工程路径 ,这个路径对应我们在idea上写的工程中的web文件夹,部署是本质是把web目录的副本和src编译成的字节码文件放一起,然后在tomcat/conf/Catalina/localhost 在这个目录建立一个xml文件,来部署的。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值