前言
Web程序中,文件的上传与下载很是常见,就比如CSDN插入图片的功能,就是典型的文件上传功能,接下来来看下这个功能是怎么实现的。
文件上传
从前台开始,首先,JSP中要引用几个相关的js文件,如jquery.js和ajaxfileupload.js,引用完这两个基础的js之后,我们就可以开始写jsp的内容,jsp简单来说,主要的就是一个点:
<input type="file" name="file" id="ceshi" class="files_upload">浏览文件</input>
其中,type=file就是定义了这是一个选择文件的窗口。Id唯一标识了一个文件域。
保存按钮:
<input id="upload" type="button" οnclick="upload()" value="保存"/>
保存按钮对应的upload方法:
function upload() {
ajax_upload (null,' /upload.do','ceshi');//使用ajax上传文件
}
function ajax_upload(tsAlert, url, feid) { // 具体上传文件的方法
$.ajaxFileUpload({
fileElementId : feid, // 需要上传的文件域的ID,即<input type="file">的ID。
url : url, // 后台方法的路径
type : 'post', // 当要提交自定义参数时,这个参数要设置成post
dataType : 'json', // 服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
secureuri : false, // 是否启用安全提交,默认为false。
async : true, // 是否是异步
success : function(data, status) { //参数data就是服务器返回的数据。
//上传成功后执行的函数
},
error : function(data, status, e) {
//上传失败后执行的函数
}
});
}
前台需要的东西已经准备就绪,现在开始写url后台方法路径里的方法:
@RequestMapping("/upload")
@ResponseBody
public void upload(@RequestParam("file") CommonsMultipartFile file){
try {
if (null != file) {
String filePath =”E:/ceshi”; // 文件上传路径
String filename = file.getOriginalFilename();//获取文件名(带后缀)
File realfFile = new File(filePath, filename);
if (!realfFile.exists()) {
if (!realfFile.getParentFile().exists()) {
realfFile.getParentFile().mkdirs();
}
realfFile.createNewFile();
}
FileUtils.copyInputStreamToFile(file.getInputStream(), realfFile);
}
} catch (Exception e) {}
return file_;
}
这段代码的大致意思就是将web端传过来的文件转换成流,然后在相应文件夹中创建相同名称的文件,再将文件流输入到文件中。
文件下载
文件的下载也很常见,比如CSDN有使用积分下载文档啊,jar包啊之类的功能,那么这个功能又是怎么实现的呢。
文件下载不需要前端,它的的大概意思就是将服务器文件转换成流推送到浏览器,然后浏览器有相应的下载功能。看代码:
@RequestMapping("/down")
public void down(HttpServletRequest request, HttpServletResponse response) {
String filePath = “E:/ceshi” + “/” + “文件名.后缀”;
byte[] tmpByte = fileToByte(filePath);
File file = new File(“文件名.后缀”);//这里不需要加路径,这个文件最后会删除
try {//把byte数组写入到一个文件中
OutputStream ou = new FileOutputStream(file);
ou.write(tmpByte);
ou.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//读取要下载的文件,保存到文件输入流
FileInputStream in;
//创建输出流
OutputStream out;
try {
//设置响应头,控制浏览器下载该文件
response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(file.getName(), "UTF-8"));
in = new FileInputStream(file.getAbsolutePath());
//创建输出流
out = response.getOutputStream();
//创建缓冲区
byte buffer[] = new byte[1024];
int len = 0;
//循环将输入流中的内容读取到缓冲区当中
while ((len = in.read(buffer)) > 0) {
//输出缓冲区的内容到浏览器,实现文件下载
out.write(buffer, 0, len);
}
//关闭文件输入流
in.close();
//关闭输出流
out.close();
file.delete();//删除临时生成的文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//工具类,将File文件转换成流
private static byte[] fileToByte (String filePath)
{
byte[] buffer = null;
try
{
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1)
{
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return buffer;
}
如果想下载的话,直接网页访问:
服务器地址:端口/down.do
即可。
总结
文件上传与下载都是通过二进制流的形式进行的,这些在代码中也有体现。