• JavaWeb学习笔记三 Servlet


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

    servlet规范:包含三个技术点,它们是 servlet技术;filter(过滤器)技术;listener(监听器)技术。

    Servlet快速入门

    实现步骤:

    1. 创建类实现Servlet接口
    2. 覆盖尚未实现的方法---service方法
    3. 在web.xml进行servlet的配置

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

    实现步骤:

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

    画图描述整个访问过程:

     

     下面来看看Servlet长什么样子

    代码演示:

    public class AServlet extends HttpServlet {
    
    }

    发现HttpServlet在IDEA中不能导包,百度了一下,IntelliJ IDEA 没有导入 servlet-api.jar 这个jar包,需要你手动导入支持。具体导包过程如下:

    点击右上方那个蓝色按钮(project structure 项目结构)——>点击Libraries——>点击上面的加号——>点击Java

    然后再弹出框中找到Tomcat安装路径下的lib文件夹中的Servlet.api这个文件,添加就好了。

    在Intellij idea中快速重写HttpServlet

    鼠标左击以确定代码插入的位置,使用快捷键CTRL+O,会弹出窗口让选择某个方法,我们选择覆盖doGet和doPost方法,然后输出一句话。

    package servletDemo;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * Created by Administrator on 2017/7/21.
     */
    public class AServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("My First Servlet");
        }
    }
    AServlet

    配置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-name>AServlet</servlet-name>
            <servlet-class>servletDemo.AServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>AServlet</servlet-name>
            <url-pattern>/AServlet</url-pattern>
        </servlet-mapping>
    </web-app>
    web.xml

    运行报错:Tomcat启动服务报错:Unknown version string [3.1]. Default version will be used.解决方式参考这里

    然后运行,在浏览器输入:http://localhost:8080/AServlet,界面出现:

    My First Servlet

    到此,我们的第一个Servlet就成功了。

     Servlet的API(生命周期)

    Servlet接口中的方法

    package servlet.demo;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    /**
     * Created by yang on 2017/7/23.
     */
    public class SecondServlet implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
    
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
    
        }
    }
    SecondServlet .java
    • init(ServletConfig config):servlet对象创建的时候执行,ServletConfig 代表的是该servlet对象的配置信息
    • service(ServletRequest request,ServletResponse response):每次请求都会执行

    ServletRequest :代表请求,ServletRequest 内部封装的是 http请求的信息

    ServletResponse :代表响应,封装的是响应的信息

    • destroy():servlet销毁的时候执行
    • getServletInfo: 获得servlet的信息(版本,作者,版权..),没什么用.
    • getServletConfig:返回servletConfig对象.

     HttpServlet类的方法

    package servlet.demo;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by yang on 2017/7/23.
     */
    public class ServletDemo03 extends HttpServlet{
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doGet(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    
        @Override
        public void destroy() {
            super.destroy();
        }
    
    }
    ServletDemo03
    • init()
    • doGet(HttpServletRequest request,HttpServletResponse response)
    • doPost(HttpServletRequest request,HttpServletResponse response)
    • destroy()

    Servlet的生命周期

    Servlet何时创建?默认第一次访问servlet时创建该对象

    Servlet何时销毁?服务器关闭servlet就销毁了

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

    问题:对XXXServlet进行了10次访问,init(),destory(),service(),doGet(),doPost() 一共执行力多少次?request对象创建几个?response创建几个?

    答案:init(),1次;destory(),服务器没有关闭, 不执行;service(),10次;request对象创建10个;response创建10个

    Servlet的配置

    基本配置

    其中url-pattern的配置方式:

    • 完全匹配 访问的资源与配置的资源完全相同才能访问到

    • 目录匹配 格式:/虚拟的目录../* ,*代表任意

    • 扩展名匹配 格式:*.扩展名

    注意:1、关于路径,配置的路径匹配范围越大优先级越低;2、目录匹配与扩展名匹配不要混用,比如: /aaa/bbb/*.abcd(这是错误的)

    ServletConfig对象

    ServletConfig封装了servletweb.xml中的配置.

    比如web.xml参数配置如下:

    <init-param>
        <param-name>name</param-name>
        <param-value>tom</param-value>
    </init-param>

    方法:

    //获得servlet的name(获得配置文件中<servlet-name>元素的内容)
    String servletName =getServletConfig().getServletName();
    
    //获取init-param中的所有参数(返回所有<param-name> )
    Enumeration<String> en = getServletConfig().getInitParameterNames();
    while(en.hasMoreElements()){
      String key = en.nextElement();
      //根据键获取值(根据<init-param>中的<param-name>获得</param-value>
      String value = getServletConfig().getInitParameter(key);)
      res.getWriter().print(key+"==>"+value+"<br/>");
    }

    服务器启动实例化Servlet配置

    Servlet何时创建:默认第一次访问时创建。为什么是默认?当在servlet的配置时,加上一个配置 <load-on-startup> ,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>
        <load-on-startup>3</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>abc</servlet-name>
        <url-pattern>/quickStratServlet</url-pattern>
      </servlet-mapping>

    1、load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。

    2、它的值必须是一个整数,表示servlet应该被载入的顺序

    3、当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;

    4、当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。

    5、正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

    6、当值相同时,容器就会自己选择顺序来加载。

    所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。欲知更多请参考这里

    缺省Servlet

    可以将url-pattern配置一个/,代表该servlet是缺省的servlet。什么是缺省的servlet?当你访问资源地址所有的servlet都不匹配时 , 缺省的servlet负责处理。其实,web应用中所有的资源的响应都是servlet负责,包括静态资源。

    欢迎页面

     

    ServletContext对象

    ServletContext代表的是一个web应用的环境(上下文)对象,ServletContext对象内部封装是该web应用的信息,ServletContext对象一个web应用只有一个。那么一个web应用有几个servlet对象?很多个。

    ServletContext对象的生命周期

    创建:该web应用被加载(服务器启动或发布web应用(前提,服务器为启动状态))

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

    获得ServletContext对象

    1、ServletContext servletContext = config.getServletContext();

    2、ServletContext servletContext = this.getServletContext();

    ServletContext的作用

    1、获得web应用全局的初始化参数,方法:

    getInitParameterNames();  ==> 获得所有键
    
    getInitParameter(key);  ==> 根据键获得对应的值

    比如:web.xml中配置初始化参数

     <!--配置全局的初始化参数-->
        <context-param>
            <param-name>driver</param-name>
            <param-value>com.mysql.jdbc.Driver</param-value>
        </context-param>

    则可以通过context对象获得参数 

    ServletContext context= getServletContext();
    String initValue= context.getInitParameter("driver");
    resp.getWriter().print(initValue);//com.mysql.jdbc.Driver

    2、获得web应用中任何资源的绝对路径,此功能很重要。方法:

    getRealPath  ==> 通过相对路径获得绝对路径
    getResourceAsStream ==> 根据相对路径获得指定资源流

    context.getRealPath(相对于该web应用的相对地址);

    ServletContext sc = getServletContext();
    //getResourceAsStream ==> 填写相对路径即可, 相对的是webRoot下
    InputStream is = sc.getResourceAsStream("/WEB-INF/students.xml");
    System.out.println(is);//java.io.ByteArrayInputStream@2d83e895
                    
    String path = sc.getRealPath("/WEB-INF/students.xml");
    System.out.println(path);
    //F:编程语言JavaProjectToolsapache-tomcat-7.0.52webappsDay07-servletWEB-INFstudents.xml Set set = sc.getResourcePaths("/"); for(Object obj : set){ System.out.println(obj); } // /index.jsp // /WEB-INF/ // /MyHtml.html // /META-INF/

    String path2= sc.getResource("/WEB-INF/students.xml").getPath(); System.out.println(path2); //  /localhost/Day07-servlet/WEB-INF/students.xml
    //获得lib目录下的资源
    getServletContext().getRealPath("/WEB-INF/lib/students.xml");
    //获得src下的资源==> 获得classes目录下的资源
    getServletContext().getRealPath("/WEB-INF/classes/students.xml");
    //获得cn.itcast.servlet.servlet_context包下的资源
    getServletContext().getRealPath("/WEB-INF/classes/cn/itcast/servlet/servlet_context/students.xml");
    //---------------------------------------------------------------------------
    //如果获得的是包下的,那么使用上面的方式太麻烦了.可以使用以下方式:
    //一:使用getClass().getResourceAsStream方法,相对路径分为两种情况
        //1: 加"/"  ==> 相对的是classes目录
        //2: 不加"/" ==>相对的是本类当前目录
    InputStream is = this.getClass().getResourceAsStream("students.xml");
    System.out.println(is);
    
    //二:使用this.getClass().getClassLoader().getResourceAsStream("");获得 //只有一个相对路径 ==> 就是相对于 classes目录 InputStream is2 = this.getClass().getClassLoader().getResourceAsStream("students.xml"); System.out.println(is2); //注意:
    //1、使用类和类加载器加载资源文件时,
    jvm运行期间只加载一次.一旦加载完毕后,就会存放在虚拟机内存中,直到虚拟机关闭,所以文件路径更改,也还是之前的路径,可以使用下面的代码可以解决这个问题. String path = this.getClass().getClassLoader().getResource("students.xml").getPath(); File file = new File(path.substring(1, path.length())); System.out.println(path); //getClassLoader()原本是用来加载.class文件的, 所以缓存设计的很小.不要用他加载一些别较大的资源.

    3、ServletContext是一个域对象,此功能很重要。

    什么是域对象?什么是域?存储数据的区域就是域对象。

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

    域对象的通用的方法

    放入键值对 setAttribute(key,value)
    通过键取值 getAttribute(key)
    通过键删除 removeAttribute(key)
    遍历所有键 getAttributeNames()
    //通过servletContext设置值
    sc.setAttribute("bag", "Calvin Klein");
    sc.setAttribute("car", "BMW");
    sc.setAttribute("passport", "HAWAII");
    //通过servletContext取值
    String bag = (String) sc.getAttribute("bag");
    //不喜欢,扔掉(删除)
    sc.removeAttribute("bag");
    //遍历
    Enumeration<String> en = sc.getAttributeNames();
    while(en.hasMoreElements()){
        String key = en.nextElement();
         Object value =  sc.getAttribute(key);
         System.out.println(key +"==>"+value);
    }        
  • 相关阅读:
    centos8重置root密码
    Mysql查询某列最长字符串记录
    ssm连接mysql出现Connections could not be acquired from the underlying database 问题
    spring-基于xml配置Bean
    WinForm控件命名缩写
    SQL Server 将一张表的某个字段更新到另一张表中
    SQL Server 取出指定字符后字符串(用于分割)
    小白学CMD下运行MySQL
    Bootstrap3.0和bootstrap2.x的区别
    有关js弹出提示框几种方法
  • 原文地址:https://www.cnblogs.com/ginb/p/7219259.html
Copyright © 2020-2023  润新知