Servlet(一) servlet的三種創建方式


不會servlet談不上會javaweb開發,所以很重要

這個servlet不用new,就是一個java類,可以直接使用,用來處理請求響應的。

 

寫一個java類繼承serlvet接口。 重寫未實現的方法。其實最關鍵的一個就是service()方法。 

 

 

ServletContext

WEB-INF中不可以直接訪問src中的文件:通過以下渠道

 

servlet生命周期(重要)

四個過程

  1. 執行構造函數(實例化,servlet第一次被訪問時)
  2. init(初始化,servlet第一次被訪問時)
  3. service 服務,每次被訪問都會被調用
  4. destroy 銷毀

當servlet開啟后再刷新界面的時候,就只執行service函數,當項目被卸載(也就是webroot下的項目被刪除了)時,會執行destroy方法。

 

 

servlet執行過程:

  1. 先寫一個類實現servlet接口。
  2. 然后現在web.xml中配置

上面第二步中:創建一個servlet實例

 

<servlet-class>這個標簽其實就是new這個servlet類,底層代碼其實就是classforName,因為Tomcat功能可以解析xml,所以可以這么寫

 

下圖可以通過copy qualified name來復制Servlet類的全路徑

 

然后servlet-name 改成小寫即可

 

servlet-mapping:

 

一定記得加一個/ ,否則就是訪問localhost:8080/demo1 (顯然這種地址是錯的),而不是localhost:8080/項目名/demo1,通過這個映射地址找到servlet類。

對於錯誤信息:

HTTP Status 405 - HTTP method GET is not supported by this URL type Status report message HTTP method GET is not supported by this URL description The specified HTTP method is not allowed for the requested resource. Apache Tomcat/7.0.75

原因是在覆蓋doPost或者doGet的時候忘記去掉super.doGet或則super.doPost了,去掉就好了。

 

原理解釋:

三步走:

  1. 客戶端首先通過地址訪問demo1下的內容, tomcat會找到對應的項目,即day08。
  2. 然后會通過web.xml找到url-pattern下  為/demo的標簽,然后找到兄弟標簽servlet-name對應的servletDemo,
  3. 最后找到對應的servlet類,之后就會調用該類下的service()方法。

時序圖如下:

上面在第四步,創建servlet實體類,然后調用init方法。


 

第一種創建方式:

就像上面的例子一樣,寫一個類實現servlet接口,然后配置web.xml文件。

 

第二種創建方式:

GenericServlet類 實現service方法

 

第三種創建方式

實際開發中,就用這種!

使用方法:創建一個類然后繼承HttpServlet類

HttpServlet類:

它是繼承GenericServlet類。

doGet doPost service(兩個service方法),這三個方法更常用

不建議重寫service方法,否則,他自帶的service中的doPost doGet方法就沒有起到作用了。主要是重寫doGet doPost方法。使用HttpServlet其實主要就是要重寫doget doPost,因為在HttpServlet中的service最后就是調用doget dopost,這是一個模板(模板方法),模板已經給你搭好了,具體在那兩個方法里改變

在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("non-HTTP request or response");
        }
        service(request, response);
    }
}

最后 service(request, response);調用這個方法,這個方法里的doPost,doGet最終被我們自己重寫

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);
        }
    }

 三種創建方式的關系可用下圖表示:

 

使用IDE創建一個Servlet ,就可以不用使用類的方式創建,就不需要手動寫web.xml文件

 

這樣就自動在web.xml中生成以下代碼:

訪問的時候需要多加一個/servlet串就可以,通常url-pattern項目文件小寫。所以改成小寫了。

 

 

 

 

 

 


 idea中輸入sout就是System.out.println快捷鍵 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM