package com.javafast.common.utils; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class FileDownload { //以流的方式下载 public static HttpServletResponse download(String path, HttpServletResponse response) { try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase(); // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } return response; } //下载本地文件 public void downloadLocal(HttpServletResponse response) throws FileNotFoundException { // 下载本地文件 String fileName = "Operator.doc".toString(); // 文件的默认保存名 // 读到流中 InputStream inStream = new FileInputStream("c:/Operator.doc");// 文件的存放路径 // 设置输出的格式 response.reset(); response.setContentType("bin"); response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // 循环取出流中的数据 byte[] b = new byte[100]; int len; try { while ((len = inStream.read(b)) > 0) response.getOutputStream().write(b, 0, len); inStream.close(); } catch (IOException e) { e.printStackTrace(); } } //下载网络文件 public void downloadNet(HttpServletResponse response) throws MalformedURLException { // 下载网络文件 int bytesum = 0; int byteread = 0; URL url = new URL("windine.blogdriver.com/logo.gif"); try { URLConnection conn = url.openConnection(); InputStream inStream = conn.getInputStream(); FileOutputStream fs = new FileOutputStream("c:/abc.gif"); byte[] buffer = new byte[1204]; int length; while ((byteread = inStream.read(buffer)) != -1) { bytesum += byteread; System.out.println(bytesum); fs.write(buffer, 0, byteread); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //支持在线打开的方式 public void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception { File f = new File(filePath); if (!f.exists()) { response.sendError(404, "File not found!"); return; } BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0; response.reset(); // 非常重要 if (isOnLine) { // 在线打开方式 URL u = new URL("file:///" + filePath); response.setContentType(u.openConnection().getContentType()); response.setHeader("Content-Disposition", "inline; filename=" + f.getName()); // 文件名应该编码成UTF-8 } else { // 纯下载方式 response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + f.getName()); } OutputStream out = response.getOutputStream(); while ((len = br.read(buf)) > 0) out.write(buf, 0, len); br.close(); out.close(); } //下载项目文件直接传入文件路径的方法 public static void downloadLocal(String filePath, HttpServletResponse response) throws FileNotFoundException { // 下载本地文件 String fileName = "input.txt".toString(); // 文件的默认保存名 // 读到流中 InputStream inStream = new FileInputStream(filePath);// 文件的存放路径 // 设置输出的格式 response.reset(); response.setContentType("bin"); response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // 循环取出流中的数据 byte[] b = new byte[100]; int len; try { while ((len = inStream.read(b)) > 0) response.getOutputStream().write(b, 0, len); inStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
javaweb实现文件下载(包含.txt文件等默认在浏览器中打开的文件)
刚开始研究文件下载是找有关js的方法,找了好多发现对于.txt、.xls等文件在浏览器中还是打开,或者就是跨域问题。后来通过查找资料发现可以在后台对http相应头设置参数,而且实现起来也不复杂。现总结如下:
文章参考 《javaweb文件下载》、《根据网络url 实现web下载图片 java》、《Java文件下载及web文件的contentType大全》
前端代码:
function downloadLog(logName){
location.href=basePath + "/demp/common/downloadDeviceLog.do";
}
后台代码:
import org.apache.commons.io.IOUtils;
@RequestMapping({"/demp/common/downloadDeviceLog.do"})
@ResponseBody
public void downloadDeviceLog(HttpServletRequest request, HttpServletResponse response) throws Exception {
String logUrl = "https://**/2018-11-20.txt";
try {
String [] logUrlArray = logUrl.split("/");
String fileName = logUrlArray[logUrlArray.length-1];
URL url = new URL (logUrl);
URLConnection uc = url.openConnection();
response.setContentType("application/octet-stream");//设置文件类型
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.setHeader("Content-Length", String.valueOf(uc.getContentLength()));
ServletOutputStream out = response.getOutputStream();
IOUtils.copy(uc.getInputStream(), out);
} catch (Exception e) {
e.printStackTrace();
}
}
注:
1、其中关键的一句是给响应头设置“content-disposition”属性,关于它的介绍可参考文章《Content-Disposition 响应头,设置文件在浏览器打开还是下载》
2、contenType也可以设置成专门针对某种文件类型的,比如文中是.txt类型,就可以这样设置:
response.setContentType("text/plain");//设置文件类型
3、最近将代码放在两台服务器上(两台tomcat编码相同),一台正常,一台报Server returned HTTP response code: 400 for URL,报错的地方在 IOUtils.copy(uc.getInputStream(), out);后来发现代码引用的url里面含中文,去掉中文之后发现好了,但是还是不知道为什么两台服务器会出现不一样的情况,先贴出来,以后找到问题原因再补充。