zoukankan      html  css  js  c++  java
  • JavaWeb之Servlet一

    作者:刘婧怡

    时间:2019.03.27

    主机环境:MacBookPro


     

    Servlet

    1. Servlet简介

    • Servlet是JavaWeb的三大组件之一,属于动态资源

    • Servlet的功能

      • 接受请求数据

      • 处理请求:每个Servlet都是唯一的,能处理的请求都是不同的

      • 完成响应

    • Servlet需要我们自己编写

    2. 实现Servlet的方式(三种)

    • 实现javax.servlet.Servlet接口

    • 继承javax.servlet.GenericServlet类

    • 继承javax.servlet.http.HttpServlet类,它是GenericServlet的子类

     

    3. Servlet接口

    • 接口中的方法,生命周期方法是Tomcat自动调用的方法

    publicclassMyServletimplementsServlet{
       
       //是生命周期方法
       //会在Servlet对象被创建后马上执行,并只执行一次
       publicvoidinit(ServletConfigservletConfig) throwsServletException;
       
       //可以用来获取Servlet的配置信息
       publicServletConfiggetServletConfig();
    ​
       //是生命周期方法
       //会被调用多次
       //每次处理请求都会被调用
       publicvoidservice(ServletRequestservletRequest, ServletResponseservletResponse) throwsServletException, IOException;
       
       //可以获取Servlet的信息
       publicStringgetServletInfo();
       
       //是生命周期方法
       //会在Servlet被销毁之前调用,并且只会被调用一次
       //该方法不能销毁Servlet
       publicvoiddestroy();
    }
    ​
    • 在web.xml文件中配置Servlet

    <servlet>
           <!--xxx可以随便写-->
           <servlet-name>xxx</servlet-name>
           <servlet-class>servlet.MyServlet</servlet-class>
    </servlet><servlet-mapping>
           <servlet-name>xxx</servlet-name>
           <!--必须以/开头,后面随便写-->
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>
    • ServletConfig接口 

      • 一个ServletConfig对象对应一段web.xml中的Servlet配置信息

      • API:

        • String getServletName():获取<servlet.name>的内容

        • ServletContext getServletContext():获取Servlet上下文的对象

        • String getInitParament():通过名称获取指定初始化参数的值

        • Enumeration getInitParamentName():获取所有初始化参数的名称

    <servlet>
       <servlet-name>One</servlet-name>
       <servlet-class>cn.itcast.servlet.OneServlet</servlet-class>
       <init-param>
        <param-name>paramName1</param-name>
         <param-value>paramValue1</param-value>
       </init-param>
       <init-param>
         <param-name>paramName2</param-name>
         <param-value>paramValue2</param-value>
       </init-param>
     </servlet>

     

    4. GenericServlet类

    • GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet。

      下面是GenericServlet类的源代码

    public abstract class GenericServlet implements Servlet, ServletConfig,
            java.io.Serializable 
    {
        private static final long serialVersionUID = 1L;
        
        private transient ServletConfig config;
        
        public GenericServlet() {}
        
        @Override
        public void destroy() {}
        
        @Override
        public String getInitParameter(String name) {
            return getServletConfig().getInitParameter(name);
        }
        
        @Override
        public Enumeration<String> getInitParameterNames() {
            return getServletConfig().getInitParameterNames();
        }
        
        @Override
        public ServletConfig getServletConfig() {
            return config;
        }
        
        @Override
        public ServletContext getServletContext() {
            return getServletConfig().getServletContext();
        }
        
        @Override
        public String getServletInfo() {
            return "";
        }
        
        @Override
        public void init (ServletConfig config) throws ServletException {
            this.config = config;
            this.init();
        }
        
        public void init () throws ServletException {}
        
        public void log(String msg) {
            getServletContext().log(getServletName() + ": " + msg);
        }
        
        public void log(String message, Throwable t) {
            getServletContext().log(getServletName() + ": " + message, t);
        }
        
        @Override
        public abstract void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException;
                
        @Override
        public String getServletName() {
            return config.getServletName();
        }
    }
    • init()方法

      • init()方法是用来在继承GenericServlet类时,解决想要覆盖init(ServletConfig config)方法忘记给config赋值的问题。此时,只需要覆盖init()方法即可。

      • init()方法不是生命周期方法,但想要在构造Servlet时让Tomcat调用该方法,需要在init(ServletConfig config)中调用init()方法

    • GenericServlet实现了所有ServletConfig的方法。

     

    5. HttpServlet类

    • HttpServlet是GenericServlet的子类,它提供了对HTTP请求的特殊支持,所以通常我们都会通过继承HttpServlet来完成自定义的Servlet。

    • HttpServlet覆盖了service()方法

      • HttpServlet中有两个service()方法,一个service(ServletRequest,ServletResponse),另一个为service(HttpServletRequest,HttpServletResponse),前者为覆盖,后者不是覆盖。

      • service(ServletRequest,ServletResponse)是生命周期方法,由Tomcat自动调用,在该方法中

        • 首先对两个参数强制转换,将类型转换为Http协议相关的类型,

        • 再调用service(HttpServletRequest,HttpServletResponse)方法,

        • 该方法会通过request得到当前请求的请求方式(GET或POST),

        • 再根据请求方式调用相应的doGet()和doPost()方法。

      • 所以,不用重写service()方法只需要重写doGet()和doPost()方法如果没有覆盖doGet()和doPost()方法,并且被调用了,会出现405。

     

    6. Servlet细节

    • Servlet只有一个实例对象,就有可能会现时出一个Servlet同时处理多个请求

      Servlet不是线程安全的。这说明Servlet的工作效率很高,但也存在线程安全问题!所以我们不应该在Servlet中随便创建成员变量,因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作。

      做到以下几点:

      • 不要在Servlet中创建成员,创建局部变量即可

      • 可以创建无状态成员,即只声明

      • 可以创建有状态的成员,但状态必须为只读的

    • 默认情况下,服务器会在某个Servlet第一次收到请求时创建它。也可以在web.xml中对Servlet进行配置,使服务器启动时就创建Servlet。

    <servlet>
    <servlet-name>hello1</servlet-name>
    <servlet-class>cn.itcast.servlet.Hello1Servlet</servlet-class>
    <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>hello1</servlet-name>
    <url-pattern>/hello1</url-pattern>
    </servlet-mapping><servlet>
    <servlet-name>hello2</servlet-name>
    <servlet-class>cn.itcast.servlet.Hello2Servlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

      <load-on-startup>中,给出一个非负整数。值小的先被创建,即hello1先创建,hello2后创建。

    • <url-pattern>

      • 用来指定Servlet的访问路径,可以在<servlet-maping>中有多个

      • 可以使用通配符*,通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符

        路径匹配:<url-pattern>/servlet/*</url-pattern>,可以匹配/servlet/a、/servlet/b等

        扩展名匹配:<url-pattern>*.do</url-pattern>,可以匹配/abc/def/ghi.do、/a.do等

        啥都匹配:<url-pattern>/*</url-pattern>,可以匹配所有url

    • web.xml文件的“继承”

      • 每一个JavaWeb应用都有一个web.xml,都“继承”conf/web.xml

    <?xmlversion="1.0" encoding="ISO-8859-1"?><web-appxmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     version="3.0">
        <servlet>
           <servlet-name>default</servlet-name><!--他的优先级最低,如果请求没人处理,那么它就会来处理,显示404-->
           <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><servlet>
           <servlet-name>jsp</servlet-name>
           <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
           <init-param>
               <param-name>fork</param-name>
               <param-value>false</param-value>
           </init-param>
           <init-param>
               <param-name>xpoweredBy</param-name>
               <param-value>false</param-value>
           </init-param>
           <load-on-startup>3</load-on-startup>
       </servlet><servlet-mapping>
           <servlet-name>default</servlet-name>
           <url-pattern>/</url-pattern>  <!--没有url能匹配上,就会匹配这个-->
       </servlet-mapping><servlet-mapping>
           <servlet-name>jsp</servlet-name>
           <url-pattern>*.jsp</url-pattern>
           <url-pattern>*.jspx</url-pattern>
       </servlet-mapping><session-config>  <!--session的过期时间为30分钟-->
           <session-timeout>30</session-timeout>
       </session-config><!-- 这里省略了大概4000多行的MIME类型的定义,这里只给出两种MIME类型的定义 -->
       <mime-mapping>
           <extension>bmp</extension>
           <mime-type>image/bmp</mime-type>
       </mime-mapping>
       <mime-mapping>
           <extension>htm</extension>
           <mime-type>text/html</mime-type>
       </mime-mapping><welcome-file-list>
           <welcome-file>index.html</welcome-file>
           <welcome-file>index.htm</welcome-file>
           <welcome-file>index.jsp</welcome-file>
       </welcome-file-list>
    </web-app>
     

    7. ServletContext

    • 概述

      • 一个项目只有一个ServletContext对象,我们可以在很多个Servlet中来获取这个唯一的对象,使用它可以给Servlet传递数据,完成共享数据。

      • ServletContext对象在Tomcat启动时创建,在Tomcat关闭时销毁

    • 获取ServletContext

      在Servlet接口中,init(ServletConfig config)方法可以获取ServletConfig对象,该对象有getServletContext()方法可以获取ServletContext对象

    public class MyServlet implements Servlet {
        public void init(ServletConfig config) {    
            ServletContext context = config.getServletContext();
        }
        …
    }    
      在GenericServlet类中,有成员变量ServletConfig,有getServletContext()方法可以获取ServletContext对象
    public class MyServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) {
        ServletContext context = this.getServletContext();
      }
    }
    • 域对象的功能

      • 域对象是用来在多个Servlet中传递数据,所以域对象必须要有存和取数据的功能。JavaWeb中包含四个域对象,分别是ServletContext、PageContext、HttpSession、ServletRequest

      • ServletContext对象用来操作数据的方法

        • void setAttribute(String name, Object value):用来存储一个对象,相当于在ServletContext中有一个Map对象,所以在存储时name值不能相同

        • Object getAttribute(String name):用来获取数据,因为返回值为Object对象,需要强制转换

        • void removeAttribute(String name):删除一个对象

        • Enumeration getAttributeNames():获取所有域属性的名称

    • 获取初始化参数

      • Servlet也可以获取初始化参数,但它只能获取局部的初始化参数,即只能获取自己的初始化参数

      • 使用ServletContext可以配置公共的初始化参数

    <web-app...>
    ...
     <context-param>
    <param-name>paramName1</param-name>
    <param-value>paramValue1</param-value>
     </context-param>
     <context-param>
    <param-name>paramName2</param-name>
    <param-value>paramValue2</param-value>
     </context-param>
    </web-app>
    ServletContext context = this.getServletContext();
    String value1 = context.getInitParameter("paramName1");
    String value2 = context.getInitParameter("paramName2");
    System.out.println(value1 + ", " + value2);
    • 获取相关资源的方法

      • 获取真实路径

        • 获取a.txt的真实路径String realPath = this.getServletContext.getRealPath("/a.txt");

        • windows系统下这种方法获取的路径是代盘符的

      • 获取资源流

        • 获取a.txt的t资源流:InputStream in = this.getServletContext.getResourceAsStream("/a.txt");

      • 获取指定目录下所有资源路径

        • 获取/WEB-INF下所有资源的路径:Set set = this.getServletContext.getResourcePaths("/WEB-INF");

  • 相关阅读:
    Shell Script-读取配置文件
    [LeetCode]题解(python):048-Rotate Image
    [LeetCode]题解(python):043-Multiply Strings
    暑假学习记录(七)
    暑期学习记录(六)
    暑假学习记录(五)
    暑假学习记录(四)
    暑假学习记录(三)
    暑假学习记录(二)
    暑假学习记录(一)
  • 原文地址:https://www.cnblogs.com/jyliu/p/10606657.html
Copyright © 2011-2022 走看看