使用jsp/servlet简单实现文件上传与下载

来源:互联网 发布:软件项目组织结构图 编辑:程序博客网 时间:2024/06/05 04:40

使用JSP/Servlet简单实现文件上传与下载

   通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马。好了,下面来简单了解如何通过使用jsp与servlet实现文件上传与下载。
       在写代码之前,我们需要导入两个额外的jar包,一个是common-io-2.2.jar,另一个是commons-fileupload-1.3.1.jar,将这个两个jar 包导入WEB-INF/lib目录里。
       首先,想要在web端即网页上实现文件上传,必须要提供一个选择文件的框,即设置一个<input type="file"/>的元素,光有这个还不行,还需要对<input>元素外的表单form进行设置,将form的enctype属性设置为“multipart/form-data”,即<form action="" method="post" enctype="multipart/form-data">,当然请求方式也必须是post。让我们来简单做一个上传的jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>文件上传</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>    <form action="${pageContext.request.contextPath}/servlet/UploadServlet" method="post" enctype="multipart/form-data">    name:<input name="name"/><br/>    file1:<input type="file" name="f1"/><br/>        <input type="submit" value="上传">    </form>  </body></html>
       jsp页面做好之后,我们就要写一个UploadServlet,在编写上传servlet时,我们需要考虑到如果上传的文件出现重名的情况,以及上传的文件可能会出现的乱码情况,所以我们需要编码与客户端一致,并且根据文件名的hashcode计算存储目录,避免一个文件夹中的文件过多,当然为了保证服务器的安全,我们将存放文件的目录放在用户直接访问不到的地方,比如在WEB-INF文件夹下创建一个file文件夹。具体做法如下:
public class UploadServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();System.out.print(request.getRemoteAddr());boolean isMultipart = ServletFileUpload.isMultipartContent(request);if(!isMultipart){throw new RuntimeException("请检查您的表单的enctype属性,确定是multipart/form-data");}DiskFileItemFactory dfif = new DiskFileItemFactory();ServletFileUpload parser = new ServletFileUpload(dfif);parser.setFileSizeMax(3*1024*1024);//设置单个文件上传的大小parser.setSizeMax(6*1024*1024);//多文件上传时总大小限制List<FileItem> items = null;try {items = parser.parseRequest(request);}catch(FileUploadBase.FileSizeLimitExceededException e) {out.write("上传文件超出了3M");return;}catch(FileUploadBase.SizeLimitExceededException e){out.write("总文件超出了6M");return;}catch (FileUploadException e) {e.printStackTrace();throw new RuntimeException("解析上传内容失败,请重新试一下");}//处理请求内容if(items!=null){for(FileItem item:items){if(item.isFormField()){processFormField(item);}else{processUploadField(item);}}}out.write("上传成功!");}private void processUploadField(FileItem item) {try {String fileName = item.getName();//用户没有选择上传文件时if(fileName!=null&&!fileName.equals("")){fileName = UUID.randomUUID().toString()+"_"+FilenameUtils.getName(fileName);//扩展名String extension = FilenameUtils.getExtension(fileName);//MIME类型String contentType = item.getContentType();//分目录存储:日期解决//Date now = new Date();//DateFormat df = new SimpleDateFormat("yyyy-MM-dd");////String childDirectory  = df.format(now);//按照文件名的hashCode计算存储目录String childDirectory = makeChildDirectory(getServletContext().getRealPath("/WEB-INF/files/"),fileName);String storeDirectoryPath = getServletContext().getRealPath("/WEB-INF/files/"+childDirectory);File storeDirectory = new File(storeDirectoryPath);if(!storeDirectory.exists()){storeDirectory.mkdirs();}System.out.println(fileName);item.write(new File(storeDirectoryPath+File.separator+fileName));//删除临时文件}} catch (Exception e) {throw new RuntimeException("上传失败,请重试");}}//计算存放的子目录private String makeChildDirectory(String realPath, String fileName) {int hashCode = fileName.hashCode();int dir1 = hashCode&0xf;// 取1~4位int dir2 = (hashCode&0xf0)>>4;//取5~8位String directory = ""+dir1+File.separator+dir2;File file = new File(realPath,directory);if(!file.exists())file.mkdirs();return directory;}private void processFormField(FileItem item) {String fieldName = item.getFieldName();//字段名String fieldValue;try {fieldValue = item.getString("UTF-8");} catch (UnsupportedEncodingException e) {throw new RuntimeException("不支持UTF-8编码");}System.out.println(fieldName+"="+fieldValue);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

      至此,上传的任务就基本完成了,有了上传当然也要有下载功能,在下载之前,我们需要将所有已经上传的文件显示在网页上,通过一个servlet与一个jsp页面来显示,servlet代码如下:
public class ShowAllFilesServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");File root = new File(storeDirectory);//用Map保存递归的文件名:key:UUID文件名   value:老文件名Map<String, String> map = new HashMap<String, String>();treeWalk(root,map);request.setAttribute("map", map);request.getRequestDispatcher("/listFiles.jsp").forward(request, response);}//递归,把文件名放到Map中private void treeWalk(File root, Map<String, String> map) {if(root.isFile()){String fileName = root.getName();//文件名     String oldFileName = fileName.substring(fileName.indexOf("_")+1);map.put(fileName, oldFileName);}else{File fs[] = root.listFiles();for(File file:fs){treeWalk(file, map);}}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
       通过上面的servlet转发到listFiles.jsp页面,listFiles.jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>title</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>    <h1>以下资源可供下载</h1>    <c:forEach items="${map}" var="me">    <c:url value="/servlet/DownloadServlet" var="url">    <c:param name="filename" value="${me.key}"></c:param>    </c:url>    ${me.value}  <a href="${url}">下载</a><br/>    </c:forEach>  </body></html>

      到这里,文件也显示出来了,就需要点击下载进行下载文件了,最后一步,我们再编写一个DownloadServlet:
public class DownloadServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String uuidfilename = request.getParameter("filename");//get方式提交的uuidfilename = new String(uuidfilename.getBytes("ISO-8859-1"),"UTF-8");//UUID的文件名String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");//得到存放的子目录String childDirecotry = makeChildDirectory(storeDirectory, uuidfilename);//构建输入流InputStream in = new FileInputStream(storeDirectory+File.separator+childDirecotry+File.separator+uuidfilename);//下载String oldfilename = uuidfilename.substring(uuidfilename.indexOf("_")+1);//通知客户端以下载的方式打开response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldfilename, "UTF-8"));OutputStream out = response.getOutputStream();int len = -1;byte b[] = new byte[1024];while((len=in.read(b))!=-1){out.write(b,0,len);}in.close();out.close();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}//计算存放的子目录private String makeChildDirectory(String realPath, String fileName) {int hashCode = fileName.hashCode();int dir1 = hashCode&0xf;// 取1~4位int dir2 = (hashCode&0xf0)>>4;//取5~8位String directory = ""+dir1+File.separator+dir2;File file = new File(realPath,directory);if(!file.exists())file.mkdirs();return directory;}}

      文件上传与下载就已经全部完成了。

     
0 0
原创粉丝点击