我需要在网站上托管.apk文件,以便从Android设备浏览器下载。我在服务器端使用servlet。 要请求下载,我使用我在下载页面的标签中输入的网址http://xxx.xxx.xxx.xxx:8080/root/AppsServlet.do?id=arg
我已将内容类型设置为vnd.android.package-archive
response.setContentType("application/vnd.android.package-archive");
我已经在服务器的default-web.xml(glassfish)中添加了apk mime标签,即使在webapp的部署描述符中也是如此。
APK 应用程序/ vnd.android.package存档
这是来自servlet的一段代码
void sendApk(HttpServletResponse response, String pckg){
FilesManager fm = new FilesManager(FilesManager.APPS_KEY);
response.setContentType("application/vnd.android.package-archive");
File apkFile = fm.getApkFile(pckg);
if(apkFile!= null){
response.setHeader("Content-Disposition","attachment;filename=\""+apkFile.getName()+"\"");
response.setHeader("Content-Description","File Transfert");
response.setHeader("Content-Transfert_Encoding","binary");
FileInputStream fis = null;
OutputStream os = null;
try {
fis = new FileInputStream(apkFile);
//byte [] apkBytes = new byte[fis.available()];
response.setContentLength(fis.available());
//response.setHeader("Content-Length",fis.available()+"");
os = response.getOutputStream();
//java.nio.file.Files.readAllBytes(Paths.get(apkFile.getAbsolutePath()));
// int read = fis.read(apkBytes);
//fis.close();
System.out.println(response.getHeaderNames());
// os.write(apkBytes, 0, apkBytes.length);
// os.flush();
Utils.copyFileStream(fis, os);//Here's the line 76
} catch (FileNotFoundException ex) {
Logger.getLogger(AppsServlet.class.getName()).log(Level.SEVERE, null, ex);
}
catch(IOException i){
Logger.getLogger(AppsServlet.class.getName()).log(Level.SEVERE, null, i);
}
finally{
if(fis != null){
try {
fis.close();
} catch (IOException ex) {
Logger.getLogger(AppsServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(os !=null){
try {
os.close();
} catch (IOException ex) {
Logger.getLogger(AppsServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
这是从Utils类
传输字节的方法 public static void copyFileStream(FileInputStream is, OutputStream os){
final int buffer_size = 20480;
try{
byte [] buffer = new byte[buffer_size];
for(;;){
int count = is.read(buffer, 0, buffer_size);
if(count == -1)
break;
os.write(buffer, 0, count);//Here's (Utils.java:50)
}
os.flush();
}
catch(IOException ex){
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}
}
但是在每次测试和代码中的每次更改之后,仍然会失败,并且始终在服务器的日志中显示以下错误
SEVERE:org.apache.catalina.connector.ClientAbortException:java.io.IOException:已建立的连接已被主机中的软件中止 在org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:430) 在com.sun.grizzly.util.buf.ByteChunk.append(ByteChunk.java:385) 在org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:455) 在org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:442) 在org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:160) at com.dimania.Utils.copyFileStream(Utils.java:50) 在com.dimania.AppsServlet.sendApk(AppsServlet.java:76) at com.dimania.AppsServlet.processRequest(AppsServlet.java:44) 在com.dimania.AppsServlet.doGet(AppsServlet.java:119) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:668) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:770) 在org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 在org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 在org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 在org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) at com.sun.enterprise.v3.services.impl.ContainerMapper $ AdapterCallable.call(ContainerMapper.java:317) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 在com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 在com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 在com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 在com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 在com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 在com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532) 在com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513) 在java.lang.Thread.run(Thread.java:744) 引起:java.io.IOException:已建立的连接已被主机中的软件中止 at sun.nio.ch.SocketDispatcher.write0(Native Method) at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51) 在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:487) 在com.sun.grizzly.util.OutputWriter.flushChannel(OutputWriter.java:108) 在com.sun.grizzly.util.OutputWriter.flushChannel(OutputWriter.java:76) 在com.sun.grizzly.http.SocketChannelOutputBuffer.flushChannel(SocketChannelOutputBuffer.java:426) at com.sun.grizzly.http.SocketChannelOutputBuffer.flushBuffer(SocketChannelOutputBuffer.java:498) at com.sun.grizzly.http.SocketChannelOutputBuffer.realWriteBytes0(SocketChannelOutputBuffer.java:382) at com.sun.grizzly.http.SocketChannelOutputBuffer.realWriteBytes(SocketChannelOutputBuffer.java:364) at com.sun.grizzly.tcp.http11.InternalOutputBuffer $ OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:894) at com.sun.grizzly.tcp.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:159) at com.sun.grizzly.tcp.http11.InternalOutputBuffer.doWrite(InternalOutputBuffer.java:661) at com.sun.grizzly.tcp.Response.doWrite(Response.java:685) 在org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:425) ......还有34个
帮助将受到高度赞赏