1. 程式人生 > >Servlet,jsp,jsp的9大內置對象

Servlet,jsp,jsp的9大內置對象

www 輸入流 () 抽象 patch use 源文件 config 邏輯

以servlet作為控制器

1:servlet的生命周期:以下方法都是servlet容器進行調用

1)構造函數;只被調用一次,當項目啟動時或者該servlet被容器第一次調用時,會創建servlet實例,所以servlet是單例模式。

2)init方法:只被調用一次,當servlet實例創建成功後會立即調用init方法,用來初始化servlet;

3)service方法:每次請求都會被調用一次,實際是用來響應請求的;

4)destroy方法:只被調用一次,在當前servlet所在的web應用程序被卸載之前調用,用來釋放servlet所占用的資源;

servlet在web.xml中的配置(註冊和映射)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 3         xmlns="http://java.sun.com/xml/ns/javaee" 
 4         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
 5         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
 6
version="2.5"> 7 8 <!-- 無論是在程序運行時就創建servlet實例並初始化,還是當訪問servlet的時候在進行實例創建並初始化, 9 實例的創建和初始化只被進行一次,也就是說此單一實例是貫穿整個程序的運行周期的,程序停止,此實例就被 10 銷毀,也就是servlet是單例模式的,所以存在線程安全問題 --> 11 <!-- 配置HelloServlet --> 12 <servlet> 13
<servlet-name>HelloServlet</servlet-name> 14 <servlet-class>com.yinfu.servlets.HelloServlet</servlet-class> 15 16 <!-- 配置servlet的初始化參數 --> 17 <init-param> 18 <param-name>user</param-name> 19 <param-value>root</param-value> 20 </init-param> 21 <init-param> 22 <param-name>password</param-name> 23 <param-value>12345</param-value> 24 </init-param> 25 26 <!-- 這個配置是“零或正數”當服務器啟動servlet容器加載此web應用的時候就創建servlet實例,並進行初始化,此數值越小優先級越高, 27 如果沒有這個配置或者此配置為“負數”,只有當訪問此servlet的時候才會創建實例並初始化 --> 28 <load-on-startup>1</load-on-startup> 29 </servlet> 30 <!-- 配置SecondServlet --> 31 <servlet> 32 <servlet-name>SecondServlet</servlet-name> 33 <servlet-class>com.yinfu.servlets.SecondServlet</servlet-class> 34 <load-on-startup>2</load-on-startup> 35 </servlet> 36 <!-- servlet映射,次映射是為了運行此servlet中的service內容代碼而進行的配置 --> 37 <servlet-mapping> 38 <servlet-name>HelloServlet</servlet-name> 39 <!-- ‘/‘代表當前項目的根目錄:‘http://127.0.0.1:8080/ServletProject/‘ --> 40 <url-pattern>/hello</url-pattern> 41 </servlet-mapping> 42 43 </web-app>

2:servlet映射:

1)同一個servlet可以被映射到多個URL上,即多個<servlet-mapping>中的<servlet-name>可以使同一個servlet

2)當servlet映射到的URL中使用通配符 * 時,只有兩種固定格式

  一種是:*.擴展名  二種是:/*

3:servletAPI中servletConfig中的方法:

1)ServletConfig的 getInitParameter(String str);用來獲得指定的servlet初始化參數,返回值類型:String

2)ServletConfig的 getInitParameterNames();用來獲得所有初始化參數的參數名,返回值類型:Enumeration<String>

3)ServletConfig的 getServletName();用來獲取servlet註冊時的註冊名的(很少用)

  即:<servlet-name>HelloServlet</servlet-name>中的HelloServlet

4)ServletConfig的 getServletContext();用來獲取當前WEB應用的上下文對象,從而獲得當前WEB應用中的各方面信息

5)ServletRequest 封裝了用戶的請求信息,可以從中獲取到任何的請求信息;(HttpServletRequest是他的子類)

6)ServletResponse 封裝了響應信息;(HttpServletResponse為他的子類)

用法如下:

  1 package com.yinfu.servlets;
  2 
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.util.Enumeration;
  6 
  7 import javax.servlet.Servlet;
  8 import javax.servlet.ServletConfig;
  9 import javax.servlet.ServletContext;
 10 import javax.servlet.ServletException;
 11 import javax.servlet.ServletRequest;
 12 import javax.servlet.ServletResponse;
 13 
 14 public class HelloServlet implements Servlet {
 15 
 16     @Override
 17     public void destroy() {
 18         System.out.println("銷毀HelloServlet的實例");
 19     }
 20 
 21     @Override
 22     public ServletConfig getServletConfig() {
 23         System.out.println("getServletConfig");
 24         return null;
 25     }
 26 
 27     @Override
 28     public String getServletInfo() {
 29         System.out.println("getServletInfo");
 30         return null;
 31     }
 32 
 33     @Override
 34     public void init(ServletConfig servletConfig) throws ServletException {
 35         System.out.println("將HelloServlet的實例進行初始化");
 36         
 37         /**
 38          * 此方法是用來獲取web.xml中的init-param中的初始化參數的(局部變量,僅限於此servlet)
 39          * user=root
 40          */
 41         String user = servletConfig.getInitParameter("user");
 42         System.out.println("user=" + user);
 43         /**
 44          * 此輸出會將init-param中的所有初始化參數全部輸出
 45          * (Enumeration接口本身不是一個數據結構。但是,對其他數據結構非常重要)
 46          * user:root
 47          * password:12345
 48          */
 49         Enumeration<String> names = servletConfig.getInitParameterNames();
 50         while(names.hasMoreElements()){
 51             String name = names.nextElement();
 52             String value = servletConfig.getInitParameter(name);
 53             System.out.println(name +":"+ value);
 54         }
 55         /**
 56          * 此getServletName()方法是用來獲取web.xml中<servlet-name>HelloServlet</servlet-name>的HelloServlet
 57          * 此方法很少用;
 58          * servletName:HelloServlet
 59          */
 60         String servletName = servletConfig.getServletName();
 61         System.out.println("servletName:"+servletName);
 62         /**
 63          * Servlet引擎為每個WEB應用程序都創建了一個ServletContext對象,ServletContext對象包含在ServletConfig對象中
 64          * 調用ServletConfig的getServletContext()方法可以返回ServletContext對象的引用
 65          * 而WEB應用程序中的每一個servlet都共用同一個ServletContext對象,ServletContext對象又被稱之為application對象
 66          * (應用程序對象)功能:
 67          * ①。獲取WEB應用程序的初始化參數
 68          * ②。記錄日誌
 69          * ③。application域範圍的屬性
 70          * ④。訪問資源文件
 71          * ⑤。獲取虛擬路徑所映射的本地路勁
 72          * ⑥。WEB應用程序之間的訪問
 73          * ⑦。ServletContext對象的其他方法
 74          */
 75         //獲取ServletContext對象
 76         ServletContext context=servletConfig.getServletContext();
 77         //用來獲取指定的ServletContext的初始化參數(成員變量,範圍為整個WEB程序)
 78         //contextName=com.mysql.jdbc.driver
 79         String contextName = context.getInitParameter("driver");
 80         System.out.println("contextName="+contextName);
 81         //獲取所有的ServletContext的初始化參數
 82         //driver:com.mysql.jdbc.driver
 83         //jdbcUrl:jdbc:mysql://apache
 84         Enumeration<String> contextNames = context.getInitParameterNames();
 85         while(contextNames.hasMoreElements()){
 86             String name = contextNames.nextElement();
 87             String contextValue = context.getInitParameter(name);
 88             System.out.println(name+":"+contextValue);
 89         }
 90         //獲取WEB應用的某一個文件在服務器上的絕對路徑,而不是部署前的路徑(文件上傳下載的時候會用到)
 91         //E:\File SetUp\develop environment setup\tts9\apache-tomcat-7.0.67\wtpwebapps\ServletProject\picture.png
 92         String realPath=context.getRealPath("picture.png");
 93         System.out.println(realPath);
 94         //獲取當前WEB應用的名稱(關於頁面絕對路徑的時候會用到)
 95         //結果:/ServletProject
 96         String contextPath = context.getContextPath();
 97         System.out.println(contextPath);
 98         //獲取當前WEB應用的某一文件對應的輸入流
 99         //有兩種方法呢第一種:classLoader;第二種:ServletContext
100         //第一種方法classloader
101         //結果得到輸入流:[email protected]
102         try {
103             //這裏的路徑是該文件的類路徑
104             ClassLoader classLoader = getClass().getClassLoader();
105             InputStream is = classLoader.getResourceAsStream("jdbc.properties");
106             System.out.println(is);
107         } catch (Exception e) {
108             e.printStackTrace();
109         }
110         //第二種方法ServletContext
111         //結果得到輸入流:[email protected]
112         try {
113             //這裏的path是相對於當前WEB應用的相對路徑,也就是服務器中被編譯後的相對路徑
114             InputStream is = context.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
115             System.out.println(is);
116         } catch (Exception e) {
117             e.printStackTrace();
118         }
119     }
120 
121     @Override
122     public void service(ServletRequest arg0, ServletResponse arg1)
123             throws ServletException, IOException {
124         System.out.println("HelloServlet的服務邏輯內容");
125     }
126     
127     public HelloServlet(){
128         System.out.println("創建HelloServlet的實例");
129     }
130 
131 }

4:所有以下內容結合GenericServlet抽象類的源碼進行測試所得思想:

技術分享

技術分享

5:以下為簡單小例子HttpServlet的源碼分析後所得:

簡寫代碼:(自定義代碼,非真正源碼)技術分享技術分享技術分享

實際的service方法源碼是這樣寫的(替換上面的第一張圖片):技術分享

通過以上源碼分析所得思想:技術分享技術分享

5:jsp中的9大隱含對象;

當程序運行加載的時候,jsp文件會生成一個.java源文件;如圖:技術分享

生成的.java文件類繼承了HttpJspBase父類,而在HttpJspBase源碼中HttpJspBase繼承了HttpServlet父類,即:由jsp頁面生成的.java文件也間接繼承了HttpServlet父類,因此.java文件也是一個servlet,同樣重寫了init,destroy,service方法:技術分享

因此在jsp中的所欲邏輯js代碼以及HTML代碼都會出現在.java文件的service方法中,而在響應的service方法中也會內置自定義一些屬性如:技術分享

這些屬性:request,response,pageContext,session,application,config,out,page還有一個exception共九個內置對象,這些內置對象就是jsp的9大隱含對象,在jsp文件中可以直接使用;但這種使用的方法只能是用java代碼來使用,因此這些對象,以及調用的方法要寫在標簽<%%>中:技術分享技術分享技術分享技術分享技術分享

6:jsp的語法:

①:模板元素:jsp中靜態的HTML內容

②:jsp腳本片段(scriptlet),是指嵌套在<%%>標簽之中的一條或者多條java代碼,而多個腳本片段之間的代碼可以進行相互訪問;

③:jsp表達式<%= %>,他可以將java變量或者表達式的計算結果直接輸出到客戶端瀏覽器頁面上;

<%

  Date date=new Date()

%>

<%= date  %>

④:技術分享

(jsp頁面中幾乎從來不這樣用)

⑤:技術分享

7:和屬性相關的方法:技術分享

8:請求的轉發和重定向:技術分享技術分享

HttpServletRequest request;HttpServletResponse response;

請求轉發:

String path="testServlet";
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/"+path);
requestDispatcher.forward(request, response);

請求重定向:

response.sendRedirect("testServlet");

9:將一jsp文件引入到另一個jsp文件中:(在實際開發中,這兩種引入方式都可以交替使用,只做了解)

技術分享技術分享

10:jsp中文亂碼解決方案:

技術分享

由於中文參數在傳遞過程中默認的編碼是ISO-8859-1;當用此編碼進行解碼然後在用"UTF-8"進行編碼這樣就可以解決中文亂碼問題,這種方法無視請求方式,get和post方式都可以,不過就是太麻煩;

技術分享

Servlet,jsp,jsp的9大內置對象