文件准备就不用说了,先建立一个jsp,此jsp负责用户上传文件。此jsp中有一form表单,此表单有三个特点,或者是说文件上传的三个前提。
a、表单的method必须是post
b、表单的enctype属性必须是multipart/form-data
c、表单中提供<inputtype="file"/>类型的上传输入域
下面是具体的代码:- <form action="${pageContext.request.contextPath}/servlet/UploadServlet2" method="post" enctype="multipart/form-data">
- name:<input type="text" name="name"/><br/>
- file1:<input type="file" name="photo"/><br/>
- file2:<input type="file" name="photo"/><br/>
- <input type="submit" value="上传"/>
- </form>
二.开始上传
我们建立一个servlet,在此servlet中开始准备上传时用到的类,也就是DiskFileItemFactory类,和ServletFileuqLoad类,DiskFileItemFactory负责管理磁盘文件,ServletFileuqLoad类负责上传和解析文件。下面是具体的代码。
- <pre name="code" class="java">public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- request.setCharacterEncoding("UTF-8");// 解决上传的中文文件乱码问题
- response.setContentType("text/html;charset=UTF-8");
- // 1.0. 检查是否是multipart/form-data类型的
- boolean isMultipart = ServletFileUpload.isMultipartContent(request);
- if (!isMultipart) {
- throw new RuntimeException(
- "The form's enctype attribute value must be multipart/form-data");
- }
- // 2.0开始实现上传,创建上传文件需要用到的两个对象
- DiskFileItemFactory factory = new DiskFileItemFactory();// 产生FileItem的工厂
- ServletFileUpload sfu = new ServletFileUpload(factory); //因为解析器依赖于这个工厂,所以将这个工厂传进去
- // 3.0创建一个容器来接收解析的内容
- List<FileItem> items = new ArrayList<FileItem>();
- //4.0将上传的文件信息放到容器中
- try {
- items = sfu.parseRequest(request);
- } catch (FileUploadException e) {
- e.printStackTrace();
- }
- //5.0 遍历 开始处理解析的内容,这里封装了两个方法,一个是专门处理FormField的方法,一个是专门处理UploadField的方法
- for (FileItem item : items) {
- if (item.isFormField()) {
- processFormField(item);// 处理普通p上传字段
- } else {
- processUploadField(item);// 处理上传字段
- }
- }
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
下面是两个需要解析的方法,一个是一个是专门处理FormField的方法(也就是表单中普通的字段),一个是专门处理UploadField的方法(也就是需要上传的文件)。
三、解析上传文件并保存到服务器
1、专门处理FormField的方法
- <pre name="code" class="java">protected void processFormField(FileItem item) {
- // 打印到控制台
- String fieldName = item.getFieldName();
- String value = "";
- try {
- value = item.getString("UTF-8");// 解决普通字段的编码问题,得到普通字段的值
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- System.out.println(fieldName + "=" + value);
- }
2、专门处理FormField的方法(此方法负责存放文件)
- <pre name="code" class="java">protected void processUploadField(FileItem item) {
- try {
- // 找到一个存放位置 存放文件名
- String fileName = item.getName();// 上传的文件的文件名
- // C:\Users\wzhting\Desktop\a.txt
- // a.txt(浏览器不同)
- if (fileName != null) {
- // 控制只能能上传图片
- // if (!item.getContentType().startsWith("image")) {
- // return;
- // }
- fileName = FilenameUtils.getName(fileName);
- fileName = IdGenertor.genGUID() + "_" + fileName;
- }
- // 存放路径
- String realPath = getServletContext().getRealPath("/WEB-INF/files");
- // 生成一个子目录
- String childDirectory = genChildDirectory(realPath, fileName);
- File storeDirectory = new File(realPath + File.separator
- + childDirectory);
- //如果目录不存在,就创建一个
- if (!storeDirectory.exists()) {
- storeDirectory.mkdirs();
- }
- //开始存放磁盘文件
- item.write(new File(storeDirectory, fileName));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- <pre name="code" class="java">// 按照hashcode创建分目录 放置一个文件夹下面的上传文件过度
- private String genChildDirectory(String realPath, String fileName) {
- int hashCode = fileName.hashCode();
- int dir1 = hashCode & 0xf;
- int dir2 = (hashCode & 0xf0) >> 4;
- String str = dir1 + File.separator + dir2;
- File file = new File(realPath, str);
- if (!file.exists()) {
- file.mkdirs();
- }
- return str;
- }
- // 按照时间创建分目录 放置一个文件夹下面的文件过多
- protected String genChildDirectory(String realPath) {
- Date now = new Date();
- DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
- String str = df.format(now);
- File file = new File(realPath, str);
- if (!file.exists()) {
- file.mkdirs();
- }
- return str;
- }
四、其它上传文件中经常用到的功能
1.限制上传文件的类型,比如说,限制只能上传照片
- if (!item.getContentType().startsWith("image")) {
- return;
- }
2.限制一下上传文件的大小
- DiskFileItemFactory factory = new DiskFileItemFactory();// 产生FileItem的工厂
- ServletFileUpload sfu = new ServletFileUpload(factory); //因为解析器依赖于这个工厂,所以将这个工厂传进去
- // 限制上传文件大小
- sfu.setFileSizeMax(1024 * 196);// 限制单个文件的大小不超过200kb
- //sfu.setSizeMax(5*1024*1024);//限制上传的总文件大小不超过5M
- // 3.0创建一个容器来接收解析的内容
- List<FileItem> items = new ArrayList<FileItem>();
- //4.0将上传的文件信息放到容器中
- try {
- items = sfu.parseRequest(request);
- } catch (FileUploadBase.FileSizeLimitExceededException e) {
- response.getWriter().write("照片不能超过196k");
- } catch (FileUploadException e) {
- e.printStackTrace();
- }