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()方法的内容。
转载说明:请注明作者及原文链接。谢谢!