下载文件 vue +springboot

vue前端

// 下载
    download (item) {
      this.loadFlag = true
 //outputFile是后端接口,接收来自response的数据
      outputFile(item.entityId, encodeURIComponent(item.attPath)).then(response => {
        this.loadFlag = false
        const content = response.data
        const blob = new Blob([content])
        const fileName = item.attName
        if ('download' in document.createElement('a')) { // 非IE下载
          const elink = document.createElement('a')
          elink.download = fileName
          elink.style.display = 'none'
          elink.href = URL.createObjectURL(blob)
          document.body.appendChild(elink)
          elink.click()
          URL.revokeObjectURL(elink.href) // 释放URL 对象
          document.body.removeChild(elink)
        } else { // IE10+下载
          navigator.msSaveBlob(blob, fileName)
        }
      })
    }

后端接口

方案一

/**
	 * 回显图片信息
	 *
	 * @param path
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@GetMapping("/outputFile")
	public void outputFile(@RequestParam(value = "entityId", required = false) String entityId,
			@RequestParam(value = "path", required = false) String path,
			@RequestParam(value = "att", required = false) Double att,
						   HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		String QUOTATION = "\"";
		String CLENGTH = "Content-Length";
		String CDISPOSITION = "Content-Disposition";
		String HEADNAME = "attachment;filename=";
		String CONETNTTYPE = "application/octet-stream";
		// 查询文件路径
		NewsAttEntity attEntity = newsAttService.selectByPath(entityId, path, att);
		// 读取文件
		File file = new File(attEntity.getAttPath());

		response.setStatus(HttpServletResponse.SC_OK);
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Disposition", "attachment;filename=" +  java.net.URLEncoder.encode(attEntity.getAttName(), "UTF-8"));
        response.addHeader("Content-Length", "" + file.length());
		try (BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
			 OutputStream out = response.getOutputStream();
		) {
			byte[] buffBytes = new byte[1024];
			int read = 0;
			while ((read = input.read(buffBytes)) != -1) {
				out.write(buffBytes, 0, read);
			}
			out.flush();
		} catch (Exception e) {
			logger.error("文件处理异常:", e);
		}

	}

方案二

@GetMapping(value = "/outputFile")
	public void outputFile(@RequestParam(value = "entityId", required = false) String enatityId,
			@RequestParam(value = "businessType", required = false) String businessType,
			@RequestParam(value = "path", required = false) String path, HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		// 查询文件路径
		HrFileAttachmentEntity fileAttachment = hrFileAttachmentService.selectByPath(enatityId, businessType, path);

		if (fileAttachment == null){
			return;
		}
		// 读取文件
		File file = new File(fileAttachment.getPath());

		FileUtil.downloadSupport(request,response,fileAttachment.getName());
		FileUtil.rangeSupport(request,response,file);
	}

FileUtil




import com.foresealife.iam.client.bean.IamUserInfo;
import org.apache.commons.lang.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Servlet请求/下载文件资源的工具类
 */
public class FileUtil {
    /**
     * controller提供下载文件的方法,解决中文文件名乱码
     *
     * @param request
     * @param response
     * @param formFileName
     * @throws IOException
     */
    public static void downloadSupport(HttpServletRequest request, HttpServletResponse response, String formFileName) throws IOException {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent != null && (userAgent.contains("MSIE") || userAgent.contains("Trident"))) {
            // 针对IE或者以IE为内核的浏览器:
            formFileName = java.net.URLEncoder.encode(formFileName, "UTF-8");
        } else {
            // 非IE浏览器的处理:
            formFileName = new String(formFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", formFileName));
        response.setCharacterEncoding("UTF-8");
    }


    public static boolean cacheSupport(HttpServletRequest request, HttpServletResponse response, File file) throws IOException{
        response.setHeader("Cache-control", "public, max-age=31536000");
        long reqTime = request.getDateHeader("If-Modified-Since");
        long fileTime = file.lastModified();
        try {
            response.setContentType(Files.probeContentType(Paths.get(file.getPath())));
        } catch (IOException e) {
            //ignore this exception.
        }
        if (reqTime > 0 && Math.abs(reqTime - fileTime) < 1000) {
            //如果文件没有修改,则直接返回304,不会读文件 也不会产生流,可提高访问速度
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return  true;
        }
        response.setDateHeader("Last-Modified", fileTime);
        return false;
    }

    /**
     * 限制接口只能通过localhost访问
     * @param request
     * @return
     */
    public static boolean isLocalhost(HttpServletRequest request){
        String remoteAddress = request.getRemoteAddr();
        if(remoteAddress != null && remoteAddress.indexOf(':') != -1){
            //ipv6访问
            return "0:0:0:0:0:0:0:1".equals(remoteAddress);
        }
        return "localhost".equals(remoteAddress) || "127.0.0.1".equals(remoteAddress);
    }



    public static void viewSupport(HttpServletRequest request, HttpServletResponse response, String formFileName) throws IOException {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent != null && (userAgent.contains("MSIE") || userAgent.contains("Trident"))) {
            // 针对IE或者以IE为内核的浏览器:
            formFileName = java.net.URLEncoder.encode(formFileName, "UTF-8");
        } else {
            // 非IE浏览器的处理:
            formFileName = new String(formFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        response.setHeader("Content-Disposition", String.format("inline; filename=\"%s\"", formFileName));
        response.setCharacterEncoding("UTF-8");
    }

    public static void rangeSupport(HttpServletRequest request, HttpServletResponse response, File file) throws IOException {
        ServletOutputStream os = null;
        BufferedOutputStream out = null;
        byte[] b = new byte[1024];
        try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
            long pos = headerSetting(request, response, file);
            os = response.getOutputStream();
            out = new BufferedOutputStream(os);
            raf.seek(pos);
            int n = 0;
            while ((n = raf.read(b, 0, 1024)) != -1) {
                out.write(b, 0, n);
            }
            out.flush();
        }

    }

    private static long headerSetting(HttpServletRequest request, HttpServletResponse response,
                                      File file) throws IOException {
        long len = file.length();
        response.setHeader("Accept-Ranges", "bytes");
        String strRange = request.getHeader("Range");
        if (strRange == null || strRange.isEmpty()) {
            setResponse(new RangeSettings(len), response);
            return 0;
        }
        String range = strRange.replace("bytes=", "");
        RangeSettings settings = getSettings(len, range);
        setResponse(settings, response);
        return settings.getStart();
    }

    private static void setResponse(RangeSettings settings, HttpServletResponse response) {
        if (!settings.isRange()) {
            response.addHeader("Content-Length", String.valueOf(settings.getTotalLength()));
        } else {
            long start = settings.getStart();
            long end = settings.getEnd();
            long contentLength = settings.getContentLength();
            response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
            response.addHeader("Content-Length", String.valueOf(contentLength));
            String contentRange = "bytes " + start + "-" + end + "/" + settings.getTotalLength();
            response.setHeader("Content-Range", contentRange);
        }
    }

    private static RangeSettings getSettings(long len, String range) {
        long contentLength = 0;
        long start = 0;
        long end = 0;
        if (range.startsWith("-"))
        // -500,最后500个
        {
            contentLength = Long.parseLong(range.substring(1));
            //要下载的量
            end = len - 1;
            start = len - contentLength;
        } else if (range.endsWith("-"))
        //从哪个开始
        {
            start = Long.parseLong(range.replace("-", ""));
            end = len - 1;
            contentLength = len - start;
        } else
        //从a到b
        {
            String[] se = range.split("-");
            start = Long.parseLong(se[0]);
            end = Long.parseLong(se[1]);
            contentLength = end - start + 1;
        }
        return new RangeSettings(start, end, contentLength, len);
    }

    /**
     * 获取IP地址
     *
     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            return null;
        }

//        //使用代理,则获取第一个IP地址
//        if(StringUtils.isEmpty(ip) && ip.length() > 15) {
//			if(ip.indexOf(",") > 0) {
//				ip = ip.substring(0, ip.indexOf(","));
//			}
//		}

        return ip;
    }
}
RangeSettings


import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
class RangeSettings{
    private long start;
    private long end;
    private long contentLength;
    private long totalLength;
    private boolean range;
    public RangeSettings(){
        super();
    }
    public RangeSettings(long start, long end, long contentLength,long totalLength) {
        this.start = start;
        this.end = end;
        this.contentLength = contentLength;
        this.totalLength = totalLength;
        this.range = true;
    }
    public RangeSettings(long totalLength) {
        this.totalLength = totalLength;
    }

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值