JavaWeb

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项目的根目录。

原文地址:https://www.cnblogs.com/frankcui/p/14022533.html