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);
原文地址:https://www.cnblogs.com/zhaojiankai/p/7806081.html