UploadServlet.java html
package cn.heimar.upload; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.UUID; 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.FileUploadBase.SizeLimitExceededException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * 1,限制上传文件大小 2,限制上传文件类型 3,设置上传缓存大小 */ public class UploadServlet extends HttpServlet { private String[] allowedSuffix = new String[] { "JPG", "JPEG", "GIF","BMP", "PNG", "ICO" }; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 判断上传的确实是一个包含了文件域的表单 boolean isMultipart = ServletFileUpload.isMultipartContent(req); if (isMultipart) { try { // 处理有文件的表单内容 // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); File folder = new File("C:\\uploadtemp"); if(!folder.exists()){ folder.mkdirs(); } // 设置临时文件夹 factory.setRepository(folder); // 设置缓存区大小 factory.setSizeThreshold(3 * 1024 * 1024); // 建立一个上传处理器 ServletFileUpload upload = new ServletFileUpload(factory); // 设置一次请求可以上传的文件总大小 upload.setSizeMax(10 * 1024 * 1024); // 解析请求 List<FileItem> items = upload.parseRequest(req); //FileItem:包装了普通表单域和文件域的统一对象 for (FileItem item : items) { // isFormField是在判断当前FileItem是否是普通表单域 if (item.isFormField()) { // item.getFieldName:表单属性名称 String name = item.getFieldName(); // item.getString:表单属性值 String value = item.getString(); System.out.println(name + " " + value); } else { String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); // 判断文件类型是否合法 String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); if (Arrays.asList(allowedSuffix).contains(suffix.toUpperCase())) { String writeFileName = UUID.randomUUID().toString(); String fp = this.getServletContext().getRealPath("/upload") + File.separator + writeFileName + "." + suffix; item.write(new File(fp)); } else { System.out.println("文件类型不合法"); } } } } catch (SizeLimitExceededException fx) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } else { // 按照普通表单的方法处理 } } }
upload.jsp java
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/upload" method="POST" enctype="multipart/form-data"> <table> <tr> <td>文件名称:</td> <td><input type="text" name="name" /></td> </tr> <tr> <td>文件:</td> <td><input type="file" " name="filepath"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="上传" /></td> </tr> </table> </form> </body> </html>
在一些网络系统中,须要隐藏下载文件的真实地址,或者下载的文件须要一个程序来动态的肯定后在传送给客户端。 apache
解决方案: 浏览器
利用程序编码实现下载。利用程序实现下载须要设置 2 个报头: 缓存
Web 服务器须要告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML 文件,而是一个要保存到本地的下载文件。设置Content-Type 的值为:application/x-msdownloadWeb 服务器但愿浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这须要设置 Content-Disposition 报头。该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还能够指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。在设置 Content-Dispostion 以前必定要指定 Content-Type。 安全
示例: 服务器
DownloadServlet.java 网络
package cn.heimar.upload; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DownloadServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String filename = req.getParameter("file"); /* * 设置响应报头 contentType: application/x-msdownload --> * 告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML 文件,而是一个要保存到本地的下载文件 */ // response.setHeader("content-type", "application/x-msdownload"); resp.setContentType("application/x-msdownload"); /* * 设置响应报头 Content-Disposition: attachment Web 服务器但愿浏览器不直接处理相应的实体内容, * 而是由用户选择将相应的实体内容保存到一个文件中 */ resp.setHeader("Content-Disposition", "attachment; filename=11111.zip"); String filePath = this.getServletContext().getRealPath( "/WEB-INF/download") + File.separator + filename; BufferedInputStream is = new BufferedInputStream(new FileInputStream( filePath)); BufferedOutputStream os = new BufferedOutputStream( resp.getOutputStream()); byte[] buf = new byte[1024]; int len = 0; while ((len = is.read(buf)) != -1) { os.write(buf, 0, len); } is.close(); os.close(); } }download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="${pageContext.request.contextPath }/download?file=test.zip">点击下载</a> </body> </html>