Reputation: 3328
I'm following this guide stream file to send file through spring but I receive this exception on client side:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.http.ResponseEntity] and content type [application/octet-stream]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:110)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:572)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
at client.services.FileServicesImpl.getFile(FileServicesImpl.java:28)
at client.wbcontroller.ControllerMatlab.Get(ControllerMatlab.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at 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)
at java.lang.Thread.run(Thread.java:745)
The code is easy and only to test, then I have to write byte[]
as file on file system.
@Override
public void getFile(String serverIp, String toStorePath, String filePath) throws Exception{
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<byte[]> responseEntity = restTemplate.getForObject(serverIp + "ATS/client/file/?filePath={filePath}", ResponseEntity.class, filePath);
System.out.println("OK");
}
I think there is a problem with the getForObject
, like as the server want to send the stream but the client can't retrieve it.
On the server I have the same code of the guide:
@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;
try {
inputStream = new FileInputStream(toServeUp);
} catch (FileNotFoundException e) {
//Also useful, this is a good was to serve down an error message
String msg = "ERROR: Could not find the file specified.";
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
}
resp.setContentType("application/octet-stream"); //.exe file
resp.setHeader("Content-Disposition", "attachment; filename=\"Test.zip\"");
Long fileSize = toServeUp.length();
resp.setContentLength(fileSize.intValue());
OutputStream outputStream = null;
try {
outputStream = resp.getOutputStream();
} catch (IOException e) {
String msg = "ERROR: Could not generate output stream.";
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
}
byte[] buffer = new byte[1024];
int read = 0;
try {
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
catch (Exception e) {
String msg = "ERROR: Could not read file.";
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
}finally{
//close the streams to prevent memory leaks
try {
inputStream.close();
outputStream.flush();
outputStream.close();
} catch (IOException e) {
}
}
return null;
}
On the server receive exception about connection reset by peer (when outputStream has 16384 bytesWritten, so the while cycle is done some times). I would like to send any type of file. Before that I stored the file in heap memory and send all the file, but it is a bad approach because with big file, or with simultaneous download, I received heap exception. Do you have any idea?Thanks
Upvotes: 6
Views: 23415
Reputation: 129
Set in the Json response the next header:
"headers": { "Content-Type": "application/json" }
Upvotes: 1
Reputation: 3328
it seems work with row
ResponseEntity<byte[]> responseEntity = restTemplate.getForEntity(serverIp + "ATS/client/file/?filePath={filePath}", byte[].class, filePath);
instead of
ResponseEntity<byte[]> responseEntity = restTemplate.getForObject(serverIp + "ATS/client/file/?filePath={filePath}", ResponseEntity.class, filePath);
Upvotes: 3
Reputation: 8387
Try to control your security configuration maybe an html error page generated by a wrong security configuration.
Upvotes: 0