HttpServlet概述

在大多数的Web应用程序中,client都是通过Http协议去訪问server端的资源,而我们编写的Servlet主要是用于Http协议的请求和响应处理。为了高速开发应用于Http协议的Servlet类,Sun公司在javax.servlet.http包中提供了一个抽象类HttpServlet,它继承于GenericServlet,用于创建适合基于Http协议的Web Servlet。

public abstract class HttpServlet extends GenericServlet {}

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

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抽象类中提供的各个方法进行讨论。

重写的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()方法,对client的请求进行处理。

在第二个service()方法中。针对Http 1.1协议中定义的7种请求方式Get、Post、Head、Put、Delete、Trace和Options提供了7种处理方法。这7种方法的參数类型及异常抛出类型与HttpServlet类中的第二个service()方法是一致的。

当Servlet容器接收到一个针对HttpServlet对象的请求时,调用该对象的方法顺序例如以下:

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

因此。我们在自己定义Servlet继承于HttpServlet的时候。通常不须要重写service()方法,仅仅需重写响应的doXXX()方法就可以。

七种请求处理方法

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

  • 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的client请求,这些方法返回的状态码为400。表示client发送的请求在语法上是错误的。对于Http 1.1的client请求。这些方法返回的状态码为405,表示对于指定资源的请求方法不被同意。

而对于Http协议的实际应用来讲。我们最经常使用的是Get和Post,所以在自己定义Servlet时,常重写doGet()和doPost()两个请求处理方法。当中doGet()方法用来处理Get方式的请求,doPost()方法用来处理Post方式的请求,以下我们通过一个案例来看一看:

  • 创建一个HTML页面用于发送client请求。
<!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>

  • 将Webproject公布到Tomcatserver,并启动Tomcatserver。

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

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


转载说明:请注明作者及原文链接。谢谢!