Web階段:第八章:Servlet上

Servlet技術(shù)
a)什么是Servlet
1、Servlet是一個(gè)接口(JavaEE規(guī)范)
2、Servlet是運(yùn)行在服務(wù)器(Tomcat或其他的服務(wù)器)上的小程序。
3、Servlet程序用來接收用戶的請求,和給客戶端響應(yīng)數(shù)據(jù)。(接收請求,回傳響應(yīng))

b)手動(dòng)實(shí)現(xiàn)Servlet程序
1、編寫一個(gè)類去實(shí)現(xiàn)Servlet接口
2、實(shí)現(xiàn)接口中的service方法
3、到web.xml中去配置訪問地址

Servlet程序

public class HelloServlet implements Servlet {
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        System.out.println("hello world!!");
    }
}

web.xml中的配置:

 

  1. <!--
  2. servlet配置一個(gè)Servlet程序,給Tomcat服務(wù)器配置
  3. -->
  4. <servlet>
  5. <!-- servlet-name給這個(gè)servlet啟一個(gè)名稱,一般值是類名 -->
  6. <servlet-name>HelloServlet</servlet-name>
  7. <!-- servlet-name是Servlet程序的全類名 -->
  8. <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
  9. </servlet>
  10. <!-- servlet-mapping用來配置servlet程序的訪問地址 -->
  11. <servlet-mapping>
  12. <!-- servlet-name表示給誰配置訪問地址 -->
  13. <servlet-name>HelloServlet</servlet-name>
  14. <!--
  15. url-pattern配置訪問地址
  16. 地址的格式:http://ip:port/工程名/資源名
  17. 在服務(wù)器上。/ 斜杠 == 表示地址:http://ip:port/工程名/
  18. /hello ====== 表示http://ip:port/工程名/hello
  19. 也就是說,我們在瀏覽器地址欄上輸入訪問地址:
  20. http://ip:port/工程名/hello 就可以訪問這個(gè)HelloServlet程序。
  21. 如果將項(xiàng)目部署到服務(wù)器上默認(rèn)訪問的是index.html,如果沒有index文件則會(huì)報(bào)錯(cuò)
  22. -->
  23. <url-pattern>/hello</url-pattern>
  24. </servlet-mapping>

   

常見錯(cuò)誤: servlet-name標(biāo)簽配置不統(tǒng)一

 


常見錯(cuò)誤二:servlet-class標(biāo)簽全類名標(biāo)簽錯(cuò)誤

 


常見錯(cuò)誤三:url-pattern沒有以斜杠打頭

 


c)解析url到servlet訪問細(xì)節(jié)

 


d)Servlet的生命周期(了解內(nèi)容,面試)
1 先執(zhí)行Servlet的構(gòu)造器
2 執(zhí)行init初始化方法
工程啟動(dòng)之后,我們第一次訪問Servlet程序的時(shí)候執(zhí)行 1 和 2兩個(gè)步驟
3 執(zhí)行service 業(yè)務(wù)方法
每次調(diào)用都會(huì)執(zhí)行service方法
4 執(zhí)行destroy銷毀方法
當(dāng)web工程停止的時(shí)候(重新部署)

e)模擬GET請求和POST請求的分發(fā)

public class HelloServlet implements Servlet {
    /**
     * service方法是業(yè)務(wù)處理方法,每次請求都會(huì)調(diào)用
     */
    @Override
    public void service(ServletRequest request, ServletResponse response)
            throws ServletException, IOException {
//        System.out.println("3 service業(yè)務(wù)處理方法");
        // 想辦法知道到底請求進(jìn)來到底是GET。還是POST
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        //getMethod 可以獲取請求的方式,GET或POST
        String method = httpRequest.getMethod();
        // System.out.println( method );
        
        // 可能一般GET請求,和POST請求,需要做的工作不同
        if ("GET".equals(method)) {
            // 做GET請求的處理
            doGet();
        } else if ("POST".equals(method)) {
            // 做POST請求的處理
            doPost();
        }
    }
    
    public void doGet() {
        System.out.println("這是GET請求的功能");
    }
    
    public void doPost() {
        System.out.println("這是POST請求的功能");
    }
}

f)通過繼承HttpServlet實(shí)現(xiàn)Servlet程序
在開發(fā)的時(shí)候。為了讓開發(fā)代碼更佳簡潔,方便,然后規(guī)范中提供了一個(gè)類叫HttpServlet類。
我們只需要繼承HttpServlet類,就可以實(shí)現(xiàn)Servlet程序了
1、編寫一個(gè)類去繼承HttpServlet
2、重寫doGet或doPost方法
3、去web.xml中去配置請求地址
源代碼:

public class HelloServlet2 extends HttpServlet {
    /**
     * doGet方法,在請求進(jìn)來 是GET請求的時(shí)候,調(diào)用
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("這是繼承HttpServlet 實(shí)現(xiàn)的 GET功能");
    }
    /**
     * doPost方法,在請求進(jìn)來 是POST請求的時(shí)候,調(diào)用
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("這是繼承HttpServlet 實(shí)現(xiàn)的 POST功能");
    }   
}

   

web.xml中的配置:

  1. <servlet>
  2. <servlet-name>HelloServlet2</servlet-name>
  3. <servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>HelloServlet2</servlet-name>
  7. <!-- 在服務(wù)器中 / 斜杠 ===== 表示http://ip:port/工程名/
  8. /hello2 ===>>>> http://ip:port/工程名/hello2
  9. -->
  10. <url-pattern>/hello2</url-pattern>
  11. </servlet-mapping>

 

表單:

  1. <form action="http://localhost:8080/day06/hello2" method="post">
  2. <input type="submit" />
  3. </form>

g)使用Eclipse創(chuàng)建Servlet程序

 

 

 


Servlet類的繼承體系

 


ServletConfig類
ServletConfig類從類名中就感覺它是Servlet程序的配置信息。
這個(gè)ServletConfig只能由Tomcat服務(wù)器負(fù)責(zé)創(chuàng)建。每次Tomcat創(chuàng)建Servlet程序的時(shí)候,就會(huì)創(chuàng)建ServletConfig對(duì)象,然后調(diào)用init初始化方法進(jìn)行初始化操作。

a)ServletConfig類的三大作用
1、獲取在web.xml中配置的Servlet-name的別名
2、獲取在web.xml中配置的初始化參數(shù)init-param
3、獲取ServletContext對(duì)象

源代碼:

public class ConfigServlet extends HttpServlet {

    public void init(ServletConfig config) throws ServletException {
//        1、獲取在web.xml中配置的Servlet-name的別名
        System.out.println("servlet-name的值:" + config.getServletName());
//        2、獲取在web.xml中配置的初始化參數(shù)init-param
        System.out.println("初始化參數(shù)user的值:" + config.getInitParameter("user"));
        System.out.println("初始化參數(shù)url的值:" + config.getInitParameter("url"));
//        3、獲取ServletContext對(duì)象
        System.out.println( config.getServletContext() );
    }

}

   xml中的配置:

  1. <servlet>
  2. <servlet-name>ConfigServlet</servlet-name>
  3. <servlet-class>com.atguigu.servlet.ConfigServlet</servlet-class>
  4. <!--
  5. init-param
  6. 配置配置初始化參數(shù)(由鍵值對(duì)組成)
  7. -->
  8. <init-param>
  9. <!-- param-name是參數(shù)名 -->
  10. <param-name>user</param-name>
  11. <!-- param-value是參數(shù)值 -->
  12. <param-value>root</param-value>
  13. </init-param>
  14. <!--
  15. init-param
  16. 配置配置初始化參數(shù)(由鍵值對(duì)組成)
  17. -->
  18. <init-param>
  19. <!-- param-name是參數(shù)名 -->
  20. <param-name>url</param-name>
  21. <!-- param-value是參數(shù)值 -->
  22. <param-value>jdbc:mysql://localhost:3306/test</param-value>
  23. </init-param>
  24. </servlet>
  25. <servlet-mapping>
  26. <servlet-name>ConfigServlet</servlet-name>
  27. <url-pattern>/configServlet</url-pattern>
  28. </servlet-mapping>

   

注意點(diǎn):

 

 


ServletContext類
a)什么是ServletContext?
1、ServletContext是一個(gè)接口
2、ServletContext在一個(gè)web工程中只有一個(gè)對(duì)象實(shí)例(Tomcat服務(wù)器負(fù)責(zé)創(chuàng)建)。
3、ServletContext是一個(gè)域?qū)ο蟆?/p>

什么是域?qū)ο?
域?qū)ο笫强梢韵駇ap一樣存取數(shù)據(jù)的對(duì)象
setAttribute 保存數(shù)據(jù) put
getAttribute 獲取數(shù)據(jù) get
removeAttribute 刪除數(shù)據(jù) remove
域指的是這些存取的數(shù)據(jù)的操作范圍。ServletContext對(duì)象的數(shù)據(jù)操作范圍是整個(gè)web工程。
ServletContext對(duì)象在web工程啟動(dòng)的時(shí)候創(chuàng)建。在web工程停止的時(shí)候銷毀。

b)ServletContext類的四個(gè)作用
1、獲取在web.xml中配置的上下文初始化參數(shù) context-param
2、獲取工程路徑地址
3、獲取工程發(fā)布之后在服務(wù)器上的絕對(duì)路徑
4、像map一樣存取數(shù)據(jù)。

ServletContext作用的演示源代碼:

public class ContextServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        //獲取ServletContext對(duì)象
        ServletContext servletContext = getServletContext();        
//        1、獲取在web.xml中配置的上下文初始化參數(shù)    context-param
        String password = servletContext.getInitParameter("password");
        String url = servletContext.getInitParameter("url");
        System.out.println( "上下文參數(shù)password的值:" + password );
        System.out.println( "上下文參數(shù)url的值:" + url );
//        2、獲取工程路徑地址
        System.out.println("當(dāng)前工程路徑是:" + servletContext.getContextPath());
//        3、獲取工程發(fā)布之后在服務(wù)器上的絕對(duì)路徑
        // / 斜杠表示到http://ip:port/工程名/    映射到代碼的webContent目錄    
        // getRealPath 獲取在服務(wù)器上的絕對(duì)路徑。
        System.out.println( "/ 根 的絕對(duì)路徑是:" + servletContext.getRealPath("/") );
        System.out.println("/css的絕對(duì)路徑是:" + servletContext.getRealPath("/css"));
        System.out.println("/imgs/11.jpg的絕對(duì)路徑是:" + servletContext.getRealPath("/imgs/11.jpg"));
        System.out.println( servletContext.getRealPath("/1.js") );
    }
}

   

web.xml配置文件內(nèi)容:

  1. <context-param>
  2. <param-name>password</param-name>
  3. <param-value>root</param-value>
  4. </context-param>
  5. <context-param>
  6. <param-name>url</param-name>
  7. <param-value>jdbc:mysql://localhost:3306/contextServlet</param-value>
  8. </context-param>

  

像map一樣存取數(shù)據(jù):

Context1的代碼:

public class Context1 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {    
        ServletContext context = getServletContext();
        System.out.println( context );
        // 獲取屬性值:
        System.out.println("在保存屬性前 Context1 里獲取abc的屬性值:" + context.getAttribute("abc"));        
        context.setAttribute("abc", "麥當(dāng)勞是誰開的?麥當(dāng)娜開的!因?yàn)樗麄兌夹整湥?);    
        System.out.println("在保存屬性后 Context1 里獲取abc的屬性值:" + context.getAttribute("abc"));
    }    
}

Context2的代碼:

public class Context2 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {        
        ServletContext context = getServletContext();
        System.out.println( context );
        // 獲取屬性值:
        System.out.println("Context2 里獲取abc的屬性值:" + context.getAttribute("abc"));
    }
}