使用commons-fileupload实现文件上传详解编程语言

一、文件上传的必要前提

1、表单的method必须是post

2、表单的enctype属性必须是multipart/form-data类型的。

enctype默认值:application/x-www-form-urlencoded

作用:告知服务器,请求正文的MIME类型

application/x-www-form-urlencoded   :   username=abc&password=123

ServletRequest.getParameter(String name);该方法是专门读取该类型的方法

multipart/form-data:


二、借助commons-fileupload组件实现文件的上传

拷贝jar包:commons-fileupload.jar

commons-io.jar


三、乱码问题

1、普通字段的乱码

FileItem.getString(String charset);编码要和客户端一致

2、上传的中文文件名乱码

request.setCharacterEncoding(“UTF-8”);编码要和客户端一致


四、程序代码

前台upload.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/UploadServlet3″ method=”post” enctype=”multipart/form-data”>

        name:<input name=”name”/><br/>

        file1:<input type=”file” name=”f1″/><br/>

        file2:<input type=”file” name=”f2″/><br/>

        <input type=”submit” value=”上传”>

    </form>

  </body>

</html>

后台servlet代码

import java.io.File;

import java.io.IOException;

import java.io.PrintWriter;

import java.io.UnsupportedEncodingException;

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;

import org.apache.commons.fileupload.FileUploadException;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

import org.apache.commons.io.FilenameUtils;

//详解

public class UploadServlet3 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();

                

                if(contentType.startsWith(“image/”)){

                

                //分目录存储:日期解决

    //            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);

    }

}


五、关于临时文件问题

1、DiskFileItemFactory

public void setRepository(File repository):设置临时文件的存放目录

public void setSizeThreshold(int sizeThreshold):设置缓存的大小

2、文件上传时,自己用IO流处理,一定要在流关闭后删除临时文件。FileItem.delete()

建议使用:FileItem.writer(File f).会自动删除临时文件。


六、限制文件的大小

1、ServletFileUpload.setFileSizeMax(3*1024*1024);//设置单个文件上传的大小

2、ServletFileUpload.setSizeMax(6*1024*1024);//多文件上传时总大小限制

使用commons-fileupload实现文件上传详解编程语言

转载请注明来源网站:blog.ytso.com谢谢!

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/14791.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论