[Servlet]深刻研究HttpServlet

HttpServlet概述

在大多数的Web应用程序中,客户端都是经过Http协议去访问服务器端的资源,而咱们编写的Servlet主要是用于Http协议的请求和响应处理。为了快速开发应用于Http协议的Servlet类,Sun公司在javax.servlet.http包中提供了一个抽象类HttpServlet,它继承于GenericServlet,用于建立适合基于Http协议的Web Servlet。html

public abstract class HttpServlet extends GenericServlet {}

下列表中罗列了HttpServlet的全部方法:java

Method Summary
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
protected long getLastModified(HttpServletRequest req)
protected void service(HttpServletRequest req, HttpServletResponse resp)
void service(ServletRequest req, ServletResponse res)

下面咱们就针对HttpServlet抽象类中提供的各个方法进行讨论。web

重写的service()方法

在HttpServlet类中提供了两种重载的service()方法:浏览器

public abstract class HttpServlet extends GenericServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {
        HttpServletRequest  request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException("non-HTTP request or response");
        }
        service(request, response);
}
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doGet(req, resp);
        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
       } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
}

经过查看HttpServlet的源代码咱们能够知道,第一个service()方法是GenericServlet类中的Service()方法的实现。在该service()方法中将ServletRequest和ServletResponse对象转换成HttpServletRequest(继承于ServletRequest接口)和HttpServletResponse(继承于ServletResponse接口),而后调用了第二个service()方法,对客户端的请求进行处理。服务器

在第二个service()方法中,针对Http 1.1协议中定义的7种请求方式Get、Post、Head、Put、Delete、Trace和Options提供了7种处理方法。这7种方法的参数类型及异常抛出类型与HttpServlet类中的第二个service()方法是一致的。当Servlet容器接收到一个针对HttpServlet对象的请求时,调用该对象的方法顺序以下:markdown

  • 调用公用service()方法,将参数类型转换成HttpServletRequest和HttpServletResponse,而后调用受保护的service()方法。
  • 在受保护的service()方法中,获取Http请求方法的名字,而后根据请求方法的类型,调用响应的doXXX()方法。

所以,咱们在自定义Servlet继承于HttpServlet的时候,一般不须要重写service()方法,只需重写响应的doXXX()方法便可。app

七种请求处理方法

在HttpServlet抽象类中提供了针对Http 1.1协议中定义的7种请求方式Get、Post、Head、Put、Delete、Trace和Options提供了7种处理方法:jsp

  • protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
  • protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
  • protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
  • protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
  • protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
  • protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
  • protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException

这7种处理请求的方法中,HttpServlet类对Trace和Options方法作了适当的实现,所以咱们不须要重写doTrace()和doOptions()方法。而对于其余的5种请求处理方法,HttpServlet类提供的实现都是返回Http错误。对于Http 1.0的客户端请求,这些方法返回的状态码为400,表示客户端发送的请求在语法上是错误的。对于Http 1.1的客户端请求,这些方法返回的状态码为405,表示对于指定资源的请求方法不被容许。ide

而对于Http协议的实际应用来说,咱们最经常使用的是Get和Post,因此在自定义Servlet时,常重写doGet()和doPost()两个请求处理方法。其中doGet()方法用来处理Get方式的请求,doPost()方法用来处理Post方式的请求,下面咱们经过一个案例来看一看:post

  • 建立一个HTML页面用于发送客户端请求。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>index.html</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <h1>GET方式请求</h1>
    <form id="userinfo" method="get" action="threeServlet">
        用户名:<input type="text" id="username" name="username">
        <input type="submit" id="submit" value="提交">
    </form>
    <h1>POST方式请求</h1>
    <form id="userinfo" method="post" action="threeServlet">
        用户名:<input type="text" id="username" name="username">
        <input type="submit" id="submit" value="提交">
    </form>
  </body>
</html>
  • 建立一个Servlet用于处理请求。
public class ThreeServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("这是GET方式发送的请求,Servlet使用doGet()方法来处理.");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("这是POST方式发送的请求,Servlet使用doPost()方法来处理.");
    }
}
  • 配置web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="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_2_5.xsd">
  <servlet>
<servlet-name>ThreeServlet</servlet-name>
    <servlet-class>app.java.servlet.ThreeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ThreeServlet</servlet-name>
    <url-pattern>/threeServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

这里写图片描述

利用GET方式发送请求,控制台会打印doGet()方法的内容。利用POST方式发送请求,控制台会打印doPost()方法的内容。


转载说明:请注明做者及原文连接,谢谢!

相关文章
相关标签/搜索