JavaWeb - Servlet原理 + ServletContext应用
Servlet原理
前提:自定义的servlet (MyServlet)继承HttpServlet,HttpServlet->GenericServlet->Servlet. 但MyServlet只重写了doGet, doPost 方法,未重写service()
1-浏览器 发送HTTP请求request 给web容器(tomcat)
2-tomcat 把 浏览器发送的request,以及一个空白的response 扔给 MyServlet的service()方法 处理 -- 通过<servlet-mapping>找到MyServlet
3-去找MyServlet.service(),但没找到 --> 再去找其父类HttpServlet,找到a) HttpServlet.service(ServletRequest...) ,然后是b) HttpServlet.service(HttpServletRequest...) 。发现会调用doGet, doPost 方法,而MyServlet重写了doGet, doPost 方法,就会调用MyServlet重写的逻辑。
//a) HttpServlet 实现 Servlet接口的service() public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; //调用HttpServlet内部自己的service()方法。注意参数类型的变化。 this.service(request, response); } else { throw new ServletException("non-HTTP request or response"); } } //b) HttpServlet部自己的service()方法 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //通过request拿到method类型 String method = req.getMethod(); long lastModified; //通过method类型,来选择doGet, doPost, doXXX.... if (method.equals("GET")) { lastModified = this.getLastModified(req); if (lastModified == -1L) { this.doGet(req, resp);//调用MyServlet的doGet() } else { long ifModifiedSince = req.getDateHeader("If-Modified-Since"); if (ifModifiedSince < lastModified) { this.maybeSetLastModified(resp, lastModified); this.doGet(req, resp); } else { resp.setStatus(304); } } } else if (method.equals("HEAD")) { lastModified = this.getLastModified(req); this.maybeSetLastModified(resp, lastModified); this.doHead(req, resp); } else if (method.equals("POST")) { this.doPost(req, resp);//调用MyServlet的doPost() } 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 errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[]{method}; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(501, errMsg); } }
ServletContext
共享数据
将来会用session或者header去做,少用ServletContext!!!
转发forward vs 重定向redirect
转发更常见的是用Request去做!!!
读取配置文件
这里的第一个斜杠“/”,不能省略。代表着web项目的根目录。