http下载


import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;


@Slf4j
public class HttpDownloadUtil {

   public static void doDownload(HttpServletRequest request,
                          HttpServletResponse response, String originalName,
                          String fullFilePath,boolean isEncrypted) throws ServletException, IOException{
      doDownload(request,response,originalName,fullFilePath,null,isEncrypted);
   }
   public static void doDownload(HttpServletRequest request,
         HttpServletResponse response, String originalName,
         String fullFilePath,String contentType,boolean isEncrypted) throws IOException {

      File file = new File(fullFilePath);
      if (file.isDirectory() || !file.exists()) {
         //得到此次请求的发起路径,并重新回到此路径
 String url=request.getHeader("Referer");
         response.setCharacterEncoding("UTF-8");
         response.setContentType("text/html; charset=UTF-8");
         try{
            response.getWriter().write("<script>top.$.jBox.tip('文件已丢失或不存在!','error');location.href='"+url+"'</script>");
         } catch (IOException e) {
            e.printStackTrace();
            log.error("因文件已丢失或不存在导致打开文件失败时在返回出错信息时出现异常. ", e.getMessage());
            throw e;
         }
         return;
      }
      try {
         // 文件名
 String filename = originalName;

         // 清空缓存
 response.reset();
         //response.setHeader("Server", "www.xx.com");

 // 告诉客户端允许断点续传多线程连接下载
 // 响应的格式是如下:
 // Accept-Ranges: bytes
 response.setHeader("Accept-Ranges", "bytes");

         // 文件长度
 long mLength = 0;
         mLength = file.length();
         if (isEncrypted) {
            mLength -= 20;
         }

         // 请求文件的开始
 long start = 0;
         // 结束位置
 long end = mLength - 1;

         // 如果是第一次下,还没有断点续传,状态是默认的 200,无需设置
 // 响应的格式是: HTTP/1.1 200 OK
 if (request.getHeader("Range") != null) {
            // 客户端请求的下载的文件块的开始字节和结束
 // 如果是下载文件的范围而不是全部,向客户端声明支持并开始文件块下载
 // 要设置状态
 // 响应的格式是: HTTP/1.1 206 Partial Content
 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);// 206

 // 从请求中得到开始的字节
 // 请求的格式是:
 // Range: bytes=[文件块的开始字节]-
 String[] tokens = request.getHeader("Range")
                  .replaceAll("bytes=", "").split("-");
            start = Long.parseLong(tokens[0]);
            if (tokens.length > 1) {
               end = Long.parseLong(tokens[1]);
            }
         }

         // 下载的文件(或块)长度
 // 响应的格式是:
 // Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节]
 response.setHeader("Content-Length",
               new Long(end - start + 1).toString());

// if (start > 0) {
// // 不是从最开始下载,
// // 响应的格式是:
// // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
 response.setHeader("Content-Range", "bytes " + start + "-"
 + end + "/" + mLength);
// }
 if(contentType==null)
            response.setContentType("application/octet-stream");
         else
 response.setContentType(contentType);

         // 文件名用ISO08859_1编码
 response.setHeader("Content-Disposition", "attachment; filename=\""
 + URLEncoder.encode(filename ,StandardCharsets.UTF_8.name())+ "\"");

         // 输出流
 if(isEncrypted){
            FileEncryption.decryptStream(file, response.getOutputStream(),
                  start, end - start + 1, 20);
         }
         else {
            try (
                  BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                  BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())
            ) {
               byte[] buffer = new byte[102400];
               int readlength;
               while ((readlength = bis.read(buffer)) > 0) {
                  bos.write(buffer, 0, readlength);
                  bos.flush();
               }
            }
         }

      } catch (Exception ignored) {
         String url=request.getHeader("Referer");
         response.setCharacterEncoding("UTF-8");
         response.setContentType("text/html; charset=UTF-8");
         response.getWriter().write("<script>top.$.jBox.tip('打开文件异常!','error');location.href='"+url+"'</script>");
         throw ignored;
      }
   }

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值