MVC模式 在講解Servlet前,先介紹一下MVC模式。 M:model 模型,相當於數據層,用於存放數據,如一個Java中的一個bean類 V:view 視圖,相當於頁面層,用於顯示數據,如一個網頁html,或者是jsp C: controller 控制器,相當於業務層,用於處理數據 我們之前使 ...
MVC模式
在講解Servlet前,先介紹一下MVC模式。
- M:model 模型,相當於數據層,用於存放數據,如一個Java中的一個bean類
- V:view 視圖,相當於頁面層,用於顯示數據,如一個網頁html,或者是jsp
- C: controller 控制器,相當於業務層,用於處理數據
我們之前使用的JSP,其中也是可以使用java小腳本來進行數據處理。
但是,我們又想要顯示數據,又要處理數據,代碼都放在JSP文件中,會造成代碼的污染,不方便閱讀和編寫。
這個時候,就出現了MVC架構,用於把數據處理、數據顯示、數據存放都分離,可以更好地管理。
這樣一來,我們就可以把一個JavaWeb項目分為了三個層次,JSP就用來顯示數據,Servlet用來處理數據,bean類用來存放數據。
Servlet介紹
Java Servlet 是運行在 Web 伺服器或應用伺服器上的程式,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 伺服器上的資料庫或應用程式之間的中間層。
簡單來說,Servlet就是可以攔截請求,然後進行處理,之後進行數據的返回,或者是頁面導航(重定向或請求轉發)
作用:
- 處理用戶的請求數據
- 響應用戶請求
- 頁面導航
- 控制業務邏輯的處理
Filter過濾器介紹
過濾器可以動態地攔截請求和響應,以變換或使用包含在請求或響應中的信息。
可以將一個或多個過濾器附加到一個 Servlet 或一組 Servlet。過濾器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 頁面。
過濾器是可用於 Servlet 編程的 Java 類,可以實現以下目的:
在客戶端的請求訪問後端資源之前,攔截這些請求。在伺服器的響應發送回客戶端之前,處理這些響應。
過濾器是指當客戶端請求某些web組件(JSP/Servlet)前先對請求做一些預處理操作,例如提交的表單包含中文時、用戶是否已經進行了登錄等,可以用過濾器對請求數據做中文轉碼;判斷用戶是否進行了登錄等應用場合
官方建議以下案例使用過濾器;
- 身份驗證過濾器(Authentication Filters)。
- 數據壓縮過濾器(Data compression Filters)。
- 加密過濾器(Encryption Filters)。
- 觸發資源訪問事件過濾器。
- 圖像轉換過濾器(Image Conversion Filters)。
- 日誌記錄和審核過濾器(Logging and Auditing Filters)。
- MIME-TYPE 鏈過濾器(MIME-TYPE Chain Filters)。
- 標記化過濾器(Tokenizing Filters)。
- XSL/T 過濾器(XSL/T Filters),轉換 XML 內容。
Lisenter監聽器介紹
監聽器也叫Listener,是Servlet的監聽器,它可以監聽客戶端的請求、服務端的操作等。通過監聽器,可以自動激發一些操作,比如監聽線上的用戶的數量。
由於用得不多,這裡就先大概介紹一下監聽器可以用在哪個哪些功能上
兩種方式,註解 @WebListener和web.xml配置 listener
Servlet與過濾器的流程
Servlet實現
1. 編寫一個Class,使其繼承HTTPServlet,重寫doGet和doPost方法
- doGet 處理用戶的get請求
- doPost 處理用戶的post請求
PS:如果提示沒有發現這個HTTPServlet類,添加一下依賴
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author StarsOne
* @date Create in 2019/9/14 0014 20:14
* @description
*/
public class FirstServlet extends HttpServlet {
/**
* @param req 相當於request內置對象
* @param resp 相當於response內置對象
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//調用doPost方法
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//重定向頁面
resp.sendRedirect(req.getContextPath()+"/hello.jsp");
}
}
2. 打開web.xml,配置Servlet,對請求進行攔截
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>FirstServlet</servlet-name>
<!--這裡要指定Servlet的類,也就是我們之前第一步編寫的那個類-->
<servlet-class>controller.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--這裡的FirstServlet是與上面的servlet-name屬性對應,可以任意取名-->
<servlet-name>FirstServlet</servlet-name>
<!--攔截的請求,請求為hello時,就會跳轉到Servlet去執行-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
關於url-pattern的補充:請看下麵
3. 測試說明
我的項目中定義了兩個jsp,一個是index.jsp
,另外一個則是hello.jsp
index.jsp
中有一個鏈接:
<a href="hello">點擊跳轉</a>
之後點擊上面的鏈接,就會被Servlet攔截,之後進行處理。我們的Servlet其實就是實現了頁面重定向的操作,所以,之後就會跳轉到hello.jsp
的頁面
PS:除了使用web.xml配置的方式之外,也可以使用註解來標記
在Servlet那個類上使用@WebServlet
註解就可以,下麵這段代碼與之前在web.xml文件定義的也是一樣的效果,點擊之後也會跳轉到hello.jsp
中去
@WebServlet("/hello")
public class FirstServlet{
...
}
url-pattern補充
1. 精確匹配:
形式 | 匹配的url |
---|---|
/hello | http://localhost:8080/servletdemo/hello |
/hello.html | http://localhost:8080/servletdemo/hello.html |
之前我們寫的鏈接的href屬性,只寫了hello,其實訪問的url地址就是http://localhost:8080/servletdemo/hello
2. 路徑匹配:
**以“/”字元開頭,並以“/*”結尾的字元串用於路徑匹配**
形式 | 匹配的url |
---|---|
/user/* | http://localhost:8080/user/hello http://localhost:8080/user/he http://localhost:8080/user/hello/aa |
/hello.html | http://localhost:8080/servletdemo/hello.html |
3. 擴展名匹配:
簡單來說,就是url以什麼結尾的
形式 | 匹配的url |
---|---|
*.do | http://localhost:8080/servletdemo/hello.do |
*.hello | http://localhost:8080/servletdemo/aa.hello |
*.action | http://localhost:8080/servletdemo/aa.action |
*.jsp | http://localhost:8080/servletdemo/aa.jsp |
4. 預設匹配:
就是相當於不寫,匹配所有的url
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Filter過濾器實現
1.實現Filter介面,重寫方法
新建一個類,讓它實現Filter介面
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* @author StarsOne
* @date Create in 2019/9/14 0014 21:35
* @description
*/
public class FirstFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("過濾器1已過濾...");
//必須要有doFilter方法,之後過濾結束就會跳轉到匹配的url的Servlet中進行業務邏輯處理
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
配置web.xml文件
規則和Servlet的配置差不多,這裡就不過多解釋了
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>FirstFilter</filter-class>
</filter>
<!--如果有多個,過濾器的順序就是按照web.xml中的過濾器順序進行過濾 -->
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<!--指定過濾全部的url -->
<url-pattern>/*</url-pattern>
</filter-mapping>
測試
測試,會發現點擊鏈接後,控制台輸出了兩次,這也是側面說明瞭請求重定向,客戶端發出了兩次請求