我正在使用 Spring 4 的 rest 控制器创建一个 REST 服务并使用 Spring 的 RestTemplate 进行测试。
我想接受创建新文件 (POST) 的请求。
我系统中文件的概念包含两部分——(1)元数据,(2)内容。因此,我定义了我的休息控制器来接受 MultipartHttpServletRequest。我想从一部分中提取元数据映射,从第二部分中提取文件输入流,但我不确定如何使这项工作。
在请求中使用输入流而不是整个文件很重要,因为文件可能非常大,我不想通过让用户发送带有所有文件数据的巨大 http 请求来给网络带来压力。
下面我有一个我的休息控制器方法的非工作实现和我用来发送测试 Http 请求的测试。当我运行下面的代码时,我得到一个 500 服务器错误异常,因为我认为请求与我配置 RestController 的方式不匹配。
我已经尝试在控制器中制作@RequestParam 的通用对象,而不是 Map 和 InputStream。这将在没有 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);
}