上传
使用Servlet完成上传和下载相较于使用Struts框架有点麻烦,毕竟更偏底层了
项目中主要使用的jar包:
commons-io-2.2.jar commons-fileupload-1.3.2.jar
其他使用的jar有:
commons-beanutils-1.8.3.jar commons-logging-1.1.1.jar itcast-tools-1.4.2.jar
页面:
值得注意的是:form要使用post提交,并使用enctype,这和使用Struts的页面要求是一致的
上传文件四步骤
1.创建工厂(DiskFileItemFactory) 2.根据工厂创建解析器(ServletFileUpload) 3.解析request,得到FileItem集合 4.遍历FileItem,调用其API完成操作我将文件保存在WEB-INF中,这样的话通过浏览器是直接访问不到这个资源的,在WEB-INF中还使用了根据文件名的哈希名称前两个首字母生成目录来存放,对了,这个文件名还用了UUID值+_+文件名的方式避免同名问题,对于部分浏览器可能出现据对路径的问题也进行了处理
import java.io.File;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import cn.itcast.commons.CommonUtils;public class UploadServlet3 extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { //前三步 //DiskFileItemFactory factory=new DiskFileItemFactory(); //可以使用临时目录(d:/temp需先创建)和设置缓存大小(20kb) DiskFileItemFactory factory=new DiskFileItemFactory(20*1024,new File("d:/temp")); ServletFileUpload fileUpload=new ServletFileUpload(factory); Listlist = fileUpload.parseRequest(req); FileItem fi1 = list.get(1); //得到文件保存的路径(files目录需创建) String root = this.getServletContext().getRealPath("/WEB-INF/files/"); //处理绝对路径问题 String fileName=fi1.getName(); int index=fileName.lastIndexOf("//"); if(index!=-1){ fileName=fileName.substring(index+1); } //处理重名问题 String saveFileName=CommonUtils.uuid()+"_"+fileName; //目录打散 //1.获得文件名的哈希值并转换为十六进制 int hashCode = fileName.hashCode(); String hex = Integer.toHexString(hashCode); //2.获得十六进制的前两位,生成目录链 File dirFile=new File(root,hex.charAt(0)+"/"+hex.charAt(1)); dirFile.mkdirs(); //3.创建文件并保存 File desFile=new File(dirFile,saveFileName); fi1.write(desFile); } catch (Exception e) { e.printStackTrace(); } }}
这里使用了CommonUtils类来生成UUID值,这个类是在itcast-tools-1.4.2.jar(传智播客提供)
下载
下载所使用的jar包是:commons-io-2.2.jar
import java.io.FileInputStream;import java.io.IOException;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.io.IOUtils;import sun.misc.BASE64Encoder;public class DownloadServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 文件下载,两个头一个流 * 响应头1:Content-Type * 响应头2:Content-Disposition * 流:下载文件数据 */ String fileName="e:/IBelieve.mp3"; //文件所在位置 String frameName=filenameEncoding("%IBelieve%.mp3", req); //下载时显示的文件名 String contentType=this.getServletContext() .getMimeType(fileName); //通过文件名得到MIME类型 String contentDisposition="attachment;filename="+frameName; //一个流 FileInputStream inputStream=new FileInputStream(fileName); //设置头 resp.setHeader("Content-Type", contentType); resp.setHeader("Content-Disposition", contentDisposition); //获取绑定了响应端的流 ServletOutputStream outputStream=resp.getOutputStream(); IOUtils.copy(inputStream, outputStream); //将输入流的数据写到输出流 inputStream.close(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } //用来对下载文件名进行编码 public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException { String agent = request.getHeader("User-Agent"); //获取浏览器 if (agent.contains("Firefox")) { BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else if(agent.contains("MSIE")) { filename = URLEncoder.encode(filename, "utf-8"); } else { filename = URLEncoder.encode(filename, "utf-8"); } return filename; }}
filenameEncoding()方法可以根据浏览器的不同对下载的文件名进行编码,避免乱码