1概要

URI仕様https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986]は、URIパスパラメータを名前と値のペアとして定義しました。行列変数はSpringの造語であり、URIパスパラメータを渡して解析するための代替実装です。

行列変数のサポートはSpring MVC 3.2で利用可能になりました。これは

多数のパラメータを持つリクエストを

単純化することを意図しています** 。

この記事では、URIの異なるパス・セグメント内で可変またはオプションのパス・パラメーターを使用する複雑なGET要求をどのように単純化できるかを説明します。


2構成

Spring MVCマトリックス変数を有効にするために、設定から始めましょう:

@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/employeeArea/workingArea=rh,informatics,admin

またはこのように:

http://localhost:8080/spring-mvc-java
 /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
}

これら2つのクラスはリクエストパラメータをバインドします。

** 4行列変数プロパティの定義

**

変数には必須またはデフォルトのプロパティを指定できます。次の例では、

contactNumber

が必要なので、パスに含める必要があります。

http://localhost:8080/spring-mvc-java/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/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/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/  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/  companyData/id=2;name=Xpto/employeeData/id=1;name=John;
  contactNumber=2200112334


companyData

セグメントの行列変数

name

だけを知りたい場合は、入力パラメータとして次のように使用します。

@MatrixVariable(value="name", pathVar="company") String name


8結論

この記事では、行列変数を使用できるさまざまな方法について説明しました。

この新しいツールが複雑すぎる要求をどのように処理できるか、または検索を限定するためにパラメータを追加するのに役立つかを理解することが不可欠です。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/spring-mvc-java#readme[GitHubプロジェクト]にあります。これはMavenベースのプロジェクトです。そのため、インポートしてそのまま実行するのは簡単なはずです。