HttpServlet
在绝大多数的网络应用中,都是客户端(浏览器)通过 HTTP 协议去访问服务端的资源,而我们所编写的 Servlet 也主要是应用于 HTTP 协议的请求和响应。为了 快速开发应用于 HTTP 协议的 Servlet 类,提供了一个 抽象的类 HttpServlet 类,他继承自 GenericServlet 类。
在 HttpServlet 中提供了两个重载的 service 方法。
@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(lStrings.getString("http.non_http"));
}
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);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} 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 {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
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 对象的请求时,调用改对象中的方法顺序如下:
- 调用公共的 public service()方法。
- 在公共的 service()方法中,首先将参数类型转换为 HttpServletRequest 、HttpServletResponse ,然后调用受保护的 (protected) service()方法,将转换后的 HttpServletRequest 对象和 HttpServletResponse 对象作为参数传递进去。
- 在保护的 service()方法中,首先调用 HTTPServletRequest 对象的 getMethod 方法,获取请求方法的名字,然后根据请求方法的类型调用响应的 doXXX() 方法。
因此,我们编写 HttpServlet 的派生类时通常不需要去覆盖 service()方法,只需要重写相应的 doXXX()方法。
编写 Servlet
- 通常是继承 javax.servlet.http.HttpServlet
- 复写 HttpServlet 中的 doGet() 和 doPost ()方法
- 配置 web.xml 文件
- 部署项目并通过浏览器访问
- Servlet 的执行流程
提示
web 应用程序的开发分为设计开发与配置部署两个阶段。通过部署,实现了组件和组件之间的松耦合,降低了 Web 应用程序维护的难度。
为 Servet 指定了一个名字和 URL 映射,其它的组件或页面可以使用 URL 来调用这个 Servlet ,一旦 Servlet 发生了改动,例如,这个类被替换、重新命名等,只需要修改 web.xml 文件中 元素的内容,在设计开发阶段确定的程序结构和代码不需要做任何改动,降低了程序维护的难度。