Spring 4 の REST コントローラーを使用して REST サービスを作成し、Spring の RestTemplate でテストしています。
新しいファイルを作成するリクエスト (POST) を受け入れたいと思います。
私のシステムにおけるファイルの概念には、(1) メタデータ、(2) コンテンツの 2 つの部分が含まれます。したがって、MultipartHttpServletRequest を受け入れるようにレスト コントローラーを定義しました。1 つの部分からメタデータ マップを取得し、2 番目の部分からファイル入力ストリームを取得したいのですが、これを機能させる方法がわかりません。
ファイルが非常に大きくなる可能性があり、ユーザーにすべてのファイル データを含む巨大な http 要求を送信させてネットワークに負荷をかけたくないため、要求にファイル全体ではなく入力ストリームを含めることが重要です。
以下に、テスト Http リクエストを送信するために使用する REST コントローラー メソッドとテストの非動作実装を示します。以下のコードを実行すると、500 Server Error 例外が発生します。これは、RestController の構成方法とリクエストが正しく一致していないと思われるためです。
コントローラーで、Map と InputStream の代わりに @RequestParam の汎用オブジェクトを作成しようとしました。これは 500 例外なしで実行されますが、オブジェクトは文字列として解釈されます。これは私が望むものではありません (これはメタデータを処理するためには問題ありませんが、ファイルの InputStream が必要です!)。
リクエストを作成します。
public void createAndSendRequest() throws IOException {
MultiValueMap<String,Object> requestMap = new LinkedMultiValueMap<String, Object>();
url = "http:/my.domain/someService/document";
method = HttpMethod.POST;
returnType = String.class;
// add metadata to the request
Map<String, String> metadata = new HashMap<>();
metadata.put("somedata1", "alpha");
metadata.put("somedata2", "beta");
metadata.put("somedata3", "gamma");
requestMap.add("metadata", metadata);
// add the file to the request (as a stream?)
URL fileUrl = this.getClass().getClassLoader().getResource("test.txt");
File file = new File(fileUrl.getFile());
InputStream stream = new FileInputStream(file);
InputStreamResource resource = new InputStreamResource(stream);
requestMap.add("file", resource);
response = restTemplate.exchange(url, method, new HttpEntity<Object>(requestMap, headers), returnType);
handleResponse(response);
}
リクエストを処理するための Rest Controller メソッド:
@RequestMapping(value = "/document", method = RequestMethod.POST)
public ResponseEntity<String> createDocument(MultipartHttpServletRequest request,
@RequestParam("file") InputStream fileStream,
@RequestParam("metadata") Map metadata) throws Exception {
// do some file stream work
int ch;
ch = fileStream.read();
while (ch != -1) {
System.out.println((char) ch);
ch = fileStream.read();
}
// do application stuff
return new ResponseEntity(HttpStatus.CREATED);
}