文件下载的实现:

下载方式:

一.超链接下载


<a href="/项目名/download/测试.txt">下载 day10.txt</a>


若浏览器能解析该资源的mime类型,则在网页打开显示文件;若不能接下则下载;




二.编码下载 

1.通过servlet完成时:


<a href="/day10/download?name=day10.txt">     //访问DownloadServlet下载 day10.txt文件



a.设置传输文件的mime类型


String mimeType=servletContext.getMimeType(文件名) 

response.setContentType(mimeType);





b.设置下载头信息 content-disposition


response.setHeader("content-disposition", "attachment;filename="+文件名称);


注意:为了避免文件名称下载时中文显示不出来,需要按照浏览器对对文件名称进行编码


public static String getName(String agent, String filename) throws UnsupportedEncodingException { 

if (agent.contains("MSIE")) { 

// IE浏览器 

filename = URLEncoder.encode(filename, "utf-8"); 

filename = filename.replace("+", " "); 

} else if (agent.contains("Firefox")) { 

// 火狐浏览器 

BASE64Encoder base64Encoder = new BASE64Encoder(); 

filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; 

} else { 

// 其它浏览器 

filename = URLEncoder.encode(filename, "utf-8"); 

} 

return filename; 

} 

 

c.提供流 

response.getOutputStream();   

 

文件传输时:使用commons-io工具类 

对拷流: 

IOUtils.copy(is,os);











代码示例:


//获取下载文件的名称 

String filename = request.getParameter("name"); 

 

//注意中文乱码: 

filename=new String(filename.getBytes("iso8859-1"),"utf-8"); 

 

ServletContext context = this.getServletContext(); 

//文件下载 

//1.设置文件的mimeType 

String mimeType = context.getMimeType(filename); 

response.setContentType(mimeType); 

 

//2.设置下载的头信息 

//方式1:常见的浏览器将文件名称使用utf-8 但不兼容火狐 不推荐  

//response.setHeader("content-disposition", "attchment;filename="+URLEncoder.encode(filename, "utf-8")); 

//方式2:网络上的方式 (8成好使) 

//response.setHeader("content-disposition", "attachment;filename="+new String(filename.getBytes("gbk"),"iso8859-1")); 

 

//方式1:通过的方式 通过工具类编码 

String _filename=DownLoadUtils.getName(request.getHeader("user-agent"), filename); 

response.setHeader("content-disposition", "attachment;filename="+_filename); 

 

 

//3.对拷流 

//获取输入流 

InputStream is = context.getResourceAsStream("/download/"+filename); 

 

//获取输出流 

ServletOutputStream os = response.getOutputStream(); 

 

IOUtils.copy(is, os); 

 

os.close(); 

is.close();









文件上传实现:

    1.最原始的方法:使用Web 3.0时,自己去解析表单上传的内容
  


使用步骤:


浏览器端的要求:


表单的提交方式必须是post


表单必须有文件上传组件<imput type="file" name="uploadFile">


表单设置 enctype属性,属性值为 multipart/form-data




服务器获取的时候:


servlet3.0要求


在接收参数的Servlet上添加一个@MultipartConfig


获取普通的组件  


request.getParameter(name属性的值)


获取文件上传组件


Part part=request.getPart("uploadFile")  :上传组件name属性的值




//获取文件的名称,自处理截取才能获取文件名称 

Stirng sss=part.getHeader("content-disposition") 

sss.substring(sss.indexof("filename=")+10,sss.length-1); 

 

//获取上传文件对应的输入流 

part.getInputStream(); 

 

//删除临时文件 

part.delete()





上传时候需要注意的问题:


文件重名 随机名称


文件安全 重要的文件放在 web-inf meta-inf  服务器磁盘


目录分离


时间


用户


文件个数


随机目录








2.自己使用Apache组织提供的 commons-fileupload工具类进行表单内容解析


使用步骤:


浏览器端的要求:


表单的提交方式必须是post


表单必须有文件上传组件<imput type="file" name="uploadFile">


表单设置 enctype属性,属性值为 multipart/form-data






服务器获取的时候:


//创建一个磁盘文件项工厂 

1.DiskFileItemFactory factory = new DiskFileItemFactory(); 

 

//创建一个核心文件上传对象 ServletFileUpLoad 

2.ServletFileUpload upload = new ServletFileUpload(factory); 

 

//使用上传对象调用方法去解析请求,获取一个List<FileItem> 

3.List<FileItem> list = upload.parseRequest(request); 

 

//遍历list获取每一个文件项 

isFormFiled():判断是否是普通上传组件 

true:普通上传组件 

false:文件上传组件 

getFiledName():获取表单子标签的name属性值 

 

//若是普通的上传组件 

getString("utf-8"):获取用户输入的值 

 

//若是文件上传组件 

getName():获取上传文件的名称 

getInputStream():获取上传文件流 

 

//最后删除临时文件 

delete() 

 

   参考代码: 

//0.创建map 放入前台传递的数据 

HashMap<String, Object> map = new HashMap<>(); 

 

//创建磁盘文件项 

DiskFileItemFactory factory = new DiskFileItemFactory(); 

//创建核心上传对象 

ServletFileUpload upload = new ServletFileUpload(factory); 

//解析request 

List<FileItem> list = upload.parseRequest(request); 

//遍历集合 

for (FileItem fi : list) { 

//判断是否是普通的上传组件 

if(fi.isFormField()){ 

//普通上传组件 

map.put(fi.getFieldName(),fi.getString("utf-8")); 

}else{ 

//文件上传组件 

//获取文件名称 

String name = fi.getName(); 

 

//获取文件的真实名称    xxxx.xx 

String realName = UploadUtils.getRealName(name); 

//获取文件的随机名称 

String uuidName = UploadUtils.getUUIDName(realName); 

 

//获取文件的存放路径 

String path = this.getServletContext().getRealPath("/products/1"); 

 

//获取文件流 

InputStream is = fi.getInputStream(); 

//保存图片 

FileOutputStream os = new FileOutputStream(new File(path, uuidName)); 

 

IOUtils.copy(is, os); 

os.close(); 

is.close(); 

 

//删除临时文件 

fi.delete(); 

 

//在map中设置文件的路径 

map.put(fi.getFieldName(), "products/1/"+uuidName); 

 

} 

}









3.使用Struts 实现(Struts2框架的使用拦截器完成了文件上传,已近使用Apache的commons-fileupload完成了解析)


使用步骤:


浏览器端的要求:


客户端表单的三个注意事项


1. method="post" 

2. enctype="multipart/form-data" 

3. <input type="file" name="myfile">







服务器获取的时候:


fileUpload拦截器 默认在 defaultStack 栈中, 默认会执行的 




在Action中编写文件上传,需要定义三个属性(使用属性注入让Struts2注入,提供set方法)


> 文件-类型File ,

属性名:与表单中文件组件的name属性名一致.


> 文件类型-类型String , 属性名:前段是name属性名一致 + ContentType;


> 文件名-类型String ,

属性名:前段是name属性名一致+FileName;




> 可以通过FileUtils提供 copyFile 进行文件复制,将上传文件 保存到服务器端






文件上传中存在的问题:


   1.先配置input逻辑视图处理错误信息,拦截器在发现错误时默认会跳转的对应input的界面




2.文件上传的总大小默认值是2M,如果超过了2M,程序会报出异常。可以使用<s:actionError>来查看具体信息!


> 解决总大小的设置,找到常量:


* struts.multipart.parser=jakarta 
-- 默认文件上传解析器,就是FileUpload组件 

* struts.multipart.saveDir= 
-- 文件上传的临时文件存储目录 

* struts.multipart.maxSize=2097152 
-- 文件上传的最大值(总大小),默认是2M 

 

> 可以在struts.xml中设置常量,修改文件上传的默认总大小!!! 

* <constant name="struts.multipart.maxSize" value="5000000"></constant>





3.还可以通过配置拦截器来设置文件上传的一些属性


 先在<action>标签中引入文件上传的拦截器


<interceptor-ref name="defaultStack"> 

<!-- 设置单个上传文件的大小 --> 

<param name="fileUpload.maximumSize">2097152</param> 

<!-- 设置扩展名 --> 

<param name="fileUpload.allowedExtensions">.txt</param> 

</interceptor-ref>