zoukankan      html  css  js  c++  java
  • Java 之 Servlet

    1. JavaWeb 三大组件: Servlet, Filter, Listener.
    2. Servlet 的作用是处理请求,服务器会把接收到的请求交给 Servlet 来处理.在 Servlet 中通常需要:
      • 接收请求数据;
      • 处理请求;
      • 完成响应;
    3. Servlet 也称为服务端的小程序,每一个 Servlet 都是唯一的, 它们能处理的请求是不同的.

    实现 Servlet 有三种方式:

    • 实现 javax.servlet.Servlet 接口;
    • 继承 javax.servlet.GenericServlet 类;
    • 继承 javax.servlet.http.HttpServlet 类;

    1. javax.servlet.Servlet 接口

    // 实现 javax.servlet.Servlet 接口来编写自定义 Servlet
    // 需要覆盖五个方法
    
    public class AServlet implements Servlet {
    
        // 该方法获取 Servlet 的配置信息, 返回值为 ServletConfig 对象
        public ServletConfig getServletConfig(){
            System.out.println("getServletConfig run...");
            return null;
        }
    
        // 生命周期方法, 会在 Servlet 对象创建之后马上执行, 并且只执行一次!! (出生之后)
        // 在网页第一次被访问的时候, 创建 Servlet 对象
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("Init run...");
        }
    
        // 生命周期方法, 会被调用很多次, 每次处理请求都是在调用这个方法!
        public void service(ServletRequest request, ServletResponse response)
                    throws ServletException, IOException {
    
                    System.out.println("service run...");
                }
    
        // 生命周期方法, 会在 Servlet 被销毁之前调用, 并且也只会被调用一次. (临死之前, 留遗言的方法)
        public void destroy(){
            System.out.println("destroy run...");
        }
    
        // 获取 Servlet 的描述信息(使用较少)
        public String getServletInfo(){
            System.out.println("getServletInfo run....");
            return "我是一个快乐的 Servlet."
        }
    }
    

    备注:

    1. Servlet 对象是单例的, 一个 Servlet 类只有一个对象. 但是可能存在多个不同的 Servlet 类;
    2. Servlet 中的类由我们来写, 但是对象由服务器来创建, 并且由服务器来调用相应的方法;
    3. 线程不安全, 效率高

    浏览器访问 Servlet

    1. 给 Servlet 指定一个 Servlet 路径, 也就是让 Servlet 与一个路径绑定在一起;
    2. 在 web.xml 中配置 Servlet 路径;
    3. 浏览器访问 Servlet 路径
    // web.xml 配置 Servlet 路径
    
    <servlet>
        <servlet-name>XXXX</servlet-name>  // 名字任意取
        <servlet-class>cn.itcast.web.servlet.AServlet</servlet-class>  // Servlet 类的地址
    </servlet>
    
    <servlet-mapping>
        <servlet-name>XXXX</servlet-name>  // 此处名字需要和上面配置的名字相同
        <url-pattern>/AServlet</url-pattern>  // 配置浏览器访问的 url 地址, 必须以 "/" 开头, 名字随便写
    </servlet-mapping>
    

    ServletConfig 接口

    • 一个 ServletConfig 对象, 对应一段 web.xml 中 Servlet 的配置信息
    • ServletConfig 常见方法:
      • String getServletName(); : 获取 <servlet-name> 中的内容;
      • ServletContext getServletContext(); : 获取 Servlet 上下文对象;
      • String getInitParameter(String name); : 通过名称获取指定初始化参数的值; 如 p1 或 p2
      • Enumeration getInitParameterNames(); : 获取所有初始化参数的名称;

    2. javax.servlet.GenericServlet 类 (抽象类)

    • GenericServlet 类是 Servlet 接口的实现类;
    • 通过继承 GenericServlet 类, 只需要复写 service 方法即可.
    // 模拟实现 GenericServlet 类
    
    public class BServlet implements Servlet{
    
        private ServletConfig config;
    
        // Servlet 对象创建之后, 第一个被调用的方法
        public void init(ServletConfig config) throws ServletException {
    
            // 把 tomcat 传递的 ServletConfig 赋值给本类的一个成员, 其实就是把它保存起来,
            // 方便在其他方法中调用
            this.config = config;
            this.init();
        }
    
        // 这个 init 方法是本类自己定义的, 而不是 Servlet 接口中的 init 方法
        // 继承 BServlet 类的子类, 复写此方法, 可以实现在 Servlet 对象初始化时,传入自己定义的内容
        public void init(){
    
        }
    
        public ServletConfig getServletConfig() {
            return this.config;
        }
    
        public void service(ServletRequest req, ServletResponse reps)
                throws ServletException, IOException {
    
                    System.out.println("service run...");
            }
    
        public void destroy(){
            System.out.println("destroy run...");
        }
    
        public String getServletInfo(){
            return "我是一个快乐的 Servlet!";
        }
    }
    

    3. javax.servlet.http.HttpServlet 类

    • HttpServlet 继承 GenericServlet 类
    • 只需要复写 doGet() 和 doPost() 方法即可. 但是 doGet() 和 doPost() 不是抽象方法,
      默认返回值为 405 状态码
    // HttpServlet 中 service() 方法说明
    
    public abstract class HttpServlet extends GenericServlet{
    
        // Servlet 对象中的生命周期方法
        public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException{
    
                // 该方法会强转两个参数: req, res 为 http 协议相关的类型
                // 然后调用 service(HttpServletRequest req, HttpServletResponse resp) 方法
    
            }
    
        //  参数是与 Http 协议相关的
        public void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException{
    
                // 它会通过参数 req, 得到当前请求的请求方式, GET 或 POST
                // 根据请求方式再调用 doGet() 或者 doPost() 方法
            }
    
    
        // 此方法需要重写
        public void doGet(HttpServletRequest req, HttpServletResponse resp){....}
    
        // 此方法需要重写
        public void doPost(HttpServletRequest req, HttpServletResponse resp){....}
    }
    

    Servlet 细节

    1. Servlet 不是线程安全的.
    - 一个类型的 Servlet 只有一个实例对象, 那么就有可能出现一个 Servlet 同时处理多个请求.
      由于线程不安全, 因此不要在 Servlet 中创建成员(全局变量). 因为可能会存在一个线程对这个成员变量进行
      写操作, 另一个线程对这个成员变量进行读操作.
    - 可以在 Servlet 中创建局部变量.
    
    2. 让服务器在启动时就创建 Servlet
    - 默认情况下, 服务器会在某个 Servlet 第一次收到请求时创建它.
    - 也可以在 web.xml 中对 Servlet 进行配置, 使服务器启动时就创建 Servlet
    
    // 示例
    <servlet>
        <servlet-name>hello2</servlet-name>
        <servlet-class>cn.itcast.servlet.Hello2Servlet</servlet-class>
        <load-on-startup>0</load-on-startup>  // 该值为非负整数, 该值的大小,决定 hello2 比 hello3 先创建
    </servlet>
    <servlet-mapping>
        <servlet-name>hello2<servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>hello3</servlet-name>
        <servlet-class>cn.itcast.servlet.Hello3Servlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello3</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>
    
    3. <url-pattern>
    - <url-pattern> 是 <servlet-mapping> 的子元素, 用来指定 Servlet 的访问路径, 即 URL.
      它必须是以 "/" 开头!
    - 可以在 <servlet-mapping> 中给出多个 <url-pattern>
    - 还可以在 <url-pattern> 中使用通配符 "*"
    
    // <servlet-mapping> 中配置多个 <url-pattern>
    // 无论访问 /AServlet 还是访问 /BServlet, 访问的都是 AServlet
    <servlet-mapping>
            <servlet-name>AServlet</servlet-name>
            <url-pattern>/AServlet</url-pattern>
            <url-pattern>/BServlet</url-pattern>
    </servlet-mapping>
    
    // <url-pattern> 中使用通配符, 通配符要么为前缀, 要么为后缀, 不能出现在 URL 中间位置.
    <url-pattern>/servlet/*</url-pattern> :表示 /servlet/a, /servlet/b都匹配 /servlet/*; (路径匹配)
    
    <url-pattern> *.do</url-pattern> :表示 /abc/def/ghi.do, /a.do 都匹配 *.do;  (扩展名匹配)
    
    <url-pattern> /* </url-pattern>  : 表示匹配所有 URL;
    
    4. web.xml 文件
    - 每个完整的 JavaWeb 应用中都需要有 web.xml, 所有的 web.xml 文件都有一个共同的父文件,
      位置在 Tomcat 的 conf/web.xml .
    

    **参考资料:** - [JavaWeb 视频教程](https://www.bilibili.com/video/av12760389/index_2.html#page=3) - [JavaEE 6.0 文档](http://tool.oschina.net/apidocs/apidoc?api=javaEE6)
  • 相关阅读:
    L208
    L207
    L206
    L205 EE
    L204
    监控glusterfs
    监控elssticSearch健康状态
    防火墙
    创建逻辑卷
    编译安装nginx,并使用systemd管理nginx
  • 原文地址:https://www.cnblogs.com/linkworld/p/7577070.html
Copyright © 2011-2022 走看看