我必须将一个java类的文件发送到Spring rest Web服务。
使用案例:从客户端,可以选择服务器,服务器上的文件以及保存文件的位置。在服务器上,我必须检索文件(从客户端选择)并发送到客户端。
目前我使用一个字节数组,但是当文件超过50MB时,我收到堆异常,而我从我的网页到控制器MultipartFile
,它甚至可以使用超过500Mb的文件,但我使用相同的做法。
从客户端我使用这个spring方法:
Response responseStatus = restTemplate.postForObject(serverIp + "ATS/client/file/?toStorePath={toStorePath}", responseSend, Response.class, toStorePath);
并在responseSend中放置了我可能删除的文件名,字节数组和其他字段。我认为这是一个糟糕的方法,因为将所有文件加载到堆内存中。是否可以发送从文件系统获取文件的MultipartFile(或者它可能显示相同的问题)? 或者可以通过其他方式进行转移(例如big file transfer或oracle)?但我需要使用https
更新可能的解决方案1: 我想到下面的代码,但在客户端输入流是null,我如何检索文件的名称? 服务器端:
@Override
@RequestMapping(value = "/file",produces=MediaType.APPLICATION_OCTET_STREAM, method = RequestMethod.GET)
public javax.ws.rs.core.Response getAcquisition(@RequestParam(value="path", required = true) String path){
try(InputStream is = new FileInputStream(path)){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[4096];
while ((len = is.read(buffer, 0, buffer.length)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println("Server size: " + baos.size());
return javax.ws.rs.core.Response.ok(baos).build();
}catch(Exception e){
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in MatlabClientControllerImpl::getAcquisition :" + errorResponse.getStacktrace());
return null;
}
客户方:
@Override
public Response getFile(String serverIp, String toStorePath, String filePath){
FileOutputStream out = null;
InputStream is = null;
try{
Client client = ClientBuilder.newClient();
String url = serverIp + "ATS/client/file/";
javax.ws.rs.core.Response response = client.target(url).queryParam("path",filePath).request().get();
String location = toStorePath + "prova.zip";
out = new FileOutputStream(location);
is = (InputStream)response.getEntity();
int len = 0;
byte[] buffer = new byte[4096];
while((len = is.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return new Response(false, false,"Your required file has been correctly written!" , null);
}catch(Exception e){
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in FileServicesImpl::getFile :" + errorResponse.getStacktrace());
return new Response(false, false,"Error while write file into local file system!" , errorResponse);
}finally{
try{
if (out != null){
out.flush();
out.close();
}
if (is!=null)is.close();
}catch (Exception e){
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in FileServicesImpl::getFile :" + errorResponse.getStacktrace());
return new Response(false, false,"Error during stream closeing!" , errorResponse);
}
}
这是服务器上的例外
dic 04,2015 5:00:54 PM org.apache.catalina.core.StandardWrapperValve invoke GRAVE:servlet [dispatcher]的Servlet.service()在路径[/ ATS]的上下文中引发异常[请求处理失败;嵌套异常是org.thymeleaf.exceptions.TemplateInputException:错误解析模板"客户端/文件",模板可能不存在或任何已配置的模板解析器可能无法访问,具有根本原因 org.thymeleaf.exceptions.TemplateInputException:解析模板"客户端/文件"时出错,模板可能不存在或任何已配置的模板解析器可能无法访问 在org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246) 在org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104) 在org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060) 在org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011) 在org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335) 在org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190) 在org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) 在org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) 在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) 在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 在org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:622) 在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) 在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) at org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:673) 在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1526) 在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run(NioEndpoint.java:1482) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61) 在java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:0)
超过REST的500mb。我不喜欢这个主意。
使用webservice只发送一个下载链接到你的文件,让你的http-Server像Apache或NGINX处理下载请求并提供文件。