我创建了一个Spring Web服务文件,因此客户端可以从服务器下载一个文件(因为文件可能很大而流式传输),现在我想从客户端实现文件上传(客户端是java类,它调用Web服务并上传文件)。 第一步,下载部分,我使用了这段代码: 服务器端(此代码将得到改进)
@Override
@RequestMapping(value = "/file", method = RequestMethod.GET)
public @ResponseBody ResponseEntity<byte[]> getAcquisition(HttpServletResponse resp,@RequestParam(value="filePath", required = true) String filePath){
final HttpHeaders headers = new HttpHeaders();
File toServeUp = new File(filePath);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new FileInputStream(toServeUp);
resp.setContentType("application/octet-stream"); //.exe file
resp.setHeader("Content-Disposition", "attachment; filename=\""+toServeUp.getName()+"\"");
Long fileSize = toServeUp.length();
resp.setContentLength(fileSize.intValue());
outputStream = resp.getOutputStream();
byte[] buffer = new byte[1024];
int read = 0;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
catch (Exception e) {
String msg = "ERROR: Could not send file.";
headers.setContentType(MediaType.TEXT_PLAIN);
//If I set NOT_FOUND on the client I have to catch 404 exception
return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
}finally{
//close the streams to prevent memory leaks
try {
if (inputStream!=null)inputStream.close();
if (outputStream!=null){
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
String msg = "ERROR: Could not close stream.";
headers.setContentType(MediaType.TEXT_PLAIN);
//If I set NOT_FOUND on the client I have to catch 404 exception
return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
}
}
return null;
}
客户端
@Override
public Response getJsonFromRest(String url, String... queryParams) {
try{
Response response;
RestTemplate restTemplate = new RestTemplate();
if (queryParams.length!=0){
String urlParametrized = addQueryParam(url, queryParams);
response = restTemplate.getForObject(urlParametrized, Response.class);
}
else{
response = restTemplate.getForObject(url, Response.class);
}
return response;
}catch(Exception e){
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in FileServicesImpl::getJsonFromRest :" + errorResponse.getStacktrace());
return new Response(false, false,"Error with web service request!" , errorResponse);
}
}
现在对于文件上传,我应该使用上面的代码,但是反转客户端 - 服务器代码。所以在客户端我可以使用
String response= restTemplate.postForEntity(serverIp + "/client/file/?toStorePath={toStorePath}", responseSend, String.class, toStorePath);
但是如何设置HttpServletResponse
并将文件流发送到我的服务器?
感谢
更新 暂时此代码有效,但我想使用spring而不是http方法 在客户端
@Override
public Response sendFile(String serverIp, String toStorePath, String filePath) {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()){
HttpPost httppost = new HttpPost(serverIp + "ATS/client/file");
File file = new File(filePath);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
ContentBody cbFile = new FileBody(file);
ContentBody cbPath= new StringBody(toStorePath,ContentType.TEXT_PLAIN);
builder.addPart("file", cbFile);
builder.addPart("toStorePath",cbPath);
httppost.setEntity(builder.build());
CloseableHttpResponse httpResponse = httpClient.execute(httppost);
HttpEntity resEntity = httpResponse.getEntity();
System.out.println(httpResponse.getStatusLine());
if (resEntity != null) {
ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue(resEntity.getContent(), Response.class);
EntityUtils.consume(resEntity) ;
return response;
}
//It should never be thrown
else return new Response(false, false, "Error with server response" , null);
}catch(Exception e){
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in FileServicesImpl::sendFile :" + errorResponse.getStacktrace());
return new Response(false, false,"Error sending the file!" , errorResponse);
}
取而代之的是服务器:
@Override
@RequestMapping(value = "/file", method = RequestMethod.POST)
public @ResponseBody Response storeAcquisition(@RequestParam("file") MultipartFile file, @RequestParam("toStorePath") String toStorePath){
String name= file.getOriginalFilename();
if (!file.isEmpty()) {
try {
file.transferTo(new File(toStorePath + "/" + name));
return new Response(true, true, "You successfully uploaded " + name + " into " + toStorePath, null);
} catch (Exception e) {
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in MatlabClientControllerImpl::storeAcquisition :" + errorResponse.getStacktrace());
return new Response(false, false, "You failed to upload " + name, errorResponse);
}
} else {
return new Response(false, false, "You failed to upload " + name + " because the file was empty.", null);
}
}