天天看點

Javaweb03-servlet&filter

1、什麼是servlet

第一個servlet應用程式,實作servlet接口

定義:凡是實作了servlet api接口(或者繼承servlet api接口的實作類)的類就是servlet應用程式;

命周期:

  1. 建立servlet應用程式的執行個體:隻會執行一次,在首次通過url-pattern映射通路時,建立執行個體;
  2. 初始化init方法:隻會執行一次,在建立完servlet應用程式的執行個體後,立刻調用,一般都是使用者初始化servlet應用程式;
  3. 業務處理service方法:執行多次,每當通路請求映射到servlet應用程式時,都會調用service方法,進行請求處理;
  4. 銷毀destroy方法:隻會執行一次,在web應用程式解除安裝時,統一調用,多使用者釋放伺服器資源;

2、建立Servlet的三種方式

2.1 實作 servlet接口

public class HelloServlet implements Servlet {
	// 空參構造
	public  HelloServlet() {
		System.out.println("---------HelloServlet 空參構造--------------");
	}
	
	@Override
	public void destroy() {
		System.out.println("---------HelloServlet destroy--------------");
	}

	@Override
	public ServletConfig getServletConfig() {
		System.out.println("---------HelloServlet getServletConfig--------------");
		return null;
	}

	@Override
	public String getServletInfo() {
		System.out.println("---------HelloServlet getServletInfo--------------");
		return null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("---------HelloServlet init--------------");	
	}

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		System.out.println("---------HelloServlet service--------------");
	}

}
           

2.1.1 servlet的生命周期

//第一次通路映射路徑:
---------HelloServlet 空參構造---------
---------HelloServlet init-----------(//如果配置了load-on-startup 項目啟動前面兩步就會立刻執行)
    
---------HelloServlet service--------(//每次通路映射路徑都會調用此方法)

---------HelloServlet destroy--------(//關閉服務才會調用)
           

2.2 繼承 GenericServlet

public class HelloServlet2 extends GenericServlet{
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    }
}
           

2.3 繼承 HttpServlet

public class StudentInfoServlet extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        // 一般直接在get請求處理方法中,直接調用post方法,實作兩種請求統一處理
        //doPost(request, response);
    }
}

           

3、Servlet 的注冊配置

3.1 注冊

<!-- 注冊第一個 servlet應用程式 -->
 <servlet>
 	<!-- servlet應用程式的别名 -->
    <servlet-name>helloServlet</servlet-name>
    <!-- servlet應用程式的全類名 -->
    <servlet-class>com.kgc.servlet.HelloServlet</servlet-class>
 </servlet>

 <!-- 映射第一個servlet應用程式 -->
 <servlet-mapping>
 	<servlet-name>helloServlet</servlet-name>
 	<url-pattern>/hello</url-pattern>
 </servlet-mapping>
           

3.2 模糊映射

<servlet-mapping>
 	<servlet-name>helloServlet</servlet-name>
 	<!-- 比對方法 前比對 /user/* 等等 -->
 	<!-- <url-pattern>/*</url-pattern> -->
 	<!-- 比對方法 後比對 -->
 	<!--<url-pattern>*.do</url-pattern>-->
 	<!-- 不能 /*.xx  兩種一起使用 -->
 </servlet-mapping>
           

3.3 初始化參數

3.3.1 單個servlet内部初始化參數

<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.kgc.servlet.HelloServlet</servlet-class>
    <!--  指定servlet内部初始化參數,必須在load-on-startup之前 -->
    <init-param>
    	<param-name>key</param-name>
    	<param-value>value</param-value>
    </init-param>
 </servlet>
           

3.3.2 擷取單個servlet内部初始化參數

@Override
public void init(ServletConfig config) throws ServletException {
    System.out.println("---------HelloServlet init--------------");

    //擷取目前servelt初始化參數 
    //通過 config 對象擷取
    String encoding = config.getInitParameter("encoding");
    System.out.println("******* servlet内部初始化參數 encoding = "+encoding+"******");
}
           

3.3.3 全局servlet初始化參數

<context-param>
    <param-name> key </param-name>
    <param-value> value </param-value>
</context-param>
           

3.3.4 擷取全局servlet初始化參數

//擷取全局servelt初始化參數
//通過ServletContext 對象擷取
String encodingContext = config.getServletContext().getInitParameter("encoding");
System.out.println("**** servlet全局初始化參數 encodingContext = "+encodingContext+"*****");
           

3.3.5 servlet 的啟動優先級

預設情況下,啟動是不會建立執行個體和初始化;

配置了load-on-startup,servlet應用程式就會在伺服器啟動時,建立執行個體并初始化 ;

允許值為正整數(可以為0)負數不可以,一般為1,值的作用是指定servlet應用程式的建立時機,值越小優先級,越高,越早建立執行個體并初始化;

<load-on-startup>1</load-on-startup>
           

3.3.6 歡迎頁面

<!-- 歡迎頁面可以設計多個,在web.xml中越靠上優先級越高 -->
<welcome-file-list>
	<welcome-file>login.html</welcome-file>
</welcome-file-list>
           

3.3.7錯誤頁面

<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>
           

4、相對路徑和絕對路徑

通過servlet的跳轉使用相對路徑,容易出錯,會導緻缺少部分路徑,而找不到資源;

一般使用絕對路徑,進行跳轉;

//擷取項目跟路徑
<%=request.getContextPath()%>  //擷取跟路徑後再根據實際情況進行路徑拼接
           

5、filter

5.1 建立過濾器

實作Filter的應用就是過濾器;

public class MyFirstFilter implements Filter{
	public MyFirstFilter() {
		System.out.println("-----MyFirstFilter 空參構造 ------");
	}
	@Override
	public void destroy() {
		System.out.println("-----MyFirstFilter destroy ------");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("-----MyFirstFilter doFilter ------");
		//FilterChain 是決定請i去是否放行的操作對象,如果請求放行,必須要調用FilterChain的請求過濾方法doFilter
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("-----MyFirstFilter init ------");
	}
}
           

5.2 filter 注冊與映射

<!-- 注冊過濾器first:配置内容和servlet基本一樣,就是标簽不一樣 -->
<filter>
    <filter-name>myFirstFilter</filter-name>
    <filter-class>com.kgc.filter.MyFirstFilter</filter-class>
</filter>
<!-- 過濾器first映射 -->
<filter-mapping>
    <filter-name>myFirstFilter</filter-name>
    <url-pattern>/filter01.jsp</url-pattern>
    <!-- filter的映射也可以模糊比對 /* 等等 -->
</filter-mapping>
           

5.3 filter 的初始化參數

<init-param>
    <param-name>encoding</param-name>
    <param-value>utf-8</param-value>
</init-param>
           

擷取參數:

//一些配置的初始化參數可以通過 filterConfig.getInitParameter(key) 擷取
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    this.encoding = filterConfig.getInitParameter("encoding");
    System.out.println("擷取字元集過濾器中的初始化編碼:"+this.encoding);
}
           

5.4 filter 的執行順序

web.xml中映射順序,越上面的越先執行;

MySecondFilter

public class MySecondFilter implements Filter {
	@Override
	public void destroy() {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("-----1.MySecondFilter  doFilter before ------");
		chain.doFilter(request, response);
		System.out.println("-----2.MySecondFilter  doFilter after ------");
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}
           

MyThridFilter

public class MyThridFilter implements Filter {
	@Override
	public void destroy() {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("-----3.MyThridFilter doFilter before ------");
		chain.doFilter(request, response);
		System.out.println("-----4.MyThridFilter doFilter after ------");
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}
           

filterTarget.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		System.out.println("-----5.Filter Target Page-----");
	%>
 	<h2>Filter Target Page</h2>
</body>
</html>
           

web.xml

<!-- second -->
<filter>
    <filter-name>mySecondFilter</filter-name>
    <filter-class>com.kgc.filter.MySecondFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>mySecondFilter</filter-name>
    <url-pattern>/web3filter01/filterTarget.jsp</url-pattern>
</filter-mapping>

<!-- third -->
<filter>
    <filter-name>myThridFilter</filter-name>
    <filter-class>com.kgc.filter.MyThridFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>myThridFilter</filter-name>
    <url-pattern>/web3filter01/filterTarget.jsp</url-pattern>
</filter-mapping>
           

運作結果順序:

//執行順序
-----1.MySecondFilter  doFilter before ----
-----3.MyThridFilter doFilter before ------
-----5.Filter Target Page-----
-----4.MyThridFilter doFilter after -------
-----2.MySecondFilter  doFilter after ------
           

5.5 編碼過濾器

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    //this.encoding 編碼名可以存放在過濾器初始化參數中,通過filterConfig.getInitParameter("encoding");擷取
    //poet請求亂碼處理
    request.setCharacterEncoding(this.encoding);
    //響應編碼
    response.setContentType("text/html; charset=UTF-8");
    response.setCharacterEncoding(this.encoding);

    //請求放行
    chain.doFilter(request, response);
}