在大多数的Web应用程序中,客户端都是通过Http协议去访问服务器端的资源,而我们编写的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抽象类中提供的各个方法进行讨论。
在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对象的请求时,调用该对象的方法顺序如下:
因此,我们在自定义Servlet继承于HttpServlet的时候,通常不需要重写service()方法,只需重写响应的doXXX()方法即可。
在HttpServlet抽象类中提供了针对Http 1.1协议中定义的7种请求方式Get、Post、Head、Put、Delete、Trace和Options提供了7种处理方法:
这7种处理请求的方法中,HttpServlet类对Trace和Options方法做了适当的实现,因此我们不需要重写doTrace()和doOptions()方法。而对于其他的5种请求处理方法,HttpServlet类提供的实现都是返回Http错误。对于Http 1.0的客户端请求,这些方法返回的状态码为400,表示客户端发送的请求在语法上是错误的。对于Http 1.1的客户端请求,这些方法返回的状态码为405,表示对于指定资源的请求方法不被允许。
而对于Http协议的实际应用来讲,我们最常用的是Get和Post,所以在自定义Servlet时,常重写doGet()和doPost()两个请求处理方法。其中doGet()方法用来处理Get方式的请求,doPost()方法用来处理Post方式的请求,下面我们通过一个案例来看一看:
<!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>
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()方法来处理.");
}
}
<?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()方法的内容。
转载说明:请注明作者及原文链接,谢谢!