源码:http://download.csdn.net/download/u013160017/9996400
package com.goldmsg.download.controller;
import com.goldmsg.download.base.ReturnInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* Created by zhouhaiming on 2017-9-26 11:57
* Email: dg_chow@163.com
*
* @Description:
*/
@Controller
@RequestMapping("/")
public class Download {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/hello")
String home() {
return "Hello World!";
}
@RequestMapping("/download")
public Object downloadFileByPath(HttpServletRequest request, HttpServletResponse response) {
try {
downloadFile("E:\\共享文件夹\\Oracle 10g_x64_setup.zip", request, response);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return ReturnInfo.genSucceedEvent("测试成功!");
}
/**
* 执行下载动作
*
* @param srcFileName 绝对路径,指向服务器上某个已存在的文件
* @return
* @throws UnsupportedEncodingException
*/
private Object downloadFile(String srcFileName, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String filepath = srcFileName;
FileInputStream inputFileStream = null;
OutputStream outputStream = null;
try {
File file = new File(filepath);
if (file.exists()) {
long point = 0;
long fileLength = file.length();
long position_end = fileLength;
inputFileStream = new FileInputStream(file);
outputStream = response.getOutputStream();
response.reset();
//设置支持断点
response.setHeader("Accept-Ranges", "bytes");
//获取断点位置
String Range = request.getHeader("Range");
if (Range != null) {
response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
String RangeFromTo = Range.replaceAll("bytes=", "");
logger.info("threadName: " + Thread.currentThread().getId() + " Range : " + RangeFromTo);
String[] Ranges = RangeFromTo.split("-");
point = Long.parseLong(Ranges[0]);
if (Ranges.length == 2 && !Ranges[1].equals("")) {
position_end = Long.parseLong(Ranges[1]);
}
}
//写明要下载的文件的大小
response.setHeader("Content-Length", new Long(position_end - point).toString());
logger.info("threadName: " + Thread.currentThread().getId() + "point : " + point + " Content-Length : " + new Long(position_end - point).toString());
//设置response的编码方式
response.setContentType("application/x-msdownload");
//设置断点续传回应头
String contentRange = new StringBuffer("bytes ")
.append(new Long(point).toString())
.append("-")
.append(new Long(fileLength - 1).toString())
.append("/")
.append(new Long(fileLength).toString())
.toString();
if (point != 0) {
// 断点续传的回应头:告诉改块插入的位置和文件的总大小
// 格式:Content-Range: bytes [文件块的开始字节]-[文件块的结束字节 - 1]/[文件的总大小]
contentRange = new StringBuffer("bytes ")
.append(new Long(point).toString())
.append("-")
.append(new Long(position_end - 1).toString())//
.append("/")
.append(new Long(fileLength).toString())
.toString();
// 移动文件指针位置,断点处
inputFileStream.skip(point);
}
response.setHeader("Content-Range", contentRange);
//设置附加文件名(解决中文乱码)
String downloadname = file.getName();
response.setHeader("Content-Disposition", "attachment;filename=" + new String(downloadname.getBytes("gbk"), "iso-8859-1"));
long bytesWritten = 0;
byte[] bytes = new byte[1024 * 4];
int byteCount = 0;
long NeedWriten = position_end - point + 1;
while (NeedWriten >= bytesWritten && (byteCount = inputFileStream.read(bytes)) != -1) {
if (NeedWriten >= bytesWritten) {
long tTempWriten = (bytesWritten + byteCount) > NeedWriten ? (NeedWriten - bytesWritten) : byteCount;
outputStream.write(bytes, 0, (int) tTempWriten);
bytesWritten += tTempWriten;
}
}
} else {
logger.error("下载文件失败:" + filepath + " and authcode: 文件不存在");
setHttpResposeCode(response, response.SC_NOT_FOUND, "download file failed :" + filepath + " : file not exist");
return ReturnInfo.genFileNotExistError(srcFileName);
}
} catch (FileNotFoundException e) {
logger.error("下载文件失败:" + filepath + " FileNotFoundException happen : " + e + " URL : " + request.getRequestURL().toString());
setHttpResposeCode(response, response.SC_NOT_FOUND, "download file failed FileNotFoundException happen : " + e + " filepath :" + filepath + " : file not exist");
return ReturnInfo.genFileNotExistError(srcFileName);
} catch (IOException e) {
logger.error("下载文件失败:" + filepath + " IOException hapepn : " + e + " URL : " + request.getRequestURL().toString());
setHttpResposeCode(response, response.SC_INTERNAL_SERVER_ERROR, "download file failed IOException happen : " + e);
return ReturnInfo.genInternalsErrorEvent("下载失败");
} finally {
try {
if (null != inputFileStream) {
inputFileStream.close();
}
if (null != outputStream) {
outputStream.close();
}
} catch (IOException e) {
logger.error("下载文件失败:" + filepath + " EofException happen : " + e);
}
}
logger.info("下载文件成功:" + filepath);
return ReturnInfo.genSucceedEvent("正在下载");
}
/**
* 设置http 返回码
*
* @param code
* @param msg
**/
private void setHttpResposeCode(HttpServletResponse response, int code, String msg) {
try {
response.reset();
response.setCharacterEncoding("UTF-8"); //设置字符编码格式
response.setContentType("text/html; charset=UTF-8"); //设置输出编码格式
response.sendError(code, new String(msg.getBytes(), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
logger.error("FileDownLoad setHttpResposeCode IOException happen : " + e);
}
}
}
package com.goldmsg.download.base;
/**
* Created by zhouhaiming on 2017-9-26 15:50
* Email: dg_chow@163.com
*
* @Description:
*/
import java.util.HashMap;
import java.util.Map;
public class ReturnInfo {
public static Map genFileNotExistError(Object msg){
Map map = new HashMap();
map.put("error", 3003);
map.put("msg", msg + "资源不存在");
return map;
}
public static Map genInternalsErrorEvent(String msg){
Map map = new HashMap();
map.put("error", 3004);
map.put("msg", msg);
return map;
}
public static Map genSucceedEvent(Object msg){
Map map = new HashMap();
map.put("error", 0);
map.put("msg", msg);
return map;
}
}