• JavaWeb核心之Servlet


    本节内容:

    • Servlet简介
    • Servlet的API
    • Servlet的配置
    • ServletContext对象

    一、Servlet简介

    1. 什么是Servlet

    Servlet是运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。但servlet的实质就是java代码,通过java的API 动态的向客户端输出内容。

    Servlet规范:包含三个技术点。或者说是servlet的三大组件。

    1. servlet技术
    2. filter技术(过滤器)
    3. listener技术(监听器)

    2. Servlet入门小例子

    实现步骤:
    (1)创建类实现Servlet接口
    (2)覆盖尚未实现的方法(重点实现service方法)
    (3)在web.xml进行servlet的配置

    Eclipse创建一个“Dynamic Web Project”,在src下创建一个包,然后在包里新建一个Servlet,目前我们只实现service方法。service代码如下:

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("QuickStratServlet running....");
        res.getWriter().write("QuickStratServlet running....");
    }

    WEB-INF/web.xml文件里添加配置:

    <!-- servlet的类的配置 -->
    <servlet>
      <servlet-name>abc</servlet-name>
      <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class>
    </servlet>
    <!-- servlet的虚拟路径的配置 -->
    <servlet-mapping>
      <servlet-name>abc</servlet-name>
      <url-pattern>/quickStratServlet</url-pattern>
    </servlet-mapping>

    右键项目,"Run As"——>"Run On Server",然后浏览器访问"http://localhost:8080/project_name/quickStratServlet"

    页面显示:

    QuickStratServlet running....

    Servlet访问过程:

     

    我们在创建Servlet时,默认是实现Servlet接口,但是该接口要实现的方法有很多,有init(ServletConfig config),service(ServletRequest request,ServletResponse response),destroy()等。   

    所以在实际开发中,我们不会直接去实现Servlet接口,因为那样需要覆盖的方法太多, 我们一般创建类继承HttpServlet。

    实现步骤:

    (1)创建类继承HttpServlet类
    (2)覆盖doGet和doPost
    (3)在web.xml中进行servlet的配置

    二、Servlet的API(生命周期)

    1. Servlet接口中的方法
    (1)init(ServletConfig config)
    何时执行:servlet对象创建的时候执行。因为接下来要调用service方法,该方法不是静态的,需要一个对象来调用,这个对象就是tomcat服务器帮我们创建的。
    ServletConfig : 代表的是该servlet对象的配置信息。

    (2)service(ServletRequest request,ServletResponse response)
    何时执行:每次请求,service方法都会执行。
    ServletRequest :代表请求。认为ServletRequest内部封装的是http请求的信息。
    ServletResponse :代表响应。认为要封装的是响应的信息。

    (3)destroy()
    何时执行:servlet对象销毁的时候执行。

    2. HttpServlet类的方法

    • init()
    • doGet(HttpServletRequest request,HttpServletResponse response)
    • doPost(HttpServletRequest request,HttpServletResponse response)
    • destroy()

    3. Servlet的生命周期

    一般面试的时候会问这个。

    (1)Servlet何时创建
    默认第一次访问servlet时创建该对象。可以通过配置让servlet对象不是第一次访问的时候创建,而是在服务器一启动时就创建。

    (2)Servlet何时销毁
    服务器关闭,servlet就销毁了。
    Servlet对象是存储在内存中,这个对象不是你创建的,而且tomcat服务器帮你创建的,你无法拿到它的引用。

    (3)每次访问必然执行的方法
    service(ServletRequest req, ServletResponse res)方法。

    三、Servlet的配置

    1. 基本配置

    <!-- servlet的类的配置 -->
    <servlet>
      <servlet-name>abc</servlet-name>
      <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class>
      <!-- 初始化参数示例 -->
      <init-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql:///mydb</param-value>
      </init-param>
    </servlet>
    <!-- servlet的虚拟路径的配置 -->
    <servlet-mapping>
      <servlet-name>abc</servlet-name>
      <url-pattern>/quickStratServlet</url-pattern>
    </servlet-mapping>


    其中url-pattern的配置方式有三种:
    (1)完全匹配。访问的资源与配置的资源完全相同才能访问到。

    <servlet-mapping>
      <servlet-name>abc</servlet-name>
      <url-pattern>/quickStratServlet</url-pattern>
    </servlet-mapping>

    (2)目录匹配 格式:/虚拟的目录../*   *代表任意

    <servlet-mapping>
      <servlet-name>abc</servlet-name>
      <url-pattern>/aaa/bbb/ccc/*</url-pattern>
    </servlet-mapping>

    (3)扩展名匹配 格式:*.扩展名

    <servlet-mapping>
      <servlet-name>abc</servlet-name>
      <url-pattern>*.abcd</url-pattern>
    </servlet-mapping>

    注意:第二种与第三种不要混用。比如:/aaa/bbb/*.abcd,这种配置方式是错误的。

    2. 服务器启动实例化Servlet配置
    Servlet何时创建:默认第一次访问时创建。
    当在servlet的配置上,加上一个配置 <load-on-startup>,servlet对象就会在服务器启动时就创建。配置示例如下:

    <!-- servlet的类的配置 -->
    <servlet>
      <servlet-name>abc</servlet-name>
      <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class>
      <!-- servlet在服务器启动时创建对象,默认是第一次访问时创建对象。该配置必须放在servlet所有配置的最下面。 -->
      <!-- 里面的数字1-5都可以。数字代表优先级,数字越小,优先级越高。在开发中,一般不要配置为1,配置为中间的数。 -->
      <load-on-startup>3</load-on-startup>
    </servlet>

    3. 缺省Servlet

    可以将url-pattern配置一个/,代表该servlet是缺省的servlet。

    什么是缺省的servlet?

    当你访问资源地址所有的servlet都不匹配时 ,缺省的servlet负责处理该请求。

    其实,web应用中所有的资源的响应都是servlet负责,包括静态资源请求。

    现在在WebContent下新建一个1.html,web.xml里的url-pattern只配置一个/,如下:

    <servlet>
      <servlet-name>abc</servlet-name>
      <servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>abc</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>

    浏览器输入http://localhost:8080/web13/1.html访问,你发现是访问的结果不是1.html的内容,而是QuickStratServlet的返回结果。

    而当我们注释了“缺省的servlet”配置,再次访问http://localhost:8080/web13/1.html就可以访问到1.html的内容了。这是为什么呢?打开tomcat配置文件conf/web.xml,这个web.xml是全局的web.xml,对在该tomcat下的所有web应用都适用,但是有个前提,如果全局的web.xml和web应用的web.xml里面某些配置有冲突,则使用web应用自己的web.xml里面的配置。打开tomcat全局的web.xml,查找"<url-pattern>/</url-pattern>",

    <!-- The mapping for the default servlet -->
    <servlet-mapping>
       <servlet-name>default</servlet-name>
       <url-pattern>/</url-pattern>
    </servlet-mapping>

    在找这个default对应的servlet:

    <servlet>
         <servlet-name>default</servlet-name>
         <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
         <init-param>
             <param-name>debug</param-name>
             <param-value>0</param-value>
         </init-param>
         <init-param>
             <param-name>listings</param-name>
             <param-value>false</param-value>
         </init-param>
         <load-on-startup>1</load-on-startup>
    </servlet>

    所以在访问1.html的时候,其实找的是org.apache.catalina.servlets.DefaultServlet,并不是直接找的1.html这个文件。DefaultServlet去应用的目录下寻找1.html这个文件, 把1.html逐句输出。如果没有找到1.html,会返回一个页面,显示404。这个页面也是DefaultServlet帮我们输出的。

    4. 欢迎页面

    我们在访问一个网站时,经常像这么访问,比如访问localhost:8080/web13/,后面什么资源都不写,这个时候会自动去找index.html,index.jsp或者其他的资源。这些都是可以在web.xml中配置的。

    如果在web应用的web.xml中没有配置<welcome-file-list></welcome-file-list>,你在访问localhost:8080/web13/时,这时就会去找tomcat全局的web.xml文件中该配置。

    <welcome-file-list>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>default.html</welcome-file>
      <welcome-file>default.htm</welcome-file>
      <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    四、ServletContext对象

    1. 什么是ServletContext对象
    ServletContext代表是一个web应用的环境(上下文)对象(可以理解为就是代表web应用),ServletContext对象内部封装的是该web应用的信息。一个web应用只有一个ServletContext对象。

    问题:一个web应用有几个servlet对象?多个。

    ServletContext对象的生命周期?
    创建:该web应用被加载(服务器启动或发布web应用,前提时服务器是启动状态)

    销毁:web应用被卸载(服务器关闭,移除该web应用)

    2. 怎样获得ServletContext对象

    两种方式:
    (1)ServletContext servletContext = config.getServletContext();    一般不用这种,比较麻烦。因为这个config是servlet的init方法里才有的。
    (2)ServletContext servletContext = this.getServletContext();

    3. ServletContext的作用

    (1) 获得web应用全局的初始化参数
    web.xml中配置初始化参数。比如配置如下:

    <context-param>
      <param-name>driver</param-name>
      <param-value>com.mysql.jdbc.Driver</param-value>
    </context-param>

    今后在学习spring的时候,spring加载配置文件,配置文件位置就可以通过类似上面的配置来配置。

    通过context对象获得参数:

    public class ContextServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //获得ServletContext对象
            ServletContext context = getServletContext(); //或者this.getServletContext()  this代表当前对象,不写也可以。
                                                        //这个方法在当前类中没有,找它爸爸HttpServlet也没有,找爷爷找到了
            //1、获得初始化参数
            String initParameter = context.getInitParameter("driver");
            System.out.println(initParameter);
            }
    }

    (2)获得web应用中任何资源的绝对路径

    方法:String path = context.getRealPath(相对于该web应用的相对地址);

    public class ContextServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //获得ServletContext对象
            ServletContext context = getServletContext();
            
            //2、获得a.txt b.txt c.txt d.txt的绝对路径。(这4个txt文件分别建在不同的目录)
            //发布时,tomcat下的webapps下,建一个文件夹名和项目名一一致。将项目下的WebConten下的全部资源放到WEB13目录下。
            //String path = context.getRealPath(相对于该web应用的相对地址);  
            //2.1 获得a.txt,a.txt建在WebContent目录下
            String realPath_A = context.getRealPath("a.txt");
            System.out.println(realPath_A);
            //2.2 获得b.txt,b.txt建在WEB-INF目录下
            String realPath_B = context.getRealPath("WEB-INF/b.txt");
            System.out.println(realPath_B);
            //2.3 获得c.txt,c.txt建在src目录下。src下面的源代码最终会被发布到WEB-INF/classes/目录下
            String realPath_C = context.getRealPath("WEB-INF/classes/c.txt");
            System.out.println(realPath_C);
            //2.4 获得d.txt。d.txt建在WEB13_servlet目录下。----获取不到
            
            //补充另外一个获取路径的方法
            //在读取src(classes) 下的资源时,还可以通过类加载器(专门加载classes下的文件的)。只是写的比较麻烦
            //getResource() 参数是一个相对地址 相对classes
            String path = ContextServlet.class.getClassLoader().getResource("c.txt").getPath();
            System.out.println(path);
        }
    }   

    (3)ServletContext是一个域对象

    什么是域对象?什么是域?

    域就是区域的意思,存储数据的区域就是域对象。

    ServletContext域对象的作用范围:整个web应用(所有的web资源都可以随意向 servletcontext域中存取数据,数据可以共享)

    【例子】:写两个Servlet,一个向ServletContext域对象中存数据,一个向ServletContext域对象中写数据。

    public class ContextServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //获得ServletContext对象
            ServletContext context = getServletContext(); 
            
            //3、域对象---向servletContext中存数据
            context.setAttribute("name", "zhangsan");
    
        }
    
    }
    向ServletContext域对象中存数据
    public class ContextServlet2 extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //域对象---从servletContext中取数据
            String attribute = (String) this.getServletContext().getAttribute("name");
            System.out.println(attribute);
        }
    
    }
    向ServletContext中取数据

    域对象的通用的方法:

    • setAtrribute(String name,Object obj);
    • getAttribute(String name);
    • removeAttribute(String name);
  • 相关阅读:
    写一个精确定位异常的方法
    做一个牛XX的身份证号验证类(支持15位和18位)
    C#获取设备的IP和Mac类
    winfrom 倒计时控件
    一个实用价值很大的人脸关键点检测算法PFLD
    刷新WIDER Face纪录!TinaFace:人脸检测新网络,代码已开源!
    虚拟机安装教程
    python---文件路径的操作(有点意思)
    python_opencv -------->>>>>>>>>cv2.warpAffine()参数详解
    yolov5数据增强引发的思考——透视变换矩阵的创建
  • 原文地址:https://www.cnblogs.com/zhaojiankai/p/7806081.html
Copyright © 2020-2023  润新知