HttpServlet 是用HTTP协议实现的Servlet的基类,写Servlet时直接继承它就可以了,不需要再从头实现Servlet接口,SpringMVC中的DispatcherServlet就是继承的HttpServlet主要重写了service方法,在service方法中首先将ServletRequest和ServletResponse转换为了HttpServletRequest和HttpServletResponse,然后根据Http请求的类型不同将请求路由到了不同的处理方法
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long errMsg;
if(method.equals("GET")) {
errMsg = this.getLastModified(req);
if(errMsg == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if(ifModifiedSince < errMsg / 1000L * 1000L) {
this.maybeSetLastModified(resp, errMsg);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if(method.equals("HEAD")) {
errMsg = this.getLastModified(req);
this.maybeSetLastModified(resp, errMsg);
this.doHead(req, resp);
} else if(method.equals("POST")) {
this.doPost(req, resp);
} else if(method.equals("PUT")) {
this.doPut(req, resp);
} else if(method.equals("DELETE")) {
this.doDelete(req, resp);
} else if(method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if(method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg1 = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg1 = MessageFormat.format(errMsg1, errArgs);
resp.sendError(501, errMsg1);
}
}
具体的处理方法是doXXX的结构,如最常用的doGet、doPost就是在这里定义的。doGet、doPost、doPut和doDelete方法都是模板方法,而且如果子类没有是想将抛出异常,在调用doGet方法前还对是否过期做了检查,如果没有过期则直接返回304状态吗使用缓存;doHead调用了doGet的请求,然后返回空body的Response;doOptions和doTrace正常不需要使用,主要是用来做一些调试工作,doOptions返回所有支持的处理类型的集合,正常情况下可以禁用,doTrace用来远程诊断服务器的,它会将接收到的hrader原封不动地返回,这种做法可能会被黑客利用,存在安全漏洞,所以如果不是必须使用,最好禁用。由于doOptions和doTrace的功能非常固定,所以HttpServlet做了默认的实现。DoGet代码入下(doPost、doPut、doDelete)
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if(protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}