在前面我们学习了Servlet和它的5个接口,学习了ServletConfig和ServletContext对象,下面介绍web开发中实际用到的HttpServlet接口。
public abstract class HttpServlet extends GenericServlet
HttServlet继承自GenericServlet,它重写了service方法
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);
}
将ServletRequest和ServletResponse对象向下转型成HttpServletRequest和HttpServletResponse,然后执行自己的重载的service方法。
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);
}
}
而重载的service方法遵循了模板类设计模式的思想,首先通过getMethod方法,判断当前浏览器的请求是什么类型,包括GET,POST, DELETE等七种类型,对于不同的类型走不同的方法,比如若是GET则走doGet方法。
这些方法是需要子类的复现的,HttpServlet规定好了流程,而流程的子过程需要子类自己实现。
在浏览器键入地址,点击超链接这种都是GET方法,那就需要实现doGet方法。如果前端是一个GET请求,而后端servlet中没有对象的doGet方法,就会报405错误。
web.xml中可以设置欢迎页
<welcome-file-list>
<welcome-file>index.htmlwelcome-file>
<welcome-file>index.htmwelcome-file>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
优先级从上到下对应从高到低。
Tomcat的config目录下也有个web.xml文件,其中它的欢迎页配置就如上所示。
现在我们键入http://localhost:8080/项目名,那么就会自动跳转到欢迎页。