文件的下载一直都是web项目中的常用功能,但是在我们公司项目中,项目上线后单下载功能方面都可以简单易懂的说分为三个部分,即文件服务器、应用服务器和客户端,而我们在上传的时候都是将上传保存到文件服务器(也可以俗称网络服务器),而在数据库中存储的只是文件在文件服务器上的地址,类似于“http://182.168.1.1/group1/M00/00/73/wKgBDVoGbFWACZ_HAlZxO4o_Y24986.doc”这样的字段,在下载的时候只是获取到了数据库中存储的地址信息,然后到文件服务器上去找,然后下载。
网上大多的下载方法都是采用servlet方法下载,而我说的这种下载方式可能和网上多数下载方法不同(也或许是我没有发现更多类似的吧^_^),当时在我做的时候碰到了很多问题,也都在网上找了很多的下载方法,但都是从文件服务器下载到应用服务器,客户端网页并没有提示文件下载保存等信息,也有很多是从应用服务器下载到客户端,但是一般都是不把文件上传保存到应用服务器的项目里面的,因为对造成项目过于庞大,也会增加应用服务器的负荷,所以在这里我总结一下我的下载方法,
整个下载过程是这样的:
从文件服务器拿到文件---下载到应用服务器---最后再下载到客户端
我的方法代码如下:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xk.util.PropertyUtil;
@Controller
@RequestMapping(value = "/DownloadServlet", produces = "text/html;charset=utf-8")
public class DownloadController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* 获取服务器上的文件下载到客户端
* @param filePath
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
@RequestMapping(value = "/Download.do")
protected @ResponseBody void doGet(String filePath,HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String file_path = PropertyUtil.getProperty("file_path");
File savePath = new File(file_path+date);
if (!savePath.exists()) {
savePath.mkdir();
}
String[] urlname = filePath.split("/");
int len = urlname.length-1;
String uname = urlname[len];
try {
File file = new File(savePath+"/"+uname);
if(file!=null && !file.exists()){
file.createNewFile();
}
OutputStream oputstream = new FileOutputStream(file);
URL url = new URL(filePath);
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
uc.setDoInput(true);
uc.connect();
InputStream iputstream = uc.getInputStream();
byte[] buffer = new byte[4*1024];
int byteRead = -1;
while((byteRead=(iputstream.read(buffer)))!= -1){
oputstream.write(buffer, 0, byteRead);
}
// 取得文件的后缀名。
String ext = uname.substring(uname.lastIndexOf(".") + 1).toUpperCase();
oputstream.flush();
iputstream.close();
oputstream.close();
InputStream inStream = new FileInputStream(savePath+"/"+uname);
InputStream fis = new BufferedInputStream(new FileInputStream(file));
byte[] buffer2 = new byte[fis.available()];
fis.read(buffer2);
fis.close();
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + new String(uname.getBytes()));
response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
byte[] b = new byte[100];
int len1;
while ((len1 = inStream.read(b)) > 0)
response.getOutputStream().write(b, 0, len1);
inStream.close();
toClient.write(buffer);
toClient.flush();
toClient.close();
file.delete();
savePath.delete();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
可能新手们会问一个问题,那就是文件从文件服务器下载到应用服务器上保存在什么地方?
String file_path = PropertyUtil.getProperty("file_path");
这个就是我获取到的配置文件中的在应用服务器上文件要保存的地址,当然,这里我还生成了一个date作为文件夹,但是后来还是觉得会增加应用服务器的负荷,所以后来又经过改进,增加了文件删除方法,在文件下载到客户端后,对应用服务器上的文件进行删除操作。即
savePath.delete();
前台调用下载方法的时候,需要传一个参数,那就是filePath,也就是从数据库获取到的下载地址。
其实这里还有一个待改进的地方,就是下载后的文件的文件名是服务器生成的,所以如果大家有高标准要求还可以从数据库获取更多的信息,对下载文件进行操作。
这里进行一下更多的解释(当然都是为了能帮助更多的新手,我相信更多的程序员是能看的懂代码的,新手们加油哟!)
oputstream.flush();
iputstream.close();
oputstream.close();
代码中上面这些关闭流之前的,都是从文件服务器下载到应用服务器的,后面的才是从应用服务器下载到客户端的。
切记:
记得关闭流!!!
新手在这里献丑啦!希望大家取得更多的进步!!