JavaWeb 後端 <二> 之 Servlet 學習筆記 JavaWeb 後端 <二> 之 Servlet 學習筆記

JavaWeb 後端 <二> 之 Servlet 學習筆記

 

 1、Servlet概述

一、什麼是Servlethtml

Servlet是一個運行在服務器端的Java小程序,經過HTTP協議用於接收來自客戶端請求,併發出響應。java

二、Servlet中的方法web

public void service(ServletRequest req,ServletResponse res)小程序

throws ServletException,java.io.IOException後端

 

ServletRequest req:表明着請求對象,該對象中有HTTP協議的請求部分的全部內容。它的實現類由服務器提供的,封裝數據也是服務器來作的。安全

ServletResponse res:表明着響應對象,該對象中由咱們寫數據(HTTP協議的響應部分)進去。它的實現類也是由服務器提供的。服務器

service:由服務器調用,每次請求都會調用一次。服務器採用的是多線程機制。多線程

2、Servlet的編碼步驟

一、編寫一個類實現javax.servlet.Servlet接口,或者繼承javax.servlet.GenericServlet併發

二、編譯Servlet的源碼app

 

三、映射Servlet

修改web.xml

四、把應用部署Tomcat中,訪問地址:http://localhost:8080/firstServlet/hello

 

明確:規範 服務器 應用間的關係

3、Servlet的執行過程

 

 實例 class代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  com.it.Serlvet;
 
import  java.io.IOException;
 
import  javax.servlet.GenericServlet;
import  javax.servlet.ServletException;
import  javax.servlet.ServletRequest;
import  javax.servlet.ServletResponse;
 
public  class  SerlvetDemo1  extends  GenericServlet {
 
     @Override
     public  void  service(ServletRequest req, ServletResponse res)
             throws  ServletException, IOException {
         // TODO Auto-generated method stub
         res.getWriter().write( "this is yif's page " );
     }
 
}

 web 定義及映射

   <servlet>
        <!--定義Servlet:給Servlet類取一個名字-->
        <servlet-name>SerlvetDemo1</servlet-name>
        <servlet-class>com.it.Serlvet.SerlvetDemo1</servlet-class>
    </servlet>
    <servlet-mapping>
        <!--映射Servlet:給Servlet一個訪問地址-->
        <servlet-name>SerlvetDemo1</servlet-name>
        <url-pattern>/SerlvetDemo1</url-pattern>
    </servlet-mapping>

 

4、Servlet的編寫方式:

一、javax.servlet.GenericServlet:通用的Servlet實現,抽象類

 

(常常用)二、javax.servlet.http.HttpServlet:與HTTP協議有關的,抽象類

繼承HttpServlet,而後覆蓋掉doGet或doPost方法便可,不要覆蓋掉service方法。

*Servlet規範中的核心接口類圖

 

5、Servlet的生命週期

一、生命週期(必須清晰):誕生--活着--死亡。人有這個過程,內存中的對象也有。

二、Servlet對象的生命週期

l  誕生:用戶第一次訪問時,由容器建立他的實例。

l  活着:一旦建立就駐留內存(單例)。每次用戶的訪問,容器都會調用sevice方法發出響應(多線程)

l  死亡:應用被卸載或者Tomcat關閉了

實例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public  class  ServletDemo3  extends  HttpServlet { 
     
         //用戶第一次訪問時,只執行一次
         public  ServletDemo3(){
             System.out.println( "調用了Servlet的默認構造方法" );
         }
         
         //用戶第一次訪問時,執行一次。用於對象的初始化
         public  void  init()  throws  ServletException {
             System.out.println( "調用了Servlet的初始化方法" );
         }
         
         //每次用戶訪問都執行
         public  void  doGet(HttpServletRequest request, HttpServletResponse response)
                 throws  ServletException, IOException {
             System.out.println( "執行了Service方法" );
         }
         public  void  doPost(HttpServletRequest request, HttpServletResponse response)
                 throws  ServletException, IOException {
             doGet(request, response);
         }
         
         //調用一次。用於清理工做
         public  void  destroy() {
             System.out.println( "調用了Servlet的銷燬方法" );
         }
 
}

 

6、Servlet的線程安全

7、Servlet的一些細節

一、一個Servlet能夠被映射到多個地址上

二、可使用地址通配符*

寫法一:*.do結尾 。必須以*開頭    好比*.do

寫法二(比一優先級略高):以/開頭,必須以*結尾     好比/action/*

三、默認的Servlet

默認的Servlet的映射路徑是<url-pattern>/</url-pattern>。不須要你們配,由於默認的Servlet負責處理用戶的請求URL找不到匹配的處理工做

一切都是Servlet。訪問 1.html

四、應用在啓動時就完成Servlet的實例化和初始化

8、ServletConfig:Servlet的參數配置

一、ServletConfig:表明着針對當前Servlet的參數配置

二、如何獲得ServletConfig對象的引用:在初始化Servlet時,由容器產生,並傳遞給你

代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public  class  ServletDemo5  extends  HttpServlet {
     protected  void  doGet(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {
         //使用config了
         ServletConfig config = getServletConfig();
         test2(config);
     }
     
     //獲得當前Servlet全部的配置參數
         private  void  test2(ServletConfig config) {
             Enumeration e = config.getInitParameterNames(); //參數的名字
             while (e.hasMoreElements()){
                 String paramName = (String)e.nextElement();
                 System.out.println(paramName+ "=" +config.getInitParameter(paramName));
             }
         }
         //獲得指定名稱的參數的值
         private  void  test1(ServletConfig config) {
             //獲得指定名稱的參數值
             String value = config.getInitParameter( "encoding" );
             System.out.println(value);
         }
     protected  void  doPost(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {
         doGet(request,response);
     }
 
}

 

9、ServletContext

一、ServletContext表明着當前應用每一個應用只有一個ServletContext對象的實例,由容器提供。

二、如何獲取ServletContext的實例:

ServletConfig.getServletContext();

三、ServletContext的生命週期

誕生:應用被加載時就由容器建立好

活着:應用不掛就一直活着

死亡:應用掛了,就掛了

四、域(存活範圍)對象:

ServletContext稱爲應用範圍域對象。

能夠經過ServletContext 傳遞 參數

1
2
3
4
5
6
7
8
9
10
public  class  ServletContextDemo1  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
//      ServletConfig config = getServletConfig();
//      ServletContext sc = config.getServletContext();
         ServletContext sc = getServletContext();
         sc.setAttribute( "p" "ppp" );
         response.getWriter().write( "put done" );
     }

 

1
2
3
4
5
6
7
8
public  class  ServletContextDemo2  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         ServletContext sc = getServletContext();
         String str = (String)sc.getAttribute( "p" );
         response.getWriter().write(str);
     }

 

 ServletContextDemo1 設置參數 ,ServletContextDemo2取出 共享的 ServletContext 實現數據共享

五、配置應用級的參數web.xml

用ServletContext來取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//獲取應用級的參數
public  class  ServletContextDemo3  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         ServletContext sc = getServletContext();
         //得一個參數
//      String value = sc.getInitParameter("encoding");
//      System.out.println(value);
         //得全部的參數
         Enumeration<String> names = sc.getInitParameterNames();
         while (names.hasMoreElements()){
             String paramName = names.nextElement();
             System.out.println(paramName+ "=" +sc.getInitParameter(paramName));
         }
     }

 附:

實現 請求轉發

1
2
3
4
5
6
7
8
9
//轉發:源
public  class  ServletContextDemo4  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         ServletContext sc = getServletContext();
         RequestDispatcher rd = sc.getRequestDispatcher( "/servlet/ServletContextDemo5" ); //轉發的地址。ServletContext獲得的,地址必須以"/"開頭,該"/"就表明着當前應用的訪問路徑/day07_01_servlet
         rd.forward(request, response); //轉發
     }

 

1
2
3
4
5
6
7
//轉發:目標
public  class  ServletContextDemo5  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         response.getWriter().write( "I am five" );
     }

 實現中文文件的下載

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//實現中文文件的下載
public  class  ServletContextDemo6  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         //文件在哪兒?以不變應萬變
         ServletContext sc = getServletContext();
         String realPath = sc.getRealPath( "/WEB-INF/classes/黴女.jpg" ); //  文件存放的真實絕對路徑
//      System.out.println(realPath);
         //構建文件的輸入流
         InputStream in =  new  FileInputStream(realPath);
         //告知客戶端如下載的方式打開:Content-Disposition=attachment;filename=27.jpg
         
         //獲取要下載的文件名
         
         String filename  = realPath.substring(realPath.lastIndexOf(File.separator)+ 1 );
         
         response.setHeader( "Content-Type" "application/octet-stream" );
         response.setHeader( "Content-Disposition" "attachment;filename=" +URLEncoder.encode(filename, "UTF-8" )); //中文屬於不安全的字符,須要進行URL編碼
         
         //用response的字節流進行輸出
         OutputStream out = response.getOutputStream();
         
         int  len = - 1 ;
         byte  b[] =  new  byte [ 1024 ];
         while ((len=in.read(b))!=- 1 ){
             out.write(b,  0 , len);
         }
         in.close();
         out.close();
     }

 encode 編碼

實例: 使用utf-8編碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import  java.io.UnsupportedEncodingException;
import  java.net.URLDecoder;
import  java.net.URLEncoder;
 
import  org.junit.Test;
 
public  class  UrlEncodeDemo {
     @Test
     public  void  test1()  throws  UnsupportedEncodingException{
         String s =  "胡軒" ;
         System.out.println(URLEncoder.encode(s,  "UTF-8" ));
     }
     @Test
     public  void  test2()  throws  UnsupportedEncodingException{
         String s =  "%E8%83%A1%E8%BD%A9" ;
         String v = URLDecoder.decode(s,  "UTF-8" );
         System.out.println(v);
     }
}

 讀取配置文件的各類方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//演示:讀取配置文件的各類方式
public  class  ServletContextDemo7  extends  HttpServlet {
 
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         test31(request, response);
     }
     //請不要把Tomcat等服務器裝在有空格的目錄中
     //類加載器讀取:只能讀取classes或者類路徑中的任意資源。可是不適合讀取特別大的資源。b c 
     private  void  test31(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         ClassLoader cl = ServletContextDemo7. class .getClassLoader(); //獲得類加載器
         URL url = cl.getResource( "com/itheima/resources/c.properties" );
         String path = url.getPath();
         InputStream in =  new  FileInputStream(path);
         Properties props =  new  Properties();
         props.load(in);
         System.out.println(props.getProperty( "hello" ));
     }
     //類加載器讀取:只能讀取classes或者類路徑中的任意資源。可是不適合讀取特別大的資源。b c 
     private  void  test30(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         ClassLoader cl = ServletContextDemo7. class .getClassLoader(); //獲得類加載器
//      InputStream in = cl.getResourceAsStream("b.properties");
         InputStream in = cl.getResourceAsStream( "com/itheima/resources/c.properties" );
         Properties props =  new  Properties();
         props.load(in);
         System.out.println(props.getProperty( "hello" ));
     }
     
     //利用ResourceBundle讀取:b  c ,不能讀a,只能讀取properties的文件
     private  void  test20(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
//      ResourceBundle rb = ResourceBundle.getBundle("b");
         ResourceBundle rb = ResourceBundle.getBundle( "com.itheima.resources.c" );
         System.out.println(rb.getString( "hello" ));
     }
     //利用ServletContext讀取:a b c
     //能夠讀取應用中任何位置上的資源。使用限制:只能在web應用中用
     private  void  test10(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
//      String path = getServletContext().getRealPath("/a.properties");
//      String path = getServletContext().getRealPath("/WEB-INF/classes/b.properties");
         String path = getServletContext().getRealPath( "/WEB-INF/classes/com/itheima/resources/c.properties" );
         
         InputStream in =  new  FileInputStream(path);
         Properties props =  new  Properties();
         props.load(in);
         System.out.println(props.getProperty( "hello" ));
     }
相關文章
相關標籤/搜索