1. 概要

URI仕様RFC3986 は、URIパスパラメーターを名前と値のペアとして定義しました。 行列変数は、Springの造語であり、URIパスパラメーターを渡したり解析したりするための代替実装です。

マトリックス変数のサポートはSpringMVC3.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. 行列変数の使用方法

これらの変数はパスの任意の部分に表示でき、文字equals( “=”)は値を指定するために使用され、セミコロン(’;’)は各行列変数を区切るために使用されます。 同じパスで、同じ変数名を繰り返したり、文字コンマ(’、’)を使用して異なる値を区切ることもできます。

この例には、従業員に関する情報を提供するコントローラーがあります。 各従業員には作業領域があり、その属性で検索できます。 次のリクエストを検索に使用できます。

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
}

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

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

companyDataセグメントの行列変数nameのみを知りたい場合は、入力パラメーターとして次を使用する必要があります。

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

8. ファイアウォールの設定

アプリケーションがSpringSecurityを使用している場合は、 StrictHttpFirewall デフォルトで使用されます。 これにより、セミコロン区切り文字付きのマトリックス変数など、悪意があると思われるリクエストがブロックされます。

私たちはできる カスタマイズ アプリケーション構成でのこの実装は、他の悪意のある要求を拒否しながら、そのような変数を許可します。

ただし、このようにして、アプリケーションを攻撃に対して開くことができます。 したがって、これは、アプリケーションとセキュリティの要件を注意深く分析した後でのみ実装する必要があります。

9. 結論

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

この新しいツールが複雑すぎるリクエストを処理する方法を理解すること、または検索を区切るためにパラメーターを追加するのに役立つことを理解することが重要です。

これらすべての例とコードスニペットの実装は、 GitHubプロジェクトにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。