JavaWeb之Servlet基本使用

一、Servlet概述

Servlet在javax.servlet包下,是Servlet规范中的核心接口。
在这里插入图片描述

Servlet是一个运行在web服务器中的java小程序,负责接收和响应来自客户端的请求,使用的交互使用的协议通常是HTTP协议。

Servlet是一个接口,一个类要想通过浏览器被访问到,那么这个类就必须直接或间接的实现Servlet接口

对比普通的类和servlet

  • servlet必须运行在web服务器上,普通的类可以在任何项目中
  • servlet做的事情是(接收请求,处理请求,生成响应);普通的类做的事情是由开发人员自定义的
  • servlet的对象是web服务器创建的;普通的类的对象目前都是开发人员自己创建的

二、Servlet快速入门

2.1 编写步骤

  1. 创建一个 WEB 项目
  2. 创建一个类实现Servlet接口
  3. 重写 service 方法。
  4. 在 web.xml 中配置 Servlet
  5. 部署并启动项目
  6. 通过浏览器测试

2.2 代码实现

web.xml中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_3_1.xsd"
         version="3.1">
    <!--
        找到类,给类设置一个访问路径
        <servlet>
            <servlet-name>别名:整个xml中必须是唯一的</servlet-name>
            <servlet-class>类的全限定类名,唯一锁定类.底层tomcat需要借助全限定类名反射实例化(new)对象</servlet-class>
        </servlet>
        <servlet-mapping> servlet的映射配置
            <servlet-name>别名:使用已经定义好的别名</servlet-name>
            <url-pattern>访问的链接地址 /名称</url-pattern>
        </servlet-mapping>
    -->
    <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>com.itheima.servlet.DemoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/sayHello</url-pattern>
    </servlet-mapping>
</web-app>

servlet代码

public class DemoServlet implements Servlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("sayHello");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

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



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

    @Override
    public void destroy() {

    }
}

2.3 执行过程

浏览器发送请求→Tomcat服务器→我们的应用→应用下的web.xml→ServletDem1→执行service方法,响应浏览器
在这里插入图片描述

2.4 创建Servlet的三种方式

  • 第一种:实现 Servlet 接口,实现所有的抽象方法。该方式支持最大程度的自定义
  • 第二种:继承 GenericServlet 抽象类,必须重写 service 方法,其他方法可选择重写;
    该方式让我们开发 Servlet 变得简单,但是这种方式和 HTTP 协议无关
  • 第三种:继承 HttpServlet ,需要重写 doGetdoPost 方法,该方式表示请求和响应都需要使用HTTP 协议

使用继承GenericServlet方式创建Servlet

xml配置
<servlet>
        <servlet-name>ServletDemo</servlet-name>
        <servlet-class>com.itcast.servlet.ServletDemo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletDemo</servlet-name>
        <url-pattern>/ServletDemo</url-pattern>
    </servlet-mapping>
public class ServletDemo extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("继承GenericServlet的方式");
    }
}

使用继承HttpServlet方式创建Servlet

xml配置
<servlet>
        <servlet-name>ServletDemo2</servlet-name>
        <servlet-class>com.itcast.servlet.ServletDemo2</servlet-class>
</servlet>
<servlet-mapping>
        <servlet-name>ServletDemo2</servlet-name>
        <url-pattern>/ServletDemo2</url-pattern>
</servlet-mapping>
public class ServletDemo2 extends HttpServlet {
    //post提交
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);//不希望书写代码重复 直接调用一下即可
    }

    //get提交
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("继承HttpServlet的方式");
    }
}

关于HttpServlet

  • GenericServlet的子类
  • 重写了父类的service方法,通过doPostdoGet方法调用
  • 类中doPostdoGet方法如果不重写的话会报错,规范要求重写
  • 请求和响应都使用了HTTP 协议

实际开发中都是使用继承HttpServlet类的方式。

2.5 Servlet对象的生命周期

2.5.1 生命周期概述

生命周期:对象从创建到销毁的过程。

  • 创建:请求第一次到达Servlet时(第一次访问Servlet时)对象创建
  • 活着:只要应用一直提供服务,对象就一直存在
  • 销毁:应用停止服务或者是服务器停止(宕机)时,对象销毁

与生命周期相关的API:

  • public void init(ServletConfig servletConfig) 初始化
  • public void service(ServletRequest servletRequest, ServletResponse servletResponse) 服务
  • public void destroy() 正常销毁
public class ServletDemo implements Servlet {

    //初始化
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("初始化方法执行了");
    }
    //服务
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        int count = 1;
        System.out.println("sayHello");
        count ++;
        System.out.println(count);
    }
    //销毁
    @Override
    public void destroy() {
        System.out.println("销毁方法执行了");
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    
    @Override
    public String getServletInfo() {
        return null;
    }
}

上述代码效果:

  • 默认第一次访问服务器执行init初始化方法,创建Servlet对象

  • 每次访问都会执行service方法

  • 正常关闭服务器或者卸载应用会执行destroy销毁方法

Servlet对象可以看成是单例对象,默认是第一次请求来的时候,web服务器会创建Servlet对象,然后执行对象的init方法,实现初始化操作,再执行servlet的service方法来处理当次请求;

再有请求来的时候,web服务器会获取一个线程,在当前线程中,会调用Servlet对象的service方法来处理请求;

Servlet被移除的时候或者web服务器关闭的时候,执行servlet的destory方法来显示销毁操作。

2.5.2 修改Servlet对象创建时机

<servlet>标签中,添加<load-on-startup>标签,然后在这个标签中添加一个整数:

  • 正整数代表服务器加载时创建,值越小、优先级越高
  • 负整数或不写代表第一次访问时创建
<servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>com.itcast.servlet.ServletDemo</servlet-class>
        <!--
            load-on-startup : load 加载  startup 启动
            启动的时候就加载servlet,标签体内部书写数字 一般1-6(启动顺序)
            数字越小 优先级越高
         -->
        <load-on-startup>2</load-on-startup>
    </servlet>

不同时机加载的优劣:

  1. 第一次访问时创建
    优势:减少对服务器内存的浪费,提高了服务器启动的效率。
    弊端:如果有一些要在应用加载时就做的初始化操作,无法完成
  2. 服务器加载时创建
    优势:提前创建好对象,提高了首次执行的效率;还可以完成一些应用加载时要做的初始化操作
    弊端:对服务器内存占用较多,影响了服务器启动的效率

2.6 Servlet线程安全问题

Servlet是单实例运行的,所以存在线程安全问题,所以在类中尽量不要定义成员变量,已经定义的类成员最好不能修改。

如果需要定义可以修改的成员,要定义到方法里面去。

2.7 Servlet路径匹配

url-pattern:将一个请求网络地址和Servlet类建立一个映射关系(一对一)

资源访问路径:
在这里插入图片描述

2.7.1 配置多个访问映射规则

 <servlet>
        <servlet-name>ServletDemo5</servlet-name>
        <servlet-class>com.itcast.servlet.ServletDemo5</servlet-class>
    </servlet>

    <!--映射ServletDemo5-->
    <servlet-mapping>
        <servlet-name>ServletDemo5</servlet-name>
        <url-pattern>/ServletDemo5</url-pattern>
    </servlet-mapping>
    <!--一个Servlet可以配置多个访问映射规则-->
    <servlet-mapping>
        <servlet-name>ServletDemo5</servlet-name>
        <url-pattern>/admin/ServletDemo5</url-pattern>
    </servlet-mapping>

2.7.2 不同的路径匹配映射方式

  • 全匹配映射方式:访问URL中ServletURI的部分和web.xml的URI配置部分完全一致
如访问地址:http://localhost:8585/servlet/ServletDemo1
xml配置:
<servlet-mapping>
		<url-pattern>/ServletDemo1</url-pattern>
</servlet-mapping>
  • 路径匹配,其余通配(*表示通配符)
如访问地址:http://localhost:8585/servlet/ServletDemo1
		   http://localhost:8585/servlet/ServletDemo2
<servlet-mapping>
		<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
  • 后缀匹配,其余通配(*表示通配符)
如访问地址:http://localhost:8585/servlet/ServletDemo1.do
		   http://localhost:8585/servletDemo/ServletDemo2.do
<servlet-mapping>
		<url-pattern>*.do</url-pattern>
</servlet-mapping>
  • 缺省匹配: /" ,此路径不要使用,已经有Servlet使用,任何web服务器中都有两个Serlvet(默认的Servlet和jspservlet)

默认的Servlet:用来处理别的servlet都处理不了的请求
jspserlvet:用来处理后缀名为jsp或者jspx的请求

一个路径只能有一个Servlet执行,路径匹配的优先级:

  • 全匹配>路径匹配其余通配>后缀名匹配>缺省匹配

  • 谁更精确,谁的优先级更高

  • 当都用通配符*时,有/的永远比没/优先级高

2.8 ServletConfig对象

2.8.1 ServletConfig对象概述

ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet 都提供一些初始化的配置,所以每个 Servlet 都有一个自己的 ServletConfig对象。

ServletConfig的作用是在Servlet 初始化时,把一些配置信息传递给 Servlet。

ServletConfig对象是一个单例对象,其生命周期和Servlet相同。

2.8.2 配置

<servlet>
        <servlet-name>ServletDemo</servlet-name>
        <servlet-class>com.itcast.servlet.ServletDemo</servlet-class>
        <!--配置Servlet的初始化参数-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>namespace</param-name>
            <param-value>abc</param-value>
        </init-param>
</servlet>
  • <param-name>:代表初始化参数的 key
  • <param-value:代表初始化参数的 value

2.8.3 常用方法

返回值方法名说明
StringgetInitParameter(String name)根据参数名称获取参数的值
Enumeration<String>getInitParameterNames()获取所有参数名称的枚举
StringgetServletName()获取Servlet的名称
ServletContextgetServletContext()获取ServletContext对象

2.9 ServletContext对象

2.9.1 ServletContext对象概述

ServletContext 是应用上下文对象(应用域对象),存放着应用的所有Servlet信息,每一个应用中只有一个ServletContext 对象,它可以实现整个应用间的数据共享。

域对象指有作用范围的对象,ServletContext的作用范围是整个应用,是整个web应用中四大域对象范围最大那个,称为应用域。

在这里插入图片描述

2.9.2 ServletContext对象常用API

  • getServletConfig().getServletContext()获取ServletContext对象
  • getServletContext() 获取ServletContext对象简写形式
  • void setAttribute(String name,Object value) 存储数据
  • Object getAttribute(String name) 获取数据
  • void removeAttribute(String name) 删除数据
  • getRealPath(virtualPath) 通过一个虚拟路径获取磁盘真实路径(往服务器上写文件时需要使用此方法)
  • getInitParameter(String name) 整个应用的初始化参数,不在Servlet中配置
<!--映射ServletDemo-->
    <servlet-mapping>
        <servlet-name>ServletDemo</servlet-name>
        <url-pattern>/ServletDemo</url-pattern>
    </servlet-mapping>

    <!--配置ServletContext的初始化参数-->
    <context-param>
        <param-name>namespace</param-name>
        <param-value>abc</param-value>
    </context-param>
    <context-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </context-param>
  • Enumeration<String> names= getInitParameterNames() 获取初始化参数名称的枚举

2.9.3 ServletContext的生命周期

  • 创建:应用加载时,对象创建
  • 活着:应用提供服务时,对象一直可用(处于活着的状态)
  • 销毁:应用卸载(停止服务),或者服务器宕机,对象消亡

2.10 注解配置Servlet

  • Servlet 2.5:xml开发
  • Servlet 3.0以后:注解开发

使用注解的作用是替代xml的, 简化xml的配置操作。

使用的注解:@WebServlet

属性:

  • value:指定访问Servlet的URI,和urlPatterns属性是一样的
  • loadOnStartUp:用于配置Servlet的创建时机
  • initParam:用于配置Servlet的初始化参数
@WebServlet(value = "/ServletAnnotationConfigDemo",loadOnStartup = 1,
initParams ={
        @WebInitParam(name="namespace",value="abc"),
        @WebInitParam(name="encoding",value="UTF-8")
} )
public class ServletAnnotationConfigDemo extends HttpServlet {




    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ServletAnnotationConfigDemo执行了");

        //获取Servlet的配置对象
        ServletConfig config = this.getServletConfig();
        //根据名称获取值
        String value1 = config.getInitParameter("namespace");
        String value2 = config.getInitParameter("encoding");
        System.out.println(value1+","+value2);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值