搭建了一个ftp服务器,供用户进行上传下载,在下载过程中发现,一些文件,例如txt,jpg,png,pdf等直接被浏览器解析了。在浏览器中显示其内容,没有下载。
下面通过网上查询得到一些解决方法:
1:修改ftp目录下的.htacess文件,这个文件主要做一些类型映射,使各个文件类型映射为 octet-stream 类型,这样浏览器就不能解析了。
但是,我没有在ftp目录下发现该文件,通过filezilla连接服务器, filezilla>服务器>强制显示隐藏文件 ,也没有发现该文件。听说该文件是apache独有的,我用的是vsftpd服务器,不知道是否存在不一致,于是放弃。
2:第二种方法
使用ajax请求,将文件输出流(OutputStream)作为回调结果返回。
html代码, 后台代码同第4中方法。
<!DOCTYPE html> <html lang="en"> <head> <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script> <meta charset="UTF-8"> <title>Title</title> <script> function link() { $.ajax({ type: "get", //请求方式 url: "downloadFileByOutputStream", //请求路径 data: { "filename":‘homepage.png‘ //请求参数 }, async: true, //异步,(同步已经废弃,会报错)。 success: function (flag) { //请求成功,flag返回数据 if (flag != "") { console.log(flag); //浏览器控制台打印数据 var obj = eval(flag); //对数据进行转换 localStorage[‘UsertypeSelect‘]=JSON.stringify(obj); //将返回的数据存储到本地。 }; } }); } </script> </head> <body> <a href="javascript:void(0)" onclick="link()">客户端下载OutputStream</a> //调用上面的函数 </body> </html>
调用之后,发现数据乱码, eval(flag)对返回数据转化失败。
3: 使结果作为PrintWriter流作为回调结果,使用隐藏表单提交的方式对流进行回调。结果 txt,doc等字符文件能够下载,但是图片等字节文件不能下载。
前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script> <script> function download(){ console.log(‘执行‘); downloadTemplate(‘/downloadFileByPrintWriter‘, ‘filename‘, ‘homepage.png‘); } function downloadTemplate(action, type, value){ //action 请求接口, type : 后台接口需要的参数名,value 请求的参数值 console.log(action); var form = document.createElement(‘form‘); //创建表单 document.body.appendChild(form); form.style.display = "none"; form.action = action; //接口 form.id = ‘download‘; //表单id form.method = ‘post‘; //请求方式 var newElement = document.createElement("input"); //创建元素,类型为input newElement.setAttribute("type","hidden"); //隐藏 newElement.name = type; //元素名为type newElement.value = value; //元素值 value form.appendChild(newElement); form.submit(); //提交 } </script> </head> <body> <span onclick="download()">客户端下载PrintWriter</span> </body> </html>
后台代码:
/** * 根据给定的文件名进行下载 * Description: 从FTP服务器下载文件 * @param filename 要下载的文件名 * @return */ @RequestMapping("/downloadFileByPrintWriter") @ResponseBody public String downloadFileByPrintWriter(HttpServletResponse response, String filename) throws IOException { FTPClient ftp = new FTPClient(); try { int reply; ftp.connect(host, port); ftp.login(username, password);// 登录 ftp.enterLocalPassiveMode(); //将ftp设置为被动模式。否则不成功。 reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return "ftp无连接"; } ftp.changeWorkingDirectory(publicFilePath);// 转移到FTP服务器目录 logger.debug("远程路径" + publicFilePath); FTPFile[] fs = ftp.listFiles(); for (FTPFile ff : fs) { logger.debug("远程文件名" + ff.getName()); if (ff.getName().equals(filename)) { InputStream in = ftp.retrieveFileStream(ff.getName()); //读取ftp服务器文件,返回输入流 int len = 0; byte[] buff = new byte[1024]; response.reset(); //重置响应 response.setContentType("application/octet-stream"); //设置响应类型为流类型 response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); //文件名 InputStreamReader inputStreamReader = new InputStreamReader(in); PrintWriter fw = response.getWriter(); //得到response的字符打印流 //创建一个rd的字符留缓冲区,将字符装载入缓冲区中 BufferedReader bf = new BufferedReader(inputStreamReader); char[] chs = new char[1024]; // while ((len = bf.read(chs)) != 0) { // logger.debug("向fw写入"); //// fw.write(chs, 0, len); // } String str=null; while ((str = bf.readLine()) != null) { fw.write(str); //将ftp输入流写出到printWriter fw.flush(); } fw.flush(); in.close(); fw.close(); return "成功"; } } ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return "下载失败"; }
4:将文件作为OutputStream流作为回调结果,使用隐藏表单提交的方式对流进行回调。成功
html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script> <script> function download(){ console.log(‘执行‘); downloadTemplate(‘/downloadFileByOutputStream‘, ‘filename‘, ‘homepage.png‘); } function downloadTemplate(action, type, value){ console.log(action); var form = document.createElement(‘form‘); document.body.appendChild(form); form.style.display = "none"; form.action = action; form.id = ‘download‘; form.method = ‘post‘; var newElement = document.createElement("input"); newElement.setAttribute("type","hidden"); newElement.name = type; newElement.value = value; form.appendChild(newElement); form.submit(); } </script> </head> <body> <span onclick="download()">客户端下载PrintWriter</span> </body> </html>
后台代码:
/** * 根据给定的文件名进行下载 * Description: 从FTP服务器下载文件 * @param filename 要下载的文件名 * @return */ @RequestMapping("/downloadFileByOutputStream") @ResponseBody public String downloadFileByOutputStream(HttpServletResponse response, String filename) throws IOException { logger.debug("下载ByOutputStream"); FTPClient ftp = new FTPClient(); try { int reply; ftp.connect(host, port); // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器 ftp.login(username, password);// 登录 ftp.enterLocalPassiveMode(); //将ftp设置为被动模式。否则不成功。 reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return "连接失败"; } ftp.changeWorkingDirectory(publicFilePath);// 转移到FTP服务器目录 logger.debug("远程路径" + publicFilePath); FTPFile[] fs = ftp.listFiles(); for (FTPFile ff : fs) { logger.debug("远程文件名" + ff.getName()); if (ff.getName().equals(filename)) { InputStream in = ftp.retrieveFileStream(ff.getName()); logger.debug(in.toString()); int len = 0; byte[] buff = new byte[1024*1024]; response.reset(); response.setContentType("application/octet-stream"); //Name the file response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); // response.addHeader("Content-Length", out..ToString()); OutputStream out=response.getOutputStream(); //响应输出字节流 // OutputStream out = new PipedOutputStream(); while((len=in.read(buff))!=-1){ logger.debug("以字节流形式写出OutPutStream"); out.write(buff, 0, len); out.flush(); } in.close(); out.close(); return "成功"; } } ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return "失败"; }
原文地址:https://www.cnblogs.com/liyafei/p/9296770.html
时间: 2024-10-01 20:07:45