侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

绿泡泡:___zze,添加备注来意

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

JavaWeb(2)之Servlet入门

zze
zze
2017-05-21 / 0 评论 / 0 点赞 / 744 阅读 / 7096 字

Hello Servlet

方式一:实现 Servlet 接口

1、新建 web 工程,编写一个类,实现 javax.servlet.Servlet 接口:

package com.zze.servlet;

import javax.servlet.*;
import java.io.IOException;

public class HelloServlet1 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 {
        servletResponse.getWriter().write("Hello Servlet1!!!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

2、在 WEB-INF/web.xmlweb-app 节下加入如下配置:

<servlet>
<!--给Servlet起名-->
<servlet-name>HelloServlet1</servlet-name>
<!--Servlet地址-->
<servlet-class>com.zze.servlet.HelloServlet1</servlet-class>
</servlet>

<servlet-mapping>
<!--配置Servlet映射,该名称对应上面已定义的Servlet名-->
<servlet-name>HelloServlet1</servlet-name>
<!--访问时的路径-->
<url-pattern>/hello1</url-pattern>
</servlet-mapping>

3、接下来就可以启动服务,访问 localhost:8080/hello1
image.png

方式二:继承 HttpServlet 类

1、同方式一类似,因为 Tomcat 本身就为我们提供了 javax.servlet.Servlet 的实现类: javax.servlet.http.HttpServlet,所以我们直接继承它,重写我们要使用的方法即可:

package com.zze.servlet;

import java.io.IOException;

public class HelloServlet2 extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        response.getWriter().write("hello Servlet2!!!");
    }
}

2、同方式一,在 WEB-INF/web.xmlweb-app 加入配置:

<servlet>
    <servlet-name>HelloServlet2</servlet-name>
    <servlet-class>com.zze.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HelloServlet2</servlet-name>
    <url-pattern>/hello2</url-pattern>
</servlet-mapping>

3、重启 Tomcat ,访问 localhost:8080/hello2
image.png

Servlet 的执行流程

执行流程

创建 Servlet 如下,并加入配置:

package com.zze.servlet;

import javax.servlet.*;
import java.io.IOException;

public class TestServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("from init");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("from getServletConfig");
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("from service");
    }

    @Override
    public String getServletInfo() {
        System.out.println("from getServletInfo");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("from destroy");
    }
}

访问该 Servlet,接着通过 shutdown.bat 关闭 tomcat, 查看输出结果如下:

from init
from service
from destroy

结论:

  1. 当 Servlet 被访问时,会先执行它的 init 方法,接着才是执行 service 方法,最后执行 destroy 方法。
  2. init 方法只有在程序启动后第一次访问时才会执行,service 方法会在每次访问时执行。
  3. destroy 执行有两种情况:第一种是通过 tomcat 的 shutdown.bat 脚本关闭 tomcat 时会执行,第二种情况是将程序从 tomcat 中移除时会执行。

提前 init 方法的执行时机

可以通过在 servlet 节下加入 load-on-startup 节让指定 Servlet 实例的 init 方法在程序启动时执行,如下:

// com.zze.servlet.TestServlet1
package com.zze.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class TestServlet1 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("form TestServlet1.init");
    }
}
// com.zze.servlet.TestServlet2
package com.zze.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class TestServlet2 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("form TestServlet2.init");
    }
}
<!-- WEB-INF/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_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>testServlet1</servlet-name>
        <servlet-class>com.zze.servlet.TestServlet1</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>testServlet2</servlet-name>
        <servlet-class>com.zze.servlet.TestServlet2</servlet-class>
        <load-on-startup>6</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>testServlet1</servlet-name>
        <url-pattern>/test1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>testServlet2</servlet-name>
        <url-pattern>/test2</url-pattern>
    </servlet-mapping>
</web-app>

启动程序,查看控制台输出:

form TestServlet1.init
form TestServlet2.init

结论:

  1. 只要 servlet 节下指定了 load-on-startup,那么在程序启动时这个节对应的 Servlet 就会被加载。
  2. 它的值必须是一个整数,表示 Servlet 的加载顺序。
  3. 如果该元素的值为负数或者没有设置,则容器会当 Servlet 被请求时再加载。
  4. 如果值为正整数或者 0 时,表示容器在应用启动时就会加载并初始化该 Servlet,值越小,优先级越高,就越被先加载。值相同时,容器就会自己选择顺序来加载。
0

评论区