目錄
一、JSR303
( 1 )? 是什么
( 2 )? 作用
( 3 )??常用注解
( 4 )? 入門使用
二、攔截器
2.1? 是什么
2.2? 攔截器與過濾器的區(qū)別
2.3? 應用場景
2.4 基礎使用
2.5?用戶登錄權限控制
給我們帶來的收獲
一、JSR303
( 1 )? 是什么
JSR 303是Java規(guī)范請求(Java Specification Request)的一部分,它定義了一套標準的Java Bean驗證規(guī)范,也被稱為Bean驗證。它提供了一種簡單而強大的方式來驗證Java對象的屬性的值。
在開發(fā)應用程序時,數據的驗證是非常重要的,以確保數據的完整性和一致性。傳統(tǒng)的驗證方式通常需要大量的手動編碼,而且容易出錯。JSR 303的目標是提供一種通用的驗證框架,以便開發(fā)人員可以在應用程序中輕松地執(zhí)行輸入驗證。
JSR 303定義了一套驗證規(guī)范,通過在Java類的屬性級別上定義驗證規(guī)則,并通過注解的方式將這些規(guī)則與屬性關聯(lián)起來。開發(fā)人員可以使用內置的驗證注解,也可以自定義驗證注解,以滿足特定的驗證需求。
內置的驗證注解包括@NotNull、@Size、@Min、@Max、@Pattern、@Email等。這些注解可以用于驗證屬性的值是否滿足特定的條件,如非空、長度范圍、最小值、最大值、正則表達式匹配等。
開發(fā)人員還可以通過編寫自定義的驗證注解和驗證器來定義和執(zhí)行自定義的驗證規(guī)則。自定義驗證注解可以根據具體的業(yè)務需求定義,而驗證器則負責實現具體的驗證邏輯。
JSR 303的驗證框架可以在Java EE和Java SE環(huán)境中使用,并且已經被許多Java框架廣泛采用。例如,Hibernate Validator是一個基于JSR 303規(guī)范的驗證框架,它與Hibernate ORM框架集成,提供了強大的數據驗證功能。Spring Framework也支持JSR 303規(guī)范,可以在Spring應用程序中使用注解進行數據驗證。
通過使用JSR 303的驗證框架,開發(fā)人員可以簡化數據驗證的過程,減少手動編碼的工作量,并提高代碼的可讀性和可維護性。它是Java開發(fā)中重要的一部分,幫助開發(fā)人員構建更健壯和可靠的應用程序。
( 2 )? 作用
JSR 303的具體作用是提供一種通用的驗證框架,用于驗證Java對象的屬性的值。它在應用程序開發(fā)中的作用有以下幾個方面:
- 1. 數據驗證:JSR 303允許開發(fā)人員在Java類的屬性級別上定義驗證規(guī)則,并通過注解的方式將這些規(guī)則與屬性關聯(lián)起來。通過使用內置的驗證注解或自定義的驗證注解,開發(fā)人員可以驗證屬性的值是否符合特定的條件,如非空、長度范圍、最小值、最大值、正則表達式等。這樣可以確保輸入數據的完整性和一致性,防止無效或不合法的數據進入應用程序。
- 2. 錯誤處理:JSR 303提供了一種標準的錯誤處理機制,當驗證失敗時,可以生成詳細的錯誤信息。開發(fā)人員可以通過捕獲驗證異常或檢查驗證結果來處理驗證錯誤。這樣可以幫助開發(fā)人員快速定位和解決數據驗證問題,并向用戶提供友好的錯誤提示。
- 3. 可讀性和可維護性:通過使用JSR 303的驗證框架,開發(fā)人員可以將驗證規(guī)則與屬性直接關聯(lián)起來,使代碼更加清晰和易于理解。驗證規(guī)則以注解的形式存在于代碼中,使得驗證邏輯更加直觀和可讀。此外,通過使用注解,驗證規(guī)則與屬性的關聯(lián)性得到了明確的表達,使得代碼更易于維護和修改。
- 4. 框架集成:JSR 303的驗證框架已經被許多Java框架廣泛采用。例如,Hibernate Validator是一個基于JSR 303規(guī)范的驗證框架,與Hibernate ORM框架集成,提供了強大的數據驗證功能。Spring Framework也支持JSR 303規(guī)范,可以在Spring應用程序中使用注解進行數據驗證。通過與這些框架的集成,開發(fā)人員可以更方便地使用JSR 303的驗證功能,提高開發(fā)效率。
總之,JSR 303的具體作用是提供一種簡單而強大的驗證框架,用于驗證Java對象的屬性的值。它可以幫助開發(fā)人員確保輸入數據的完整性和一致性,并提供標準的錯誤處理機制。通過提高代碼的可讀性和可維護性,以及與其他框架的集成,JSR 303可以提高應用程序的質量和開發(fā)效率。
( 3 )??常用注解
注解 | 說明 |
---|---|
@Null | 用于驗證對象為null |
@NotNull | 用于對象不能為null,無法查檢長度為0的字符串 |
@NotBlank | 只用于String類型上,不能為null且trim()之后的size>0 |
@NotEmpty | 用于集合類、String類不能為null,且size>0。但是帶有空格的字符串校驗不出來 |
@Size | 用于對象(Array,Collection,Map,String)長度是否在給定的范圍之內 |
@Range | 用于驗證數字或字符串的值是否在指定范圍內。 |
@Length | 用于String對象的大小必須在指定的范圍內 |
@Pattern | 用于String對象是否符合正則表達式的規(guī)則 |
用于String對象是否符合郵箱格式 | |
@Min | 用于Number和String對象是否大等于指定的值 |
@Max | 用于Number和String對象是否小等于指定的值 |
@AssertTrue | 用于Boolean對象是否為true |
@AssertFalse | 用于Boolean對象是否為false |
@DecimalMin | 用于驗證數字的最小值,可以指定包含最小值的邊界。 |
@DecimalMax | 用于驗證數字的最大值,可以指定包含最大值的邊界。 |
?這些注解可以與屬性的getter方法或字段上使用,用于定義驗證規(guī)則。開發(fā)人員可以根據具體的業(yè)務需求選擇合適的注解來進行數據驗證。此外,JSR 303還支持自定義注解和驗證器,開發(fā)人員可以根據需要定義自己的驗證規(guī)則。
@Validated與@Valid區(qū)別
@Validated:
-
Spring提供的
-
支持分組校驗
-
可以用在類型、方法和方法參數上。但是不能用在成員屬性(字段)上
-
由于無法加在成員屬性(字段)上,所以無法單獨完成級聯(lián)校驗,需要配合@Valid
@Valid:
-
JDK提供的(標準JSR-303規(guī)范)
-
不支持分組校驗
-
可以用在方法、構造函數、方法參數和成員屬性(字段)上
-
可以加在成員屬性(字段)上,能夠獨自完成級聯(lián)校驗
( 4 )? 入門使用
以下的實例代碼是基于本人博客中的代碼進行擴展 :?Spring-MVC的文件上傳下載
導入依賴
<!-- JSR303 -->
<hibernate.validator.version>6.0.7.Final</hibernate.validator.version>
<!-- JSR303 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate.validator.version}</version>
</dependency>
以上代碼在我博客中已經導入完成配置?:? Spring-MVC的文件上傳下載
配置校驗規(guī)則
在實體類相對應的屬性中增加注解用來指定校驗?
例如 :?
@NotNull(message = "房間編號不能為空") //@Size(max = 100,min = 23,message = "編號大小必須在23至100之間") private Long hid; @NotBlank(message = "房間名不能為空") private String hname; @NotBlank(message = "房間的類型名稱不能為空") private String htype;
在需要校驗的對象類的控制器 (?HotelController ) 中,增加要請求處理方法中,使用@Validated或@Valid注解要驗證的對象,并根據BindingResult判斷校驗是否通過;
(增加以下方法代碼) 例如 :?
//需要校驗,使用@Validated或@Valid注解要驗證的對象 @RequestMapping("/valiadd") public String valiadd(@Validated Hotel hotel, BindingResult result, HttpServletRequest request){ // 如果服務端驗證不通過,有錯誤 if(result.hasErrors()){ // 服務端驗證了實體類的多個屬性,多個屬性都沒有驗證通過 List<FieldError> fieldErrors = result.getFieldErrors(); Map<String,Object> map = new HashMap<>(); for (FieldError fieldError : fieldErrors) { // 將多個屬性的驗證失敗信息輸送到控制臺 System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage()); map.put(fieldError.getField(),fieldError.getDefaultMessage()); } request.setAttribute("bugMap",map); }else { hotelbiz.insertSelective(hotel); return "redirect:list"; } return "hot/edit"; }
在將我們的編輯頁面的使用代碼修改為以下代碼 :?
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>酒店管理編輯界面</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/hot/${empty h ? 'valiadd' : 'edit'}" method="post">
房間編號:<input type="text" name="hid" value="${h.hid }"><span style="color: cornflowerblue;margin-left: 20px;">${bugMap.hid}</span><br>
房間名稱:<input type="text" name="hname" value="${h.hname }"><span style="color: cornflowerblue;margin-left: 20px;">${bugMap.hname}</span><br>
房間類型:<input type="text" name="htype" value="${h.htype }"><span style="color: cornflowerblue;margin-left: 20px;">${bugMap.htype}</span><br>
<input type="submit">
</form>
</body>
</html>
最后開啟服務器,到瀏覽器中請求訪問該地址進行測試 :?酒店后臺管理系統(tǒng)http://localhost:8081/ssm/hot/list酒店后臺管理系統(tǒng)
工作臺輸出結果 :
演示效果 :?
二、攔截器
2.1? 是什么
攔截器(Interceptor)是一種在請求處理過程中,對請求進行攔截和處理的機制。它可以在請求到達目標處理器之前、之后或者完全替代目標處理器來執(zhí)行一些特定的操作。攔截器通常用于實現一些橫切關注點(Cross-cutting Concerns),如日志記錄、權限驗證、性能監(jiān)控等。
在Web開發(fā)中,攔截器常用于對請求進行預處理和后處理。當一個請求到達服務器時,攔截器可以在請求到達目標處理器之前對請求進行一些預處理操作,如記錄日志、驗證權限等;在請求處理完成后,攔截器可以對響應進行后處理操作,如修改響應數據、設置響應頭等。
攔截器可以在整個請求處理過程中對請求進行多次攔截,每個攔截器都可以根據自己的需求對請求進行處理,并決定是否繼續(xù)傳遞給下一個攔截器或目標處理器。攔截器可以形成一個攔截器鏈,按照一定的順序依次對請求進行處理,每個攔截器都可以對請求進行修改或者中斷請求處理流程。
在Java的Web開發(fā)中,攔截器通常是通過實現javax.servlet.Filter接口來實現的。Filter是Servlet規(guī)范中定義的一種用于在請求和響應之間進行攔截和處理的組件。通過在web.xml配置攔截器的URL模式和順序,可以將攔截器應用到特定的URL或URL模式上。
攔截器的優(yōu)點是可以將一些通用的操作抽離出來,避免在每個處理器中重復編寫相同的代碼。它提供了一種可擴展和可配置的方式來處理請求,使得系統(tǒng)的功能更加模塊化和可維護。攔截器還可以實現一些與業(yè)務邏輯無關的功能,如性能監(jiān)控、日志記錄等,提高系統(tǒng)的可用性和可靠性。
攔截器工作原理 ?
2.2? 攔截器與過濾器的區(qū)別
什么是過濾器(Filter)
過濾器(Filter)是Java Web開發(fā)中的一種組件,它主要用于對Servlet請求進行預處理和后處理。過濾器可以在請求到達目標Servlet之前或者之后執(zhí)行一些特定的操作,如對請求參數進行解析、字符編碼轉換、請求日志記錄等。通過過濾器,開發(fā)人員可以對請求進行統(tǒng)一的處理,提高代碼的復用性和可維護性。
過濾器是基于Java的Servlet規(guī)范實現的,它是通過實現Filter接口來定義過濾器,并通過在web.xml配置過濾器的URL模式和順序來應用到特定的請求。在過濾器鏈中,每個過濾器都可以對請求進行修改或者中斷請求處理流程。過濾器的執(zhí)行順序由web.xml中的配置決定,按照配置的順序依次對請求進行處理。
過濾器的主要作用包括:
- 請求預處理:對請求進行預處理,如解析請求參數、字符編碼轉換、請求日志記錄等。
- 請求后處理:對請求的響應進行后處理,如設置響應頭、字符編碼轉換、響應日志記錄等。
- 權限驗證:對請求進行權限驗證,如用戶登錄驗證、訪問權限驗證等。
- 緩存控制:對請求進行緩存控制,如設置緩存過期時間、緩存驗證等。
- 異常處理:對請求中可能出現的異常進行處理,如捕獲異常、記錄異常日志等。
攔截器的主要作用包括:
日志記錄:攔截器可以記錄請求的相關信息,如請求的URL、請求參數、請求的處理時間等,用于系統(tǒng)的日志記錄和分析。
權限驗證:攔截器可以對請求進行權限驗證,判斷用戶是否具有訪問特定資源的權限,如用戶登錄驗證、角色權限驗證等。
參數校驗:攔截器可以對請求的參數進行校驗,確保參數的合法性和有效性,如參數的格式、范圍、長度等。
請求預處理:攔截器可以對請求進行預處理,如字符編碼轉換、請求參數解析、請求數據的封裝等。
請求后處理:攔截器可以對請求的響應進行后處理,如設置響應頭、字符編碼轉換、響應數據的封裝等。
異常處理:攔截器可以捕獲請求處理過程中可能出現的異常,并進行相應的處理,如異常的日志記錄、錯誤頁面的跳轉等。
性能監(jiān)控:攔截器可以對請求的處理時間進行監(jiān)控,用于系統(tǒng)的性能分析和優(yōu)化。
2.3? 應用場景
-
日志記錄:攔截器可以用于記錄請求的相關信息,如請求的URL、請求參數、請求的處理時間等。通過攔截器記錄日志,可以方便后續(xù)的系統(tǒng)日志記錄和分析,以及對請求的追蹤和排查問題。
-
權限驗證:攔截器可以用于對用戶進行權限驗證,判斷用戶是否具有訪問特定資源的權限。例如,在用戶訪問某個需要登錄的頁面之前,攔截器可以檢查用戶是否已登錄,并根據用戶的角色判斷是否有權限訪問該頁面。
-
請求預處理:攔截器可以用于對請求進行預處理,如字符編碼轉換、請求參數解析、請求數據的封裝等。通過攔截器進行預處理,可以減輕目標處理器的負擔,提高請求的處理效率和系統(tǒng)的穩(wěn)定性。
-
性能監(jiān)控:攔截器可以用于監(jiān)控請求的處理時間,用于系統(tǒng)的性能分析和優(yōu)化。例如,攔截器可以記錄請求的處理時間,并根據時間閾值進行性能告警或者對慢請求進行分析和優(yōu)化。
總之,攔截器可以應用于多個場景,包括權限驗證、日志記錄、參數校驗、請求預處理、請求后處理、異常處理和性能監(jiān)控等。通過攔截器,開發(fā)人員可以對請求進行統(tǒng)一的處理,提高代碼的復用性和可維護性,同時實現系統(tǒng)的安全性、穩(wěn)定性和性能優(yōu)化。
2.4 基礎使用
創(chuàng)建一個名為?Interceptor 的包,存放創(chuàng)建自定義攔截器
創(chuàng)建一個創(chuàng)建自定義攔截器,名為 :?OneInterceptor,代碼如下
package com.CloudJun.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OneInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("【OneInterceptor】:preHandle...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("【OneInterceptor】:postHandle...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("【OneInterceptor】:afterCompletion...");
}
}
在名為?spring-mvc.xml 的配置文件中,配置自定義攔截器
<mvc:interceptors>
<bean class="com.CloudJun.interceptor.OneInterceptor"></bean>
</mvc:interceptors>
啟動項目服務器,打開瀏覽器訪問請求地址,測試攔截器的攔截效果。
如以下請求地址 :? 酒店后臺管理系統(tǒng)http://localhost:8081/ssm/hot/list酒店后臺管理系統(tǒng)?(根據自己配置的請求地址進行訪問)
演示測試結果為:?
?
攔截器鏈(同時配置多個攔截器,可以進行區(qū)別攔截)
在?Interceptor 的包里,創(chuàng)建一個攔截器 TwoInterceptor。
package com.CloudJun.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TwoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("【TwoInterceptor】:preHandle...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("【TwoInterceptor】:postHandle...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("【TwoInterceptor】:afterCompletion...");
}
}
在名為?spring-mvc.xml 的配置文件中,配置自定義攔截器鏈
<!--2) 配置自定義多攔截器(攔截器鏈)-->
<mvc:interceptors>
<!-- 攔截所以有用請求地址 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.CloudJun.Interceptor.OneInterceptor"/>
</mvc:interceptor>
<!-- 只攔截中間有用名為clz的請求地址 -->
<mvc:interceptor>
<mvc:mapping path="/hot/**"/>
<bean class="com.CloudJun.Interceptor.TwoInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
注意: 這里需要將我們上次配置的攔截器配置,進行注釋,注釋以下配置
<!--配置自定義攔截器-->
<mvc:interceptors>
<bean class="com.CloudJun.Interceptor.OneInterceptor"></bean>
</mvc:interceptors>
啟動項目服務器,打開瀏覽器訪問請求地址,測試攔截器鏈的攔截效果。
如以下請求地址 :? http://localhost:8081/ssm/hot/list?(根據自己配置的請求地址進行訪問)
?
2.5?用戶登錄權限控制
創(chuàng)建一個名為 : LoginInterceptor 的攔截器
package com.CloudJun.Interceptor; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("【implements】:preHandle..."); StringBuffer url = request.getRequestURL(); if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){ // 如果是 登錄、退出 中的一種 return true; } // 代表不是登錄,也不是退出 // 除了登錄、退出,其他操作都需要判斷是否 session 登錄成功過 String hname = (String) request.getSession().getAttribute("hname"); if (hname == null || "".equals(hname)){ response.sendRedirect("/ssm/page/hot/login"); return false; } return true; } }
創(chuàng)建一個名為 :?LoginController 的控制器
package com.CloudJun.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@RequestMapping("/login")
public String login(HttpServletRequest req){
String hname = req.getParameter("hname");
HttpSession session = req.getSession();
if ("zs".equals(hname)){
session.setAttribute("hname",hname);
}
return "redirect:/hot/list";
}
@RequestMapping("/logout")
public String logout(HttpServletRequest req){
req.getSession().invalidate();
return "redirect:/hot/list";
}
}
創(chuàng)建一個 login.jsp 的顯示頁面,進行測試效果
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用戶登入</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/login" method="post" enctype="multipart/form-data">
<label>用戶名稱:</label><br/>
<input type="text" name="hname"/><br/>
<input type="submit" value="登入"/>
</form>
</body>
</html>
在名為?spring-mvc.xml 的配置文件中,配置自定義攔截器,配置登入的用戶。
<!--<!– 用戶權限的請求攔截–>-->
<mvc:interceptors>
<bean class="com.CloudJun.Interceptor.LoginInterceptor"></bean>
</mvc:interceptors>
注意:
這里需要將我們上次配置的攔截器及攔截器鏈配置,進行注釋保證效果,(當然也可不注釋)
<!--配置自定義攔截器--> <mvc:interceptors> <bean class="com.CloudJun.Interceptor.OneInterceptor"></bean> </mvc:interceptors> <!--2) 配置自定義多攔截器(攔截器鏈)--> <mvc:interceptors> <!-- 攔截所以有用請求地址 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.CloudJun.Interceptor.OneInterceptor"/> </mvc:interceptor> <!-- 只攔截中間有用名為clz的請求地址 --> <mvc:interceptor> <mvc:mapping path="/hot/**"/> <bean class="com.CloudJun.Interceptor.TwoInterceptor"/> </mvc:interceptor> </mvc:interceptors>
啟動項目服務器,打開瀏覽器訪問請求地址,測試效果。
如以下請求地址 :? http://localhost:8081/ssm/login ?(根據自己配置的請求地址進行訪問)
效果圖 :?
給我們帶來的收獲
學習完Spring MVC的JSR 303和攔截器可以給我們帶來以下幾方面的收獲:
- 1. 參數校驗的便利性:JSR 303是Java Bean驗證的標準規(guī)范,它提供了一種簡單而強大的方式來對請求參數進行校驗。通過學習JSR 303,我們可以使用注解方式在實體類中定義參數的校驗規(guī)則,從而實現對請求參數的自動校驗。這樣可以減少手動編寫校驗邏輯的工作量,提高開發(fā)效率,同時也提高了代碼的可讀性和可維護性。
- 2. 統(tǒng)一的請求處理流程:攔截器可以用于對請求進行統(tǒng)一的處理,如權限驗證、日志記錄、異常處理等。通過學習攔截器,我們可以實現對請求的統(tǒng)一攔截和處理,從而減少重復代碼的編寫,提高代碼的復用性和可維護性。同時,攔截器還可以對請求進行預處理和后處理,從而實現一些通用的操作,如字符編碼轉換、請求數據的封裝等。
- 3. 系統(tǒng)的安全性和穩(wěn)定性:通過JSR 303和攔截器的應用,我們可以實現對請求參數的校驗和權限驗證,從而提高系統(tǒng)的安全性。同時,攔截器還可以對請求進行異常處理,捕獲可能出現的異常并進行相應的處理,從而提高系統(tǒng)的容錯性和穩(wěn)定性。
- 4. 性能監(jiān)控和優(yōu)化:攔截器可以對請求的處理時間進行監(jiān)控,用于系統(tǒng)的性能分析和優(yōu)化。通過學習攔截器,我們可以實現對請求處理時間的記錄和分析,從而找出系統(tǒng)中的性能瓶頸,并進行相應的優(yōu)化,提高系統(tǒng)的性能和響應速度。
總之,學習完Spring MVC的JSR 303和攔截器可以幫助我們提高開發(fā)效率,減少重復代碼的編寫,提高代碼的復用性和可維護性。同時,它們還可以提高系統(tǒng)的安全性、穩(wěn)定性和性能優(yōu)化,為我們的開發(fā)工作帶來更多的便利和收益。文章來源:http://www.zghlxwxcb.cn/news/detail-706886.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-706886.html
到了這里,關于Spring-MVC使用JSR303及攔截器,增強網絡隱私安全的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!