私は このGoogle App Engine mavenサーバーリポジトリ をSpringに書き換えようとしています。
URLマッピングに問題があります。 Mavenリポジトリサーバーの標準は次のようになります。
末尾にスラッシュが付いたURLはフォルダーを指します。例:
http://127.0.0.1/testDir/
http://127.0.0.1/testDir/testDir2/
他のすべてのファイル(末尾にスラッシュなし)はファイルを指します。例:
http://127.0.0.1/testFile.jar
http://127.0.0.1/testFile.jar.sha1
http://127.0.0.1/testDir/testFile2.pom
http://127.0.0.1/testDir/testFile2.pom.md5
directories および files の元のアプリマッピング。
使用された注釈がありました@javax.ws.rs.Path
これは、regexyをSpringとは異なる方法でサポートします。
私は次のような組み合わせをたくさん試しました:
@ResponseBody
@GetMapping("/{file: .*}")
public String test1(@PathVariable String file) {
return "test1 " + file;
}
@ResponseBody
@GetMapping("{dir: .*[/]{1}$}")
public String test2(@PathVariable String dir) {
return "test2 " + dir;
}
しかし、Springアプリケーションでこれを正しく行う方法を理解できません。
カスタムサーブレットディスパッチャーの作成を避けたいのですが。
Springは、複数のパスセグメントにまたがるマッチングを許可しません。パスセグメントは、パス区切り文字(/)で区切られたパスの値です。そのため、正規表現の組み合わせはありません。 Spring 5では、パスの最後でのみ**または{* foobar}を使用して複数のパスセグメントにまたがることができます。
オプションは限られています。可能であれば、/とは異なる区切り文字を使用するのが最善のオプションだと思います。正規表現を使用できます。
すべての(**)エンドポイントをキャッチし、リクエストからパスを読み取り、それがファイルパスかディレクトリパスかを判断してアクションを実行するためのその他のオプション(乱雑です)。
MavenエンドポイントのSpring実装に関しても、同様の問題が1回ありました。
ファイルのエンドポイントについては、次のようなことができます
/**
* An example Maven endpoint for Jar files
*/
@GetMapping("/**/{artifactId}/{version}/{artifactId}-{version}.jar")
public ResponseEntity<String> getJar(@PathVariable("artifactId") String artifactId, @PathVariable("version") String version) {
...
}
これによりartifactId
とversion
が得られますが、groupId
の場合は文字列の解析が必要になります。 requestUri
の助けを借りて、現在のServletUriComponentsBuilder
を取得できます
String requestUri = ServletUriComponentsBuilder.fromCurrentRequestUri().build().toUri().toString();
// requestUri = /api/v1/com/my/groupId/an/artifact/v1/an-artifact-v1.jar
フォルダエンドポイントの場合、これが機能するかどうかはわかりませんが、試してみることができます
@GetMapping("/**/{artifactId}/{version}")
public ResponseEntity<String> getJar(@PathVariable("artifactId") String artifactId, @PathVariable("version") String version) {
// groupId extracted as before from the requestUri
...
}
さて、Springには、あなたがそれを使用した方法以外に特定の標準はありません。ただし、URLをカスタマイズできる場合は、ディレクトリとファイルを区別する特別な方法があります。これにより、アプリケーションのスケーラビリティと可読性が向上し、多くのコードが削減されます。
現在のコード
@ResponseBody
@GetMapping("/{file: .*}")
public String test1(@PathVariable String file) {
return "test1 " + file;
}
@ResponseBody
@GetMapping("{dir: .*[/]{1}$}")
public String test2(@PathVariable String dir) {
return "test2 " + dir;
}
上記のコードをコントローラークラスで以下のように変更します
private final Map<String, String> managedEntities=ImmutableMap.of(
"file","Type_Of_Operation_You_want_For_File",
"directory","Type_Of_Operation_You_want_For_Directory"
);
@GetMapping(path = "/{type:file|directory}")
public String myFileOperationControl(@PathVariable String type){
return "Test"+managedEntities.get(type));
}
そして、ビジネスロジックごとに、希望する方法をさらに進めます。ご不明な点がありましたらお知らせください。
注:必要に応じてエンドポイントを拡張してください。
Javaコードについてはわかりませんが、一度に1つのパスを確認する場合は、フォルダの文字列が「/」で終了しているかどうかを確認できます。 tはファイルです
\/{1}$
この正規表現は、一致がある場合は文字列が「/」で終わることを確認するだけです。一致する場合はフォルダがあり、一致しない場合はファイルがあります。