zoukankan      html  css  js  c++  java
  • Servlet

    Servlet

    • 整个JavaWeb的核心知识体系都是围绕 Servlet 来转的

    概述

    • 概念:运行在服务器端的小程序 Service Applet
      • Servlet就是一个接口,定义了 Java类被浏览器访问到(被tomcat识别)的规则
      • 将来我们定义一个类,实现 Servlet接口,复写方法,这个类就是Servlet

    Servlet概述

    快速入门

    1. 创建Java EE项目

    2. 定义一个类,实现Servlet接口

      • public class ServletDemo1 implements Servlet
    3. 实现接口中的抽象方法

    4. 配置Servlet,在web.xml中配置

    <!-- 配置Servlet -->
        <servlet>
            <servlet-name>demo1</servlet-name>
            <servlet-class>com.my.web.servlet.ServletDemo1</servlet-class>
    </servlet>
    
        <servlet-mapping>
            <servlet-name>demo1</servlet-name>
            <url-pattern>/demo1</url-pattern>
        </servlet-mapping>
    

    Tomcat 执行 Servlet 的原理(过程)

    1. 当服务器接受到客户端浏览器的请求后,会解析请求的URL路径,获取访问的Servlet的资源路径。
    2. 查找 web.xml文件,是否有对应的 <url-pattern> 标签体内容
    3. 如果有,根据<servlet-name>,再找到对应的 <servlet-class> 全类名
      • 如果在配置文件中出现 全类名 ,想到反射
    4. tomcat会将字节码文件加载进内存(Class.forName("全类名")),并且创建其对象
    5. 调用其方法
    • Servlet 执行原理:

    Servlet_执行原理

    Servlet 中的生命周期

    1. 被创建:执行 init 方法,执行一次

      1. Servlet什么时候被创建?

        • 在默认情况下,第一次被访问时,Servlet被创建
        • 可以配置指定执行 Servlet 的创建时机,在<servlet>标签下配置
          1. 在默认情况下,第一次被访问时,创建
            • <load-on-startup>的值为 负整数
          2. 在服务器启动时,创建
            • <load-on-startup>的值为 0 或 正整数
      2. Servlet的 init 方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的

        • 多个用户同时访问时,可能存在线程安全问题。
        • 解决:尽量不要在 Servlet中定义成员变量。即使定义了成员变量,也不要对其修改值。
    2. 提供服务:执行 service 方法,执行多次

      • 每次访问Servlet时,service方法都会被调用一次。
    3. 被销毁:执行 destory 方法,只执行一次

      • Servlet被销毁时执行。服务器关闭时,Servlet被销毁
      • 只有服务器正常关闭时,才会执行 destory 方法
      • destory 方法在 Servlet被销毁之前执行,一般用于释放资源
    • web.xml
    <?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>
            <servlet-name>demo1</servlet-name>
            <servlet-class>com.my.web.servlet.ServletDemo1</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>demo1</servlet-name>
            <url-pattern>/demo1</url-pattern>
        </servlet-mapping>
    
        <!-- 配置Servlet -->
        <servlet>
            <servlet-name>demo2</servlet-name>
            <servlet-class>com.my.web.servlet.ServletDemo2</servlet-class>
            <!--指定Servlet的创建时机
                1.在默认情况下,第一次被访问时,创建
                    * <load-on-startup>的值为负整数
                2.在服务器启动时,创建
                    * <load-on-startup>的值为 0 或 正整数
            -->
            <load-on-startup>6</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>demo2</servlet-name>
            <url-pattern>/demo2</url-pattern>
        </servlet-mapping>
    </web-app>
    
    
    • ServletDemo2.java
    package com.my.web.servlet;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    /**
     * Servlet的方法
     */
    
    public class ServletDemo2 implements Servlet {
    
        /**
         * 初始化方法
         * 在 Servlet被创建时,执行。只会执行一次
         *
         * @param servletConfig
         * @throws ServletException
         */
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("init...");
        }
    
        /**
         * 获取 ServletConfig对象
         * ServletConfig:Servlet的配置对象
         *
         * @return
         */
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        /**
         * 提供服务的方法
         * 每一次Servlet被访问时,执行。执行多次
         *
         * @param servletRequest
         * @param servletResponse
         * @throws ServletException
         * @throws IOException
         */
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("service...");
        }
    
        /**
         * 获取Servlet的一些信息,版本,作者等等...
         *
         * @return
         */
        @Override
        public String getServletInfo() {
            return null;
        }
    
        /**
         * 销毁方法
         * 在服务器正常关闭时,执行。执行一次
         */
        @Override
        public void destroy() {
            System.out.println("destory...");
        }
    }
    

    Servlet 3.0

    • 好处:
      • 支持注解配置。可以不需要 web.xml了。
    • 步骤:
      1. 创建JavaEE项目,选择 Servlet 的版本 3.0以上,可以不创建 web.xml
      2. 定义一个类,实现 Servlet 接口
      3. 覆盖重写 Servlet接口中的方法
      4. 在类上使用 @WebServlet 注解,进行配置
        • @WebServlet("Servlet 资源路径")
        • 如:@WebServlet("/demo")

    Servlet 体系结构

    	Servlet			-- 接口
    	  |		
    	GenericServlet	-- 抽象类
    	  |
    	HttpServlet 	-- 抽象类
    
    • GenericServlet:将 Servlet 接口中的其他方法做了默认空实现,只将 service()方法作为抽象方法
      • 将来定义 Servlet类时,可以继承 GenericServlet,实现 service()方法即可
    • HttpServlet:对 http协议的一种封装,简化操作
      1. 定义类继承 HttpServlet
      2. 覆写 doGet / doPOst 方法

    总结:

    实现 Servlet 接口,需要覆盖重写 其中的五个抽象方法
    GenericServlet 实现了 Servlet接口,对其中除 service方法外,做了空处理,我们只需要覆写 service方法即可。
    但是 当用户提交数据时,我们需要判断提交的方式,是get,还是post,还是其他
    sun公司编写了一个抽象类 HttpServlet 继承自 GenericServlet,也是一个抽象类,但对 service方法做了处理,可以判断请求的方式是何种,不需要我们进行判断请求方式。

    // 判断请求方式
    String method = req.getMethod();
    if ("GET".equals(method)) {
    	// get方式获取数据
    	doGet();
    } else if ("POST".equals(method)) {
    	// post方式获取数据
    	doPost();
    }
    

    所以我们只需重写 doGet() 方法或者 doPost() 方法即可

    示例:

    • ServletDemo3.java
    @WebServlet("/demo3")
    public class ServletDemo3 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doGet...");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doPost...");
        }
    }
    
    • login.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Login</title>
    </head>
    <body>
    
    <form action="/demo3" method="post">
        <input name="username">
        <input type="submit" value="提交">
    </form>
    
    </body>
    </html>
    

    Servlet 相关配置

    1. urlpartten:Servlet访问路径
      1. 一个Servlet可以定义多个访问路径:
      2. 路径定义规则:
        1. /xxx
          2./xxx/xxx:多层路径,目录结构
        2. .后缀名
    • 示例:
    //@WebServlet("/demo4")
    @WebServlet({"/d4", "/dd4", "/ddd4"})
    //@WebServlet("/user/demo4")
    //@WebServlet("*.do") // * 前面不要加 /
    //@WebServlet("/demo4/*")
    public class ServletDemo4 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("demo4...");
        }
    }
    

    ServletContext对象

    1. 概念:这个对象代表整个web应用,可以和程序的容器(服务器)来通信

    2. 获取

      • 1.通过request对象获取
        • request.getServletContext();
      • 2.通过HttpServlet获取
        • this.getServletContext();
    3. 功能:

      1. 获取MIME类型

        • MIME类型:在互联网通信过程中定义的一种文件数据类型
          • 格式:大类型/小类型 text/html image/jpeg
    • 获取:String getMimeType(String file)

      1. 域对象:共享数据
        1. setAttribute(String name, Object value)
        2. getAttribute(String name)
        3. removeAttribute(String name)
      • ServletContext对象范围:所有用户所有请求的数据
      1. 获取文件的真实(服务器)路径
    // 通过HttpServlet获取ServletContext对象
    ServletContext context = this.getServletContext();
    
    // 获取文件的服务器路径
    String realPath = context.getRealPath("/b.txt"); // web目录下的资源访问
    System.out.println(realPath);
    
    String c = context.getRealPath("/WEB-INF/c.txt"); // WEB-INF目录下的资源访问
     System.out.println(c);
    
    /*
         将来src目录下的资源都会放到web/WEB-INF/classes目录下
         也可以使用类加载器获取src目录下的资源,但类加载器只能获取src目录下,不能获取到web目录下,受限
    */
    String a = context.getRealPath("/WEB-INF/classes/a.txt");// src目录下的资源访问
    System.out.println(a);
    
  • 相关阅读:
    Ubuntu apt常用命令
    PHP 图片操作(按照指定尺寸压缩,按照比例裁剪)
    Django简介
    浅议SNMP安全、SNMP协议、网络管理学习
    Linux下dmesg命令处理故障和收集系统信息的7种用法
    syslog之三:建立Windows下面的syslog日志服务器
    syslog之二:syslog协议及rsyslog服务全解析
    syslog之一:Linux syslog日志系统详解
    syslog简单配置介绍
    ethtool工具使用实例
  • 原文地址:https://www.cnblogs.com/rainszj/p/12188665.html
Copyright © 2011-2022 走看看