servlet详解

什么是Servlet

  • Servlet是Javaweb的三大组件(sevlet,listner,filter)之一,它属于动态资源,Servlet的作用是处理请求,服务器会吧接收到的请求交给Servlet来处理,在Servlet中通常需要:
    • 接受请求数据
    • 处理请求
    • 完成响应
  • 例如;客户端发出登录,注册等请求,这些请求都有Servlet来完成处理,Servlet由我们来完成编写,Servlet必须实现java.servlet.Servlet接口
  • 每个Servlet都是唯一的,他们的功能是不一样的,比如一个Servlet是用来注册的,另一个servlet是用来登录的

实现Servlet接口的三种方式

  • 实现java.servlet.Servlet接口(请查看Java ee 文档)
    • 这个接口中一共有5个方法,其中声明周期方法有3个
      • 声明周期的方法是服务器自动调用的
      • destroy()servlet 销毁之前之前执行一次,不是这个方法销毁servlet
      • init()servlet 创建之后,执行初始化方法
      • service()服务器每次接收到一次请求,执行一次这个方法,每次处理请求都是使用的这个方法
    • 剩下的两个方法
      • getServletConfig()后去 servlet配置信息
      • getServletInfo()获取servlet 的信息,一般没有什么用
    • 特性:
      • 一个类只有一个对象,服务器自动获取,但是可能存在多个Servlet类
      • 线程不安全,效率高
    • 解决线程不安全的三个解决方法:
      • 不要定义成员变量,定义局部变量
      • 创建无状态的成员
        • 无状态类,也就是说类内部,没有对内部成员变量和外部变量的操作。简单来讲就是一个类中,的方法都不会操作内部和外部变量。
      • 创建有状态的成员但是 只是可读的:比如定义一个属性,只有get方法,不给set方法,这样多个线程只能读取不能设置,实现了多线程的安全
  • 继承java.servlet.GenericServlet类
    • 这个类是Servlet接口的实现抽象类,我们可以通过继承这个类来编写自己的类
  • 继承java.servlet.http.HttpServlet类
    • 这个类也是Servlet接口的一个实现类,用来面上http协议的
    • Httpservlet原理
    • 这里写图片描述
  • 通常我们会使用继承HttpServlet来使用

如何访问 servlet

  • 由于浏览器访问都是通过路径访问的
  • 给servlet 指定一个个sevlet 路径,让servlet 和这个路径绑定在一起
  • 浏览器通过路径访问servlet
  • 访问过程分析
    • 这里写图片描述

给Servlet配置Servlet路径

  • 这个操作需要在WEB-INF下的web.xml中给Servet配置路径
  • 格式:

        <servlet>
            <servlet-name>xxx</servlet-name>
            <servlet-class>com.td.Text</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>xxx</servlet-name>
           <!-- 两个servlet-name 必须名字是一样的 --> <servlet-pattern></servlet-pattern>
            <!--servlet-pattern这里必须是/开头 -->
    
        </servlet-mapping>

ServletConfig 接口介绍

  • ServletConfig实例和servlet配置文件对应,一个ServletConfig 对应一个Servlet 实例
  • 这里写图片描述
  • 常用的方法
    • getServletName()获取servlet的 名字,也就是获取web.xml中servlet配置配置的servlet-name的值
    • getServletContext() 获取Servlet上下文
    • getInitParameterNames()获取所有初始化参数的名字
    • getInitParameter(String name) 获取指定的参数的名字

定义初始化参数

  • 通过WEB-INF中的web.xml配置文件,定义初始化参数
  • 位置 servlet标签内
  • 可以定义多个
  • 格式

    <servlet>
        <init-param>
            <param-name>参数名</param-name>
            <param-value>参数值</param-value>
        </init-param>
    </servlet>
    
  • 图解:
    这里写图片描述
  • 代码:
    这里写图片描述

GenericServlet 自定义实现

  • 自定义实现GenericServle类,

    • 定义一个类,实现Servlet接口
    • 封装一个ServletConfig对象,为当前类的 属性config
    • 通过这个类的属性config实现,ServletConfig中的4个方法
    • 代码如下:

          package com.td;
      
          import java.io.IOException;
          import java.util.Enumeration;
      
          import javax.servlet.Servlet;
          import javax.servlet.ServletConfig;
          import javax.servlet.ServletContext;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
      
          public abstract class MyServlet implements Servlet {
          //  模拟GenericServlet类的方法,这个类的方法就是Servelet接口的方法加上,Servletconfig接口的四个方法,还有三个自带的方法没有重写。
              private ServletConfig config = null;
              @Override
          //  当服务器关闭时,执行这个方法
              public void destroy() {
                  // TODO Auto-generated method stub
      
              }
      
              @Override
              public ServletConfig getServletConfig() {
                  // TODO Auto-generated method stub
                  return this.config;
              }
      
              @Override
              public String getServletInfo() {
                  // TODO Auto-generated method stub
                  return "getServletInfo() 执行了";
              }
      
              @Override
          //  打开服务器,接受第一个请求的时候,执行这个方法。
              public void init(ServletConfig config) throws ServletException {
                  this.config = config;
                  System.out.println("init()");
      
                  init();
              }
              //自己定义了一个init方法,这样就可以,不用覆盖带有参数的init方法,并且能让功能进行扩展
              public void init(){
      
              }
      
              @Override
          //  服务器每次接收到一个请求,就执行一次这个方法
              public void service(ServletRequest req, ServletResponse res)
                      throws ServletException, IOException {
                  // TODO Auto-generated method stub
      
              }
          //  一下是我 使用包装的属性,把ServletConfig中的方法进行封装到了自己定义的类中
      
              public String getInitParameter(String name){
                  return this.config.getInitParameter(name);
              }
      
              public Enumeration<String> getInitParameterNames(){
                  return this.config.getInitParameterNames();
              }
              public ServletContext getServletContext(){
                  return this.config.getServletContext();
              }
              public String getServletName(){
                  return this.config.getServletName();
              }
          //  自己实现了GenericServlet中的service方法
              public abstract void service(ServletRequest req,ServletRequest res);
      
          }
      

HTTPServlet

  • extends GenericServlet 继承GenericServlet
  • 如果一个类继承了HTTPServlet那么,会调用service(ServletRequest,ServletResponse) 方法,这个方法调用service(HTTPServletRequest,HTTPServletResponse)方法,这个方式根据访问的方式,调用get 或者 put方法
  • HTTPServlet中的访问 方式的方法,都是超出异常的。如果不重写,那么 就会报错405
  • 所以我们需要重写访问方式的方法,如果没有重写,那么报错405这里写图片描述

Servlet细节补充

  • 线程安全问题
    • 一个类只能有一个对象,这个对象是服务器自动获取的,多条线程访问会造成线程不安全的问题,但是也有解决方法
      • 不要定义成员变量,定义局部变量
      • 创建无状态的成员
      • 创建有状态的成员但是 只是可读的:比如定义一个属性,只有get方法,不给set方法,这样多个线程只能读取不能设置,实现了多线程的安全
  • 可以设置为服务器 启动就执行init方法

    • 正常情况是,服务器启动后,接收到第一条请求,执行init方法
    • 但是可以通过设置配置文件,让服务器启动就执行init方法
    • 位置:web.xml 下的写在这里
    • 格式:

          <load-on-startup>这里填写非负数的整数</load-on-startup>
      
    • 数字越小,先执行
    • 用来指定Servlet的访问路径,必须是/开头,可以设置多个
    • 也就是说一个Servlet可以有多个访问路径
    • 可以使用通配符*号,但是不建议使用
      • /servlet/*匹配前缀
      • *.do匹配后缀
      • /*匹配所有
      • 不允许星号出现在URL中间
      • 一个URL只能出现一个通配符*

web.xml文件的继承

  • 每个Javaweb项目都有一个web.xml 这里写图片描述
  • 所有的web.xml都是一个公共的父文件,每个项目都在使用这个配置文件,他在Tomcat–>conf–>web.xml这里写图片描述
  • 详解web.xml文件
  • 当访问你的资源不存在的时候,它来处理这里写图片描述
  • 当请求jsp动态资源的时候,通过org.apache.jasper.servlet.JspServlet将动态资源转换成静态资源,响应给了客户端
  • session 的过期时间这里写图片描述
  • mime类型这里写图片描述

  • 欢迎页面设置这里写图片描述

  • 当请求jsp页面的时候,会根据jsp的url-pattern找到JspServlet,这个JspServlet将请求的jsp变成Java文件,在编译成class文件,创建对象,执行service方法

    • 这里写图片描述
    • 这里写图片描述

Servlet 和反射

  • 服务器通过读取Java web项目中的web.xml 文件,
  • 解析到Servlet的类名
  • 通过反射获取Servlet实例(必须有空参数的 构造函数)
  • 调用内部的方法
  • ==以上操作都是由服务器来完成的==

ServletContext

  • 概述:
    • 一个项目只能有一个ServletContext对象,所以一般给这个对象命名application
    • 可以在多个Servlet对象获取这个ServletContext对象,使用它可以在多个Servlet之间传输数据
    • ==这个对象在服务器启动时就创建,服务器关闭时关闭==
  • 获取ServletContext实例
    • Servlet中的init方法传入的参数,是一个ServletConfig对象,调用这个对象的getServletConfig方法获取
    • ServletConfig的方法getServletConfig 方法获取
    • GenericServlet的getServletContext方法获取
    • HttpServlet中的getServletContext方法获取
    • HttpSession中的getServletContext方法获取
    • ServletContextEvent中的getServletContext方法获取
  • ServletContext常用的方法
    • getServeltContextPath()这个方法会获取项目的路径,是个相对路径,经常用它来获取项目路径,然后进行资源路径的拼接,

域对象

  • 域对象:就是在多个Servlet中传递数据的,
  • 域对象必须有存储数据和获取数据的功能
  • Javaweb四大域对象

    • ServletContext
    • PageContext
    • ServletRequest
    • HttpSession
  • 域对象内部都有个map用来存储数据,常用的方法

    • setAttribute(java.lang.String name, java.lang.Object object)用来存储一个数据
    • getAttribute(java.lang.String name) 获取值
    • removeAttribute(java.lang.String name) 删除一个数据
    • java.util.Enumeration

获取类(classes文件夹)路径下的资源

  • 类路径资源对于javaweb项目而言,就是/WEB-INF/classes和WEB-INF/lib/每个jar包
  • ==因为classes文件夹在WEB-INF内,这个文件夹是不能访问的,我们需要使用反射来获取内部的资源==

  • classLoader方式读取资源,相对的是服务器地址–>webapps–>Java web项目在下 WEB-INF –> classes文件夹

    • 在Java web项目下的src目录下写的文件会被发送到classes文件夹下面
    • 实例:这里写图片描述
  • class 方式读取资源
    • 如果输入 的资源不带斜杠,相对的是资源所在目录
    • 如果输入的资源带斜杠,那么相对的是classes文件夹
    • 实例:这里写图片描述
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值