Servlet



什么是servlet
Servlet在开发动态WEB工程中,得到广泛的应用,掌握好Servlet非常重要了,Servlet(基石)是SpringMVC的基础

servlet(java 服务器小程序),它的特点:

  1. 他是由服务器端调用和执行的(一句话:是Tomcat解析和执行)
  2. 他是用java语言编写的,本质就是Java类
  3. 他是按照Servlet规范开发的(除了tomcat->Servlet weblogic->Servlet)
  4. 功能强大,可以完成几乎所有的网站功能Ⅰ

 
Servlet开发方式说明
servlet3.0前使用web.xml , servlet3.0版本以后(包括3.0)支持注解,同时支持web.xml配置

 
Servlet在JavaWeb项目中位置
在这里插入图片描述
当浏览器请求的是动态资源时(数据库中的数据),tomcat就会访问servlet,servlet会调用Java程序,去将数据库中的数据取出

当浏览器请求的是静态资源时,tomcat就会静态资源直接返回给浏览器
 
tomcat有两个作用

  1. 作为servlet的容器
  2. 充当Web服务

 

浏览器调用Servlet流程分析
浏览器将HTTP请求(http://localhost:8080/servlet/HelloServlet)发送给Tomcat,Tomcat得到HTTP请求
 
如果是第一次请求(Tomcat):

  1. tomcat会去查询web.xml(已解析出要访问的web应用:servlet)
  2. 看看请求的资源 /HelloServlet,在web.xml 中 url-pattern 是否配置
  3. 如果找到url-pattern,,就会得到servlet-name:HelloServlet(底层有个HashMap<url-pattern,servletName>)
  4. tomcat中维护了一个大的HashMap<servletName,Servlet>,利用servlet-name,查询该HashMap,看看有没有这个Servlet实例
  5. 如果没有查询到该Serletname 对应的 servlet
  6. 就根据servlet-name 去得到serlvet-class:类的全路径(在web.xml文件中,这两个是配置在<servlet></servlet>中)
  7. 使用反射技术,将servlet实例化 -> 执行init()方法 -> 执行service()方法,并放入到tomcat维护的HashMap<servletName,Servlet>

 
如果是第二次(以后)请求(Tomcat)

  1. 查询web.xml
  2. 看看请求的资源/helloServlet,在web.xml配置url-pattern
  3. 如果找到url-pattern.就会得到servlet-name:HelloServlet
  4. tomcat中维护了一个大的HashMap<servletName,Servlet>,利用servlet-name,查询该HashMap,看看有没有这个Servlet实例
  5. 如果查询到,就直接调用该Servlet的service
  6. 结果显示
    在这里插入图片描述

 
Servlet生命周期
初始化阶段
Servlet容器(比如: Tomcat)加载Servlet,加载完成后,Servlet容器会创建一个Servlet实例并调用init()方法,init()方法只会调用一次,Servlet容器在下面的情况装载Servlet:

  1. Servlet容器(Tomcat)启动时自动装载某些servlet,实现这个需要在web.xml文件中添加<load-on-startup>1<load-on-startup> 1表示装载的顺序web.xml中会配置很多Servlet,可以设置装载顺序(tomcat启动时,就把servlet放入到HashMap中)
  2. 在Servlet容器启动后,浏览器首次向Servlet发送请求
  3. Servlet重新装载时(比如tomcat进行redeploy【redeploy会销毁所有的Servlet实例】)
     

处理浏览器请求阶段(service方法)

  1. 每收到一个http请求,服务器就会产生一个新的线程去处理[线程]
  2. 创建一个用于封装HTTP请求消息的ServletRequest对象和一个代表HTTP响应消息的ServletResponse对象
  3. 然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去

tomcat去调用servlet的service方法,将HTTP请求封装成一个实现了ServletRequest接口的对象,我们只用调用这个对象的方法,就可以获得HTTP请求的信息

调用ServletRespons对象的方法,将要返回的数据写入,交给tomcat,tomcat会帮我们把这对象转换为HTTP请求返回给浏览器

 
终止阶段

  • 终止阶段destory方法
    当web应用被终止,或者Servlet容器终止运行,或者Servlet类重新装载时,会调用destroy()方法比如重启tomcat ,或者 redeploy web应用

 
GET和POST请求的分发处理
·开发Servlet,通常编写doGet、 doPost方法。来对表单的get和post请求进行分发处理

 
Servlet注意事项与细节

  1. Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,不能独立运行
  2. 针对浏览器的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出/或者redeploy该web应用,servlet实例对象才会销毁
  3. 在Servlet的整个生命周期内,init方法只被调用一次。而对每次请求都导致Servlet引擎调用一次servlet的service方法。
  4. 对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的
    HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法
  5. 如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法
     

浏览器调用注解方式创建的Servlet

  1. 对包进行扫描,如果发现某个类是@WebServlet,就说明该类是Servlet,读取urlPatterns,进行下一步
  2. 扫描到知道该类是Servlet,自然可以得到该类的全路径。利用反射创建一个Servlet实例
  3. 该实例有一个方法,可以获得注解的全部信息(aClass.getAnnotation(WebServlet.class),自然可以获得注解设定的全部url;
  4. 后面就可以通过浏览器要访问的资源与url进行一一比较,看是否有满足条件的url
  5. 大致流程与浏览器调用servlet方式一样,只是不再去xml文件去判断,而是将所有在xml配置的信息转移到注解中

 
Servlet注解URL4种匹配方式

  • 精确匹配
  • 目录匹配
  • 扩展名匹配
  • 任意匹配
     

Servlet注解URL配置注意事项

  • Tomcat自带一个默认的Servlet,当访问静态资源,其他的utl-pattern都匹配不上时,就会调用这个servlet,它会将用户请求的静态资源返回
  • 但是,如果配置了"/",它会拦截所有访问的资源,这样其他的utl-pattern都匹配不上时,不会调用默认的servlet,而是调用任意匹配(这种是返回不了静态资源)
  • 提示:建议不要使用/和/*,建议尽量使用精确匹配
  • 优先级遵守:精确路径>目录路径 > 扩展名路径 > 任意匹配 > 默认Servlet

 
 
tomcat支持servlet
浏览器将请求发送给tomcat,tomcat将http请求封装成对象送给servlet
servlet将返回的数据对象传给tomcat,tomcat在将对象解析成http请求,tomcat把http请求返回给浏览器

 
访问servlet
http://localhost:8080/项目名/ur-pattern
这样直接访问,因为在web.xml中已经配置了绝对路径
在这里插入图片描述
 
访问静态文件
如果是在web目录下创建静态文件
http://localhost:8080/项目名/静态文件名
在这里插入图片描述

如果是在web目录下的子目录创建静态文件
http://localhost:8080/项目名/子目录/.../静态文件名
在这里插入图片描述
 
 

什么是servlet

在这里插入图片描述

在这里插入图片描述

Servlet在JavaWeb项目中位置

引入动态网页(能和用户交互)技术===> Servlet
在这里插入图片描述
当浏览器请求的是动态资源时(数据库中的数据),tomcat就会访问servlet,servlet会调用Java程序,去将数据库中的数据取出
当浏览器请求的是静态资源时,tomcat就会静态资源直接返回给浏览器

tomcat有两个作用

  1. 作为servlet的容器
  2. 充当Web服务

手动开发Servlet

servlet就是一系列的规范
在这里插入图片描述

1.创建servlet项目,配置好tomcat

在这里插入图片描述

2.添加servlet-api.jar(在tomcat/lib下)到工程。因为servlet.jar不是jdk自带的,要引入

在这里插入图片描述
在这里插入图片描述

3.在src下包com.study.servlet.HelloServlet.java,并实现Servlet接口

package com.study.servlet;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author 珀筱
 * 开发一个Servlet,需要实现Servlet接口
 * 实现Servlet接口5个方法
 */
public class HelloServlet implements Servlet {

    /**
     * 1.初始化 servlet
     * 2.当创建Helloservlet实例时,会调用init方法
     * 3.该方法只会被调用一次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init()被调用...");
    }

    /**
     * 返回Servletconfig也就是返回Servlet的配置
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 1. service方法处理浏览器的请求(包括get/post)
     * 2.当浏览器每次请求Servlet时,就会调用一次service
     * 3.当tomcat调用该方法时,会把http请求的数据封装成实现ServletRequest接口的request对象
     * 4.通过servletRequest对象,可以得到用户提交的数据
     * 5. servletResponse对象可以用于返回数据给tomcat(tomcat会将对象转换成http响应的形式)->浏览器(得到结果,解析展示)
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest,
                        ServletResponse servletResponse) throws ServletException, IOException {

    }

    /**
     * 返回servlet信息
     * @return
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 1.该方法是在servlet销毁时,被调用
     * 2.只会调用一次
     */
    @Override
    public void destroy() {

    }
}

4.在web.xml配置HelloServlet,即;给HelloServlet提供对外访问地址

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--web.xml 主要用来配置该web应用使用到的Servlet
        1. servlet-name:给Servlet取名(程序员决定),该名字唯一
        2. servlet-class: Servlet的类的全路径: Tomcat在反射生成该Servlet需要使用
        3. <servlet-mapping>下的servlet-name 要与<servlet>中的servlet-name一样
        4. url-pattern:这个就是该servlet访问的url的配置(路径)
        5. 这时我们应该这样访问servlet http://localhost:8080/servlet/HelloServlet
        6. url-pattern取名是程序员决定的(前面的 / 不能丢)
-->
    <!--配置HelloServlet-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.study.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/HelloServlet</url-pattern>
    </servlet-mapping>
</web-app>

5.重新发布

在这里插入图片描述
查看结果
在这里插入图片描述
在这里插入图片描述

浏览器调用Servlet流程分析

浏览器将HTTP请求(http://localhost:8080/servlet/HelloServlet)发送给Tomcat,Tomcat得到HTTP请求

如果是第一次请求(Tomcat)
1. tomcat会去查询web.xml(已解析出要访问的web应用:servlet)
2. 看看请求的资源 /HelloServlet,在web.xml 中 url-pattern 是否配置
3. 如果找到url-pattern,就会得到servlet-name:HelloServlet
4. tomcat中维护了一个大的HashMap<id,Servlet>,其中id就是servlet-name,查询该HashMap,看看有没有这个Servlet实例
5. 如果没有查询到该Serletname 对应的 id,即没有这个Servlet实例
6.就根据servlet-name 去得到serlvet-classs:类的全路径
7. 使用反射技术,将servlet实例化 -> 执行init()方法->service()方法,并放入到tomcat维护的HashMap<id,Servlet>

 
如果是第2次(以后)请求(Tomcat)
1.查询web.xml
2.看看请求的资源/helloServlet,在web.xml配置url-pattern
3.如果找到url-pattern.就会得到servlet-name:HelloServlet
4.Tomcat维护了一个大的HashMap<id, Servlet>,查询该Hashmap看看有没有这个Servlet实例
5.如果查询到,就直接调用该Servlet的service
6.结果显示

在这里插入图片描述

Servlet生命周期

在这里插入图片描述
在这里插入图片描述

初始化阶段

在这里插入图片描述

处理浏览器阶段

在这里插入图片描述
tomcat去调用servlet的service方法,将HTTP请求封装成一个实现了ServletRequest接口的对象,我们只用调用这个对象的方法,就可以获得HTTP请求的信息

调用ServletRespons对象的方法,将要返回的数据写入,交给tomcat,tomcat会帮我们把这对象转换为HTTP请求返回给浏览器

终止阶段

在这里插入图片描述

GET和POST的请求分发处理

在这里插入图片描述
1.创建一个表单html
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>注册用户</h1>
<form action="http://localhost:8080/servlet/HelloServlet"
      method="get">
    u:  <input type="text" name="username"/><br><br>
    <input type="submit" value="注册用户"/>
</form>
</body>
</html>

配置servlet

    @Override
    public void service(ServletRequest servletRequest,
                        ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("helloServlet~");
        //思考->从servletRequest对象来获取请求方式->
        //1. ServletRequest没有得到提交方式的方法
        //2. ServletRequest看看ServletRequest子接口有没有相关方法
        //3. ctrl+alt+b =>可以看到接口的子接口和实现子类
        //4.把servletReqeust转成HttpServletRequest引用
        //ServletRequest没有获取请求方法的方法,但ServletRequest的子接口HttpServletRequest有这个方法
        //又因为servletRequest实现了ServletRequest,所以可以把servletRequest转为HttpServletRequest
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod();
        if ("GET".equals(method)) {
            doGet(); //用doGet 处理GET请求
        } else if ("POST".equals(method)) {
            doPost(); //用doPost 处理POST其你去
        }

    }

    /**
     * 用于相应get请求
     */
    public void doGet() {
        System.out.println("调用了doGet方法...");
    }

    /**
     * 用于相应post请求
     */
    public void doPost() {
        System.out.println("调用了doPost方法...");
    }

查看结果
提交表单,跳转到HelloServlet
在这里插入图片描述
在这里插入图片描述

通过继承HttpServlet开发Servlet

GenericServlet是一个抽象类,它将Servlet的五个方法全都实现了
HttpServlet继承了GenericServlet,并且它自身提供了大量的方法和字段可以供开发者使用
在这里插入图片描述
在这里插入图片描述

1.编写一个类去继承 HttpServlet类,并根据业务需要重写doGet或doPost方法

package com.study.servlet;

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

/**
 * @author 珀筱
 */

public class HiServlet extends HttpServlet {
    /**
     * 处理GET请求
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("调用了HttpServlet的doGet方法...");
    }

    /**
     * 处理POST请求
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("调用了HttpServlet的doPost方法...");
    }
}

2.到web.xml中的配置Servlet程序

    <servlet>
        <servlet-name>HiServlet</servlet-name>
        <servlet-class>com.study.servlet.HiServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HiServlet</servlet-name>
        <url-pattern>/hiServlet</url-pattern>
    </servlet-mapping>

在这里插入图片描述
在这里插入图片描述

JavaWeb开发如何Dbug

下断点
在HttpServlet的service下断点,看执行的那个doGet方法
在这里插入图片描述
点击Dbug
在这里插入图片描述
访问网页,可以发现网页一直在请求
在这里插入图片描述
程序运行到了HiServlet
在这里插入图片描述

在这里插入图片描述

IDEA开发配置Servlet

在这里插入图片描述

1. 创建Servlet文件

在这里插入图片描述

2. 输入相关信息

在这里插入图片描述

会发现自动创建
在这里插入图片描述

在这里插入图片描述

Servlet注意事项与细节

在这里插入图片描述
在这里插入图片描述

Servlet注解方式

注解方式创建Servlet

在这里插入图片描述

package com.study.servlet.annotation;

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;

/**
 * @author 珀筱
 */

/**
 * 1.WebServlet是一个注解
 * 2.WebServlet源码
 *     String name() default "";
 *
 *     String[] value() default {};
 *
 *     String[] urlPatterns() default {};
 *
 *     int loadOnStartup() default -1;
 *
 *     WebInitParam[] initParams() default {};
 *
 *     boolean asyncSupported() default false;
 *
 *     String smallIcon() default "";
 *
 * 3. urlPatterns对应web.xml 的<url-pattern></url-pattern>
 * 4. {"/ok1","/ ok2"}可以给0kServlet配置多个url-pattern
 * 5.相当于这个@WebServlet(urlPatterns = {"/ok1" ,"/ok2"})代替了web.xml的配置
 * 6.浏览器可以这样访问OkServlet时,可以 http://localhost:8080/servlet/ok1或者
 *    http://localhost:8080/servlet/ok2
 */
@WebServlet(urlPatterns = {"/ok1","/ok2"})
public class OkServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("注解的doPost()");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("注解的doGet()");
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

浏览器调用注解方式创建的Servlet

1.对包进行扫描,如果发现某个类是@WebServlet,就说明该类是Servlet,读取urlPatterns,进行下一步
2. 扫描到知道该类是Servlet,自然可以得到该类的全路径。利用反射创建一个Servlet实例
3. 该实例有一个方法,可以获得注解的全部信息(aClass.getAnnotation(WebServlet.class),自然可以获得注解设定的全部url;
4. 后面就可以通过浏览器要访问的资源与url进行一一比较,看是否有满足条件的url
5. 大致流程与浏览器调用servlet方式一样,只是不再去xml文件去判断,而是将所有在xml配置的信息转移到注解中

package com.study.servlet.annotation;

import javax.servlet.annotation.WebServlet;
import java.util.HashMap;

/**
 * @author 珀筱
 */
public class TestAnnotationServlet {
    private static final HashMap<String, Object> hm = new HashMap<>();

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //1.首先要得到扫描的包路径io,进而得到类的全路径
        String classAllPath = "com.study.servlet.annotation.OkServlet";
        //2.得到0kServlet的Class对象
        Class<?> aClass = Class.forName(classAllPath);
        //3.通过class对象,得到Annotation
        WebServlet annotation = aClass.getAnnotation(WebServlet.class);
        System.out.println(annotation); //@javax.servlet.annotation.WebServlet(loadOnStartup=-1, initParams=[], urlPatterns=[/ok1, /ok2], displayName=, name=, largeIcon=, asyncSupported=false, description=, smallIcon=, value=[])

        String[] urls = annotation.urlPatterns();
        for (String url : urls) {
            System.out.println(url); //ok1 //ok2
        }

        //如果匹配url,如果是第一次,tomcat就会创建一个OkServlet实例,放入到hashmap
        Object obj = aClass.newInstance();
        System.out.println(obj); //com.study.servlet.annotation.OkServlet@5acf9800

        //简单模拟
        hm.put("OkServlet",obj); 
    }
}

在这里插入图片描述

Servlet注解URL4种匹配方式

精确匹配

在这里插入图片描述

@WebServlet(urlPatterns = {"/ok1","/ok2"})

 

目录匹配

在这里插入图片描述

@WebServlet(urlPatterns = {"/ok1/aa/*","/ok2"})

支持多级目录访问
在这里插入图片描述
 

扩展名匹配

在这里插入图片描述

@WebServlet(urlPatterns = {"*.txt","/ok2"})

在这里插入图片描述
 

任意匹配

在这里插入图片描述

@WebServlet(urlPatterns = {"/*"})

在这里插入图片描述

Servlet注解URL配置注意事项

Tomcat自带一个默认的Servlet,当访问静态资源,其他的utl-pattern都匹配不上时,就会调用这个servlet,它会将用户请求的静态资源返回
但是,如果配置了"/",它会拦截所有访问的资源,这样其他的utl-pattern都匹配不上时,不会调用默认的servlet,而是调用任意匹配
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值