初识Servlet

1.1 什么是Servlet

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

Servlet可描述如下:

  1. 它是一种创建Web应用的技术
  2. 它是一种API,提供了接口和实现类的,方便Web应用开发
  3. 它是一种可以扩展服务,根据请求来定制响应内容
  4. 它是一个Web容器,可以部署到Web服务上面,动态地创建web网页

Servlet图示:

1.2 第一个Servlet事例

1.2.1 创建一个maven的web应用,引入servlet-api依赖

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>

1.2.2 编写一个Servlet类实现Servlet接口

public class FirstServlet 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.setContentType("text/html");
        PrintWriter writer = servletResponse.getWriter();
        writer.println("<html><body>hello this is a sample of servlet</body></html>");
        writer.close();
    }

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

    @Override
    public void destroy() {
    }
}

Servlet接口当中的5个方法:

public interface Servlet {
    /*初始化servlet, 这是生命周期的一部分,由web容器启动的时候调用一次*/
    void init(ServletConfig var1) throws ServletException;
    /*获取ServletConfig*/
    ServletConfig getServletConfig();
    /*处理来自web容器的请求,参数包括请求的内容和要返回的内容*/
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    /*返回servlet的相关信息,比如作者、版权等*/
    String getServletInfo();
    /*方法只会被调用一次,在 Servlet 生命周期结束时被调用*/
    void destroy();
}

1.2.3 创建web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Demo</display-name>

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.example.FirstServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

1.2.4 项目整体结构如下:

1.2.5 打包成war包,部署到tomcat

把打包好的war包放到tomcat目录下面的webapps目录,运行startup.bat

1.2.6 通过浏览器打开链接http://localhost:8080/hello

1.3 GenericServet类

GenericServlet 是一个抽象类,实现了 Servlet 接口,并且对其中的 init() 和 destroy() 和 service() 提供了默认实现。在 GenericServlet 中,主要完成了以下任务:

  • 将 init() 中的 ServletConfig 赋给一个类级变量,可以由 getServletConfig 获得;
  • 为 Servlet 所有方法提供默认实现;
  • 可以直接调用 ServletConfig 中的方法;

事例如下:

public class SecondServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        servletResponse.setContentType("text/html");
        PrintWriter writer = servletResponse.getWriter();
        writer.println("<html><body>hello this is a second of servlet</body></html>");
        writer.close();
    }
}

1.4 HttpServlet类

HttpServlet 也是一个抽象类,它进一步继承并封装了 GenericServlet,使得使用更加简单方便,由于是扩展了 Http 的内容,所以还需要使用 HttpServletRequest 和 HttpServletResponse,这两个类分别是 ServletRequest 和 ServletResponse 的子类。

在 HttpServlet 中,自定义了一个新的 service() 方法,其中通过 getMethod() 方法判断请求的类型,从而调用 doGet() 或者 doPost() 处理 get,post 请求,使用者只需要继承 HttpServlet,然后重写 doPost() 或者 doGet() 方法处理请求即可。

public class ThirdServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.println("<html><body>hello this is a third of servlet</body></html>");
        writer.close();
    }
}

1.5 Servlet生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 初始化后调用 init () 方法。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 销毁前调用 destroy() 方法。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

1.5.1 init() 方法

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

1.5.2 service() 方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

1.5.3 destory() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收

1.6 Redirect和Forward

Forward(转发):

  • forward是服务器端跳转,它是通过RequestDispatcher对象的forward()方法实现的。
  • forward是在服务器内部完成的,客户端浏览器并不知道页面的跳转。
  • forward可以将请求的数据传递给下一个页面。
  • forward的路径是相对于当前Servlet的路径,可以跳转到WEB-INF目录下的页面。
  • forward可以跳转到当前WEB应用中的其他Servlet、JSP页面或HTML页面。
public class ForwardServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/first").forward(req, resp);
    }
}

Redirect(重定向):

  • redirect是通过HttpServletResponse对象的sendRedirect()方法实现的。
  • redirect是通过告知浏览器发送一个新的请求,浏览器收到服务器返回的重定向响应后,会向新的URL地址发出新的请求。
  • redirect是客户端行为,客户端浏览器会重新向指定的页面发送请求,URL地址会发生变化。
  • redirect不可以将请求的数据传递给下一个页面,需要通过URL参数进行传递。
  • redirect的路径是相对于当前的域名,不能跳转到WEB-INF目录下的页面。
  • redirect可以跳转到任意URL地址,包括其他WEB应用中的页面。
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("/second");
    }
}

1.7 ServletConfig

在Servlet的配置文件中,可以使用一个或多个标签为servlet配置一些初始化参数。当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init()方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

事例: 

<servlet>
  <servlet-name>config</servlet-name>
  <servlet-class>com.example.ServletConfigServlet</servlet-class>
  <init-param>
    <param-name>name</param-name>
    <param-value>Jack</param-value>
  </init-param>
  <init-param>
    <param-name>age</param-name>
    <param-value>10</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>config</servlet-name>
  <url-pattern>/config</url-pattern>
</servlet-mapping>
public class ServletConfigServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        ServletConfig servletConfig = getServletConfig();
        Enumeration<String> e = servletConfig.getInitParameterNames();
        while(e.hasMoreElements()){
            String name = e.nextElement();
            String val = servletConfig.getInitParameter(name);
            writer.println("name="+name+",value="+val);
        }
    }
}

运行结果:

1.8 ServletConext对象

        WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。

  ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。

  由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。

事例,先访问context1,设置参数data, 再访问context2, 获取前面设置的参数。

public class ServletContextServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletConfig servletConfig = getServletConfig();
        ServletContext servletContext = servletConfig.getServletContext();
        servletContext.setAttribute("data", "context1 data");
        resp.getWriter().println("context1");
    }
}

public class ServletContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletConfig().getServletContext();
        resp.getWriter().println("context2:"+servletContext.getAttribute("data"));
    }
}

事例2, ServletContext获取在web.xml文件中使用标签配置WEB应用的初始化参数

<web-app>
  <display-name>Demo</display-name>

  <context-param>
    <param-name>url</param-name>
    <param-value>http://www.baidu.com</param-value>
  </context-param>
</web-app>
@WebServlet(urlPatterns = "/context2")
public class ServletContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletConfig().getServletContext();
        resp.getWriter().println("context2:"+servletContext.getAttribute("data"));
        String urlVal = servletContext.getInitParameter("url");
        resp.getWriter().println("url:"+urlVal);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值