欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaWeb之文件上传

程序员文章站 2022-05-08 17:05:41
...

通过commons-fileupload-1.2.1.jar组件上传文件,需要的以来包有Commons-io-1.4.jar。上传的表单如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
  	<form action="UploadServlet" enctype="multipart/form-data" method="post">
  	 用户名:<input type="text" name="username"> <br />
    <input type="file" name="upload">
    <input type="submit" value="提交">
  	</form>
         
  </body>
</html>

Serlvet1.0代码

package com.gdin.servlet;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadServlet extends HttpServlet {


	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		
	}

	/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		InputStream in = request.getInputStream();
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		//upload.setHeaderEncoding("utf-8");//优先级高
		try {
			List<FileItem> fileItems = upload.parseRequest(request);
			
			//是否为普通表单项
			FileItem f1 = fileItems.get(0);
			String value1 = f1.getString("utf-8");//普通项的值
			System.out.println(f1.getFieldName()+"="+value1);
			//文件项
			
			FileItem f2 = fileItems.get(1);
			System.out.println("content-type="+f2.getContentType());
			System.out.println("size="+ f2.getSize());
			
			File f = new File("E:\\", "baibing.jpg");
			f2.write(f);//写入文件
			
			
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

 

文件上传的注意问题以及细节主要有:

1.提交的method必须为post。并且需要声明enctype="multipart/form-data"属性

2.文件必须保存到WEB-INF下,目的就是为了不让浏览器直接访问到
3.文件名相关问题

  * 有的浏览器上传的文件名是绝对路径,这需要切割。

  *有的文件名乱码或者普通表单项乱码:request.setCharacterEncoding("utf-8"),因为fileupload内部会调用request.setCharacterEncoding()。

  *文件同名问题:需要我们为每个文件添加名称前缀,前缀不能重复,CommonUtils.uuid()
4.目录打散:一个目录不能存放过多的文件
5.上传的文件大小限制:单个文件大小限制,整个请求所有数据大小限制
6.缓存目录与临时目录

 

下面Servlet2.0:主要是演示通过哈希码的方式来目录打散

package com.gdin.servlet;

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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import cn.itcast.commons.CommonUtils;

public class Upload2Servlet extends HttpServlet {

    /**
     * 目录方式有:文件名首字母,上传日期,哈希
     * 演示哈希存储路径
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }

    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //上传的三个步骤
        //创建工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //解析器
        ServletFileUpload upload = new ServletFileUpload(factory);
        //获取到文件
        try {
            List<FileItem> list = upload.parseRequest(request);
            FileItem f = list.get(1);
            //获取到路径
            String path = this.getServletContext().getRealPath("/WEB-INF/files");
            
            //获取到文件名
            String fname = f.getName();
            //处理路径的绝对路径问题
            int index = fname.indexOf("\\");
            if(index != -1){
                fname = fname.substring(index+1);
            }
            
            //获得哈希值
            int hcode = fname.hashCode();
            //转为16进制
            String hex = Integer.toHexString(hcode);
            
            //创建目录
            File dir = new File(path, hex.charAt(0)+"/"+hex.charAt(1));
            /*
             * 如果不存在目录就创建,存在就不创建
             */
            dir.mkdirs();
            //保存的名字,防止同名覆盖
            String savename = CommonUtils.uuid()+"_"+fname;
            //创建文件
            File saveFile = new File(dir, savename);
            //保存
            f.write(saveFile);
        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

}