1. 概述
URI 規範 RFC 3986 定義 URI 路徑參數為鍵值對。矩陣變量是 Spring 提出的術語,作為傳遞和解析 URI 路徑參數的一種替代實現。
矩陣變量支持在 Spring MVC 3.2 中可用,旨在 簡化包含大量參數的請求。
在本文中,我們將展示如何簡化使用變量或可選路徑參數在 URI 的不同路徑段中進行的複雜 GET 請求。
2. 配置
要啓用 Spring MVC Matrix 變量,請從配置開始:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
否則,它們默認情況下已禁用。
3. 如何使用矩陣變量
這些變量可以在路徑的任何部分出現,等號 (“=”) 用於提供值,分號 (‘;’) 用於分隔每個矩陣變量。 在同一路徑中,也可以重複相同的變量名稱或使用逗號 (‘,’) 分隔不同的值。
我們的示例中有一個控制器,它提供有關員工的信息。 每個員工都有一個工作區域,我們可以按該屬性搜索。 以下請求可用於搜索:
http://localhost:8080/spring-mvc-java-2/employeeArea/workingArea=rh,informatics,admin
或者如下所示:
http://localhost:8080/spring-mvc-java-2
/employeeArea/workingArea=rh;workingArea=informatics;workingArea=admin
當我們想要在 Spring MVC 中引用這些變量時,我們應該使用註解 @MatrixVariable
在我們的示例中,我們將使用 Employee 類:
public class Employee {
private long id;
private String name;
private String contactNumber;
// standard setters and getters
}
以及 Company類:
public class Company {
private long id;
private String name;
// standard setters and getters
}
這兩個類將綁定請求參數。
4. 定義矩陣變量屬性
我們可以為變量指定必需或默認屬性。 在下面的示例中,contactNumber 是必需的,因此它必須包含在我們的路徑中,例如如下所示:
http://localhost:8080/spring-mvc-java-2/employeesContacts/contactNumber=223334411
請求將被以下方法處理:
@RequestMapping(value = "/employeesContacts/{contactNumber}",
method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<List<Employee>> getEmployeeByContactNumber(
@MatrixVariable(required = true) String contactNumber) {
List<Employee> employeesList = new ArrayList<Employee>();
...
return new ResponseEntity<List<Employee>>(employeesList, HttpStatus.OK);
}
結果,我們將獲取所有具有聯繫電話 223334411 的員工。
5. 補充參數
矩陣變量可以補充路徑變量。
例如,我們正在搜索員工的姓名,但也可以包含其聯繫號碼的起始數字。
該搜索請求應如下所示:
http://localhost:8080/spring-mvc-java-2/employees/John;beginContactNumber=22001
該請求將被以下方法處理:
@RequestMapping(value = "/employees/{name}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<List<Employee>> getEmployeeByNameAndBeginContactNumber(
@PathVariable String name, @MatrixVariable String beginContactNumber) {
List<Employee> employeesList = new ArrayList<Employee>();
...
return new ResponseEntity<>(employeesList, HttpStatus.OK);
}
結果,我們將獲得擁有聯繫號碼 22001 或姓名 John 的所有員工。
6. 綁定所有矩陣變量
如果出於某種原因,我們想要獲取路徑上所有可用的變量,我們可以將它們綁定到一個 Map 中:
http://localhost:8080/spring-mvc-java-2/employeeData/id=1;name=John;contactNumber=2200112334
此請求將被以下方法處理:
@GetMapping("employeeData/{employee}")
@ResponseBody
public ResponseEntity<Map<String, String>> getEmployeeData(
@MatrixVariable Map<String, String> matrixVars) {
return new ResponseEntity<>(matrixVars, HttpStatus.OK);}
當然,我們可以限制將矩陣變量綁定到路徑的特定部分。例如,如果我們有如下請求:
http://localhost:8080/spring-mvc-java-2/
companyEmployee/id=2;name=Xpto/employeeData/id=1;name=John;
contactNumber=2200112334
如果我們只想要獲取屬於 employeeData 的所有變量,那麼我們應該將此作為輸入參數使用:
@RequestMapping(
value = "/companyEmployee/{company}/employeeData/{employee}",
method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Map<String, String>> getEmployeeDataFromCompany(
@MatrixVariable(pathVar = "employee") Map<String, String> matrixVars) {
...
}
7. 偏部綁定
除了簡潔性,靈活性也是另一個優勢,矩陣變量可以以多種不同的方式使用。例如,我們可以從每個路徑片段中獲取每個變量。請考慮以下請求:
http://localhost:8080/spring-mvc-java-2/
companyData/id=2;name=Xpto/employeeData/id=1;name=John;
contactNumber=2200112334
如果我們只想知道 name 變量的 companyData 片段,那麼我們應該使用以下輸入參數:
@MatrixVariable(value="name", pathVar="company") String name
8. 防火牆配置
如果應用程序使用 Spring Security,則 StrictHttpFirewall 將默認使用。它會阻止看似惡意請求,包括使用分號作為分隔符的 Matrix 變量。
我們可以 自定義 此實現,並在應用程序配置中允許此類變量,同時拒絕其他可能存在的惡意請求。
然而,這樣會使應用程序暴露於攻擊中。因此,我們應該僅在仔細分析應用程序和安全要求之後才實施此方法。
9. 結論
本文闡述了矩陣變量可以被使用的各種方式。
理解這種新工具如何處理過於複雜的要求或幫助我們添加更多參數以限定我們的搜索至關重要。