手机扫描二维码或直接输入地址进行springmvc下载文件问题
做一个文件下载功能,主要用于下载手机的apk安装包。
@RequestMapping(value="/downloadApk",method=RequestMethod.GET)
public ResponseEntity<byte[]> downloadApk(HttpServletRequest request) throws Exception{
ResponseEntity<byte[]> re = null;
Map<String,Object> map = new HashMap<String,Object>();
map.put("TYPE", 1);
TB_MOBILE_APK_VERSION apkVersion = apkVersionService.GetEntityByMap("IApkVersionMapper.GetEntityByMap", map);
File file = new File(request.getSession().getServletContext().getRealPath("") + apkVersion.getPATH());
if(file.exists()){
//数据库中做个简单的下载计数
apkVersion.setDOWNLOAD_NUMBER(apkVersion.getDOWNLOAD_NUMBER() + 1);
apkVersionService.Update("IApkVersionMapper",apkVersion);
String fileName = new String(file.getName().getBytes("UTF-8"),"iso-8859-1");
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
re = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.OK);
}
return re;
}
PC浏览器crome,IE11经过测试都没有问题。现将下载地址成个二维码手机扫描下载。我的是安卓手机,扫描弹出下载提示选择继续下载,点击下载,然后如果不是wifi会提示,再继续到下载完毕,log如下:
[FH_sys] 2017-11-20 09:43:08 DEBUG ExceptionHandlerExceptionResolver:133 : Resolving exception from handler [public org.springframework.http.ResponseEntity<byte[]> ZhongYan.Controller.ApkVersionController.downloadApk(javax.servlet.http.HttpServletRequest) throws java.lang.Exception]: org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
[FH_sys] 2017-11-20 09:43:08 DEBUG ResponseStatusExceptionResolver:133 : Resolving exception from handler [public org.springframework.http.ResponseEntity<byte[]> ZhongYan.Controller.ApkVersionController.downloadApk(javax.servlet.http.HttpServletRequest) throws java.lang.Exception]: org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
[FH_sys] 2017-11-20 09:43:08 DEBUG DefaultHandlerExceptionResolver:133 : Resolving exception from handler [public org.springframework.http.ResponseEntity<byte[]> ZhongYan.Controller.ApkVersionController.downloadApk(javax.servlet.http.HttpServletRequest) throws java.lang.Exception]: org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
[FH_sys] 2017-11-20 09:43:08 DEBUG SimpleMappingExceptionResolver:133 : Resolving exception from handler [public org.springframework.http.ResponseEntity<byte[]> ZhongYan.Controller.ApkVersionController.downloadApk(javax.servlet.http.HttpServletRequest) throws java.lang.Exception]: org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
[FH_sys] 2017-11-20 09:43:08 DEBUG DispatcherServlet:993 : Could not complete request
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:333)
at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:718)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:647)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:368)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:346)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
at org.springframework.util.StreamUtils.copy(StreamUtils.java:92)
at org.springframework.http.converter.ByteArrayHttpMessageConverter.writeInternal(ByteArrayHttpMessageConverter.java:65)
at org.springframework.http.converter.ByteArrayHttpMessageConverter.writeInternal(ByteArrayHttpMessageConverter.java:37)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:195)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:218)
at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:186)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
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:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
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:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1374)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
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)
Caused by: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134)
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1178)
at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:691)
at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:471)
at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:409)
at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:551)
at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:76)
at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:199)
at org.apache.coyote.Response.doWrite(Response.java:538)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:328)
... 50 more(这个错误一共报了2次,log太长我就不全部粘贴了)
下载后下载的文件可以安装且大小都没有问题。但是这时候看数据库,下载次数加了3,也就是手机下载前202,下载完205,有兄弟碰到过这样的情况么?怎么解决的?谢谢(pc的crome,ie下载都ok),另外我知道这个计数本身不准确(比如IE或者手机端弹出下载提示,如果不下载这个计数也会+1,但这个不是问题重点,我就不多说了),我也尝试过换成传统的下载文件方法,具体可见
https://www.baidu.com/link?url=kv6dtkITstpIvelzDN1WCdZKuFvCKM2u4YQmZfyOkbL94N9Sg6YFhkOvbLkJPHyK5U7MGzfp7p7WXQpf3h_-FMcfPUksYTWeCJZ6xNMb4C7&wd=&eqid=9af75ffe00007c51000000025a1234c8
的第二种方法。这种也是手机端弹出下载文件的提示的时候会报上面的错误