文件上传

  

文件上传与下载

一、文件上传

文件上传即将本地文件(图片、文本文件、压缩文件等)上传到服务器,并将文件在服务器的地址保存到数据库表中。

 

文件上传常用第三方插件实现,常见的有:

SmartUploadCommons-fileupload等。

1. SmartUpload

SmartUpload用于实现文件上传及下载的免费组件(第三方上传插件)。

优点

缺点

使用简单,编写代码少;

能控制上传内容及文件大小、类型

目前已停止更新,并且使用SmartUpload上传过大文件或多文件时,可能出现CPU或内存占用过高的问题,只有重新启动服务器才能恢复正常

 

具体实现:

1.1 导包

在项目WEB-INF\lib中导入SmartUpload插件所需要的jar包:jspsmartupload.jar

1.2 表单设置

在前端页面form表单中设置文件上传属性:

<form action="/upload.jsp" method="post" enctype="multipart/form-data">

选择文件:<input type="file" name="uploadFile" />

<input type="submit" value="上传" />

</form>

注意:

l form表单的method属性值必须是post,因为文件大小会超过255个字符。

l enctype属性表示发送到服务器之前应该如何对表单数据进行编码,multipart/form-data表示不对字符编码,将按照二进制的方式提交。

1.3 编写上传代码

在使用SmartUpload插件做提交时必须严格按照如下程序进行:

// 实例化SmartUpload上传组件

SmartUpload smart = new SmartUpload();

// 初始化上传操作

smart.initialize(pageContext);   //上下文

// 上传准备

smart.upload();

// 将上传文件保存在upload文件夹中

smart.saveAs("upload");

 

限制文件的上传类型:

// 允许上传类型

smart.setAllowedFilesList("gif,jpg,png,doc,rar");

// 不允许上传类型

smart.setDeniedFilesList("jsp,asp,php,aspx");

 

限制文件上传的大小:

smart.setMaxFileSize(2*1024*1024);

 

设置字符编码:(如果未设,当请求中含有中文时会报:java.lang.NullPointerException: charsetName

smart.setCharset("utf-8");

 

获得第一个上传文件的文件名:

String file = smart.getFiles().getFile(0).getFileName();

 

获得第一个上传文件的后缀名:

String ext = smart.getFiles().getFile(0).getFileExt();

 

拼凑文件名:

String fileName = file+"."+ext;

 

由于此时要用新的文件名称保存上传文件,所以要通过smart.getFiles().getFile(0).saveAs()方法进行手工保存。具体代码:

// file.saveAs(路径 , 上传方式)

smart.getFiles().getFile(0).saveAs(getServletContext().getRealPath("/")+"upload"+java.io.File.separator+fileName);

 

源代码:

<%@ page language="java" import="java.util.*,java.sql.*,com.jspsmart.upload.*" pageEncoding="gbk"%>

<%@page import="java.text.SimpleDateFormat"%>

<%

SmartUpload su = new SmartUpload();

su.initialize(pageContext);

 

com.jspsmart.upload.File file = null;

com.jspsmart.upload.Request req  = null;

 

try {

    // 定义允许上传文件类型   

su.setAllowedFilesList("gif,jpg,png");

// 不允许上传文件类型   

// su.setDeniedFilesList(jsp,asp,php,aspx,html,htm,exe,bat);

// 单个文件最大限制   

su.setMaxFileSize(2*1024*1024);

// 设置上传编码

su.setCharset("UTF-8");

// 执行上传

su.upload();

 

// 获得单个上传文件的信息

file = su.getFiles().getFile(0);

// 声明文件路径

String filepath = null;

// 用户是否选择了文件

if(!file.isMissing()){

// 设置文件在服务器的保存位置

filepath = "upload\\";

// 拼接上文件名

filepath += file.getFileName();

// 设置文件流编码

file.setCharset("utf-8");

// 文件流按保存模式保存到filepath路径下

file.saveAs(filepath, SmartUpload.SAVE_VIRTUAL);

}

} catch (Exception e) {

e.printStackTrace();

}

%>

 

1.4 混合表单

当表单使用enctype封装后,其他的非文件类的表单控件的内容就无法通过JSPRequest内置对象取得,此时必须通过SmartUpload类中提供的getRequest()方法获取表单的请求数据,例如:

String uname = smart.getRequest().getParameter("uname");

注意:该句代码一定要在执行完upload()方法之后才可以使用

1.5 为上传文件自动命名

如果多个用户上传的文件名称一样,则肯定会发生覆盖的情况,为了避免这类问题产生,可以采用为上传文件自动命名的方式。主要方式有:

 

时间戳

SimpleDateFormat date = new SimpleDateFormat("yyyyMMddHHmmssSSS");

String filename = date.format(new Date()) + file.getFileExt();

 

IP地址 + 时间戳 + 三位随机数

// 封装方法

public String getIPTimeRand(){

    // 实例化StringBuffer对象,用来做文件名拼接

    StringBuffer buf=new StringBuffer();

    

    // 获得本机的IP地址

    InetAddress addr = InetAddress.getLocalHost();

    ip=addr.getHostAddress().toString();//获得本机IP

    address=addr.getHostName().toString();//获得本机名称

    

    // 获得当前时间戳

    SimpleDateFormat date=new SimpleDateFormat("yyyyMMddHHmmssSSS");

    date.format(new Date());

 

    // 获得一个3位数的随机数

    Random r=new Random();

    for(int i=0; i<3; i){

    buf.append(r.nextInt(10));

    }

    return buf;

}

 

1.6 批量上传

如要完成批量上传,则肯定需要循环的方式进行,那么就必须通过如下方法取得上传文件数量。

 

Form表单代码:

<form action="smartupload.jsp" method="post" enctype="multipart/form-data">

    文件1<input type="file" name="pic1"><br/>

    文件2<input type="file" name="pic2"><br/>

    文件3<input type="file" name="pic3"><br/>

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

    <input type="reset" value="重置">

</form>

 

SmartUpload.jsp代码:

<%

    ……

SmartUpload smart=new SmartUpload();

smart.initialize(pageContext);

smart.upload();

for(int i=0; i<smart.getFiles().getCount(); i++){

    smart.save("upload");

}

    ……

%>

 

1.7 Servlet中写SmartUpload的问题

Servlet中使用SmartUpload时会出现pageContext上下文报错,解决办法如下:

 

方式一:

SmartUpload smart=new SmartUpload();

smart.initialize(this.getServletConfig(), request, response);

 

方式二:

使用了JspFactory.getDefaultFactory()方法。

SmartUpload smart=new SmartUpload();

PageContext context = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8*1024, true);

// 或者

// PageContext context = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, JspWriter.DEFAULT_BUFFER, true);

smart.initialize(context);

 

参数说明:

第一个参数是传递一个Servlet,在servlet中传递this就可以了;

第二个和第三个参数是requestresponse不多说明了;

第四个参数是发生错误后的url路径地址,如果没有可以键入null

第五个参数是是否需要session,这里可以写入true

第六个参数是缓存大小,我用了8*1024,也可以用JspWriter.DEFAULT_BUFFER

第七个参数是是否需要刷新,键入ture

<要注意抛异常>

 

1.8 设置表单上传文件类型

accept="image/gif, image/jpeg"指定允许上传的只有gifjpg文件。

<form action="/upload.jsp" method=”post” accept="image/gif, image/jpeg">

  <p>First name: <input type="text" name="fname" /></p>

  <p>Last name: <input type="text" name="lname" /></p>

  <p>Your image: <input type="file" name="pic" id="pic" /></p>

  <input type="submit" value="Submit" />

</form>

 

2. Commons-FileUpload

文件上传下载一般使用commons-fileupload实现上传功能,因为commons-fileupload依赖于commons-io这个包,所以需要下载这两个包commons-fileupload-1.2.1.jarcommons-io-1.3.2.jar

2.1 导包

将相关jar包添加到项目的WEB-INF/lib目录下:

commons-fileupload-1.2.1.jar

commons-io-1.3.2.jar

2.2 表单设置

<form action="/fileupload" method="post" enctype="multipart/form-data" name="form1">

    <input type="file" name="myFile">

    <input type="submit" value="确定">

</form>

2.3 文件上传后台关键代码

虚拟路径的转换

application.getRealPath(path);

 

// 临时文件缓存目录设置以及文件上传时的缓存大小设置

DiskFileItemFactory

setRepository

setSizeThreshold

注:文件缓存目录(temp)及文件上传目录(uploads)必须提前建好

 

// 上传文件大小设置及请求处理

ServletFileUpload

    setFileSizeMax

    parseRequest(request);

      

// 表单数据获取和类型判断

    无法通过request对象获得,只能通过FileItem获得

    表单数据分为:普通元素(如:文件框、密码框)和文件

    FileItem.isFormField

 

// 获得上传文件的文件名,根据文件名对上传文件类型进行限制

    String fileName = FileItem.getName();

    String regex = "^.+\\.(jpg|gif|txt|doc)$";

    Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);

    Matcher matcher = pattern.matcher(fileName);

    boolean b = matcher.matches();

 

// IO流保存文件

    UUID生成32位长唯一字符串,保存时无需考虑文件名及类型

    UUID.randomUUID();

    保存文件后记得删除临时文件(重要)

    FileItem.delete();

 

2.4 案例:上传代码

public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

 

    // 上传文件存储目录

    private static final String UPLOAD_DIRECTORY = "upload";

 

    // 上传配置

    private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3;  // 3MB

    private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB

    private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB

 

    /**

     * 上传数据及保存文件

     */

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

// 检测是否为多媒体上传

if (!ServletFileUpload.isMultipartContent(request)) {

    // 如果不是则停止

    PrintWriter writer = response.getWriter();

    writer.println("Error: 表单必须包含 enctype=multipart/form-data");

    writer.flush();

    return;

}

 

        // 配置上传参数

        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中

        factory.setSizeThreshold(MEMORY_THRESHOLD);

        // 设置临时存储目录

        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

 

        ServletFileUpload upload = new ServletFileUpload(factory);

         

        // 设置最大文件上传值

        upload.setFileSizeMax(MAX_FILE_SIZE);

         

        // 设置最大请求值 (包含文件和表单数据)

        upload.setSizeMax(MAX_REQUEST_SIZE);

 

        // 编码处理

        upload.setHeaderEncoding("UTF-8");

 

        // 构造临时路径来存储上传的文件

        // 这个路径相对当前应用的目录

        String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY;

       

        // 如果目录不存在则创建

        File uploadDir = new File(uploadPath);

        if (!uploadDir.exists()) {

            uploadDir.mkdir();

        }

 

        try {

            // 解析请求的内容提取文件数据

            @SuppressWarnings("unchecked")

            List<FileItem> formItems = upload.parseRequest(request);

 

            if (formItems != null && formItems.size() > 0) {

                // 迭代表单数据

                for (FileItem item : formItems) {

                    // 处理不在表单中的字段

                    if (!item.isFormField()) {

                        String fileName = new File(item.getName()).getName();

                        String filePath = uploadPath + File.separator + fileName;

                        File storeFile = new File(filePath);

                        // 在控制台输出文件的上传路径

                        System.out.println(filePath);

                        // 保存文件到硬盘

                        item.write(storeFile);

                        request.setAttribute("message", "文件上传成功!");

                    }

                }

            }

        } catch (Exception ex) {

            request.setAttribute("message", "错误信息: " + ex.getMessage());

        }

        // 跳转到 message.jsp

        request.getServletContext().getRequestDispatcher("/message.jsp").forward(request, response);

    }

}

message.jsp 文件代码如下:

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>文件上传结果</title>

</head>

<body>

    <center>

        <h2>${message}</h2>

    </center>

</body>

</html>

3. 百度上传插件

http://www.jq22.com/yanshi5302

二、文件下载

1. 使用Commons-FileUpload实现下载

导入commons-fileupload-1.2.1.jarcommons-io-1.3.2.jar

 

JSP页面源代码:

<%@ 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>文件下载</title>     

  </head>  

    

  <body>  

<a href="/download/DownloadServlet?filename=1.jpg">文件下载</a>  

  </body>  

</html>

 

Servlet源代码:

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

          

        response.setCharacterEncoding("UTF-8");  

        //设置ContentType字段值  

        response.setContentType("text/html;charset=utf-8");  

        //获取所要下载的文件名称  

        String filename = request.getParameter("filename");  

        //下载文件所在目录  

        String folder = "/filename/";  

        //通知浏览器以下载的方式打开  

        response.addHeader("Content-type", "appllication/octet-stream");  

        response.addHeader("Content-Disposition", "attachment;filename="+filename);  

        //通知文件流读取文件  

        InputStream in = getServletContext().getResourceAsStream(folder+filename);  

        //获取response对象的输出流  

        OutputStream out = response.getOutputStream();  

        byte[] buffer = new byte[1024];  

        int len;  

        //循环取出流中的数据  

        while((len = in.read(buffer)) != -1){  

            out.write(buffer,0,len);  

        }     

}

 

 

 

 

1. mime介绍

   MIME意为多用途Internet邮件扩展协议,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,

   让邮件客户程序能根据其类型进行处理。每个MIME类型由两部分组成,前面是数据的大类别,后面为具体的种类。

   例如:image/bmpimage/jpegaudio/mpeg

 

2. 文件上传记录表结构介绍

   t_file_upload_recored

3. entity/dao创建及测试

   FileUploadRecored

   FileUploadRecoredDao

     add

     load

     list

4. 文件下载的两种方式

  4.1 直接打开

      response.setHeader("content-disposition","filename=\"2.jpg\"");

  4.2 另存为

      response.setHeader("content-disposition","attachment;filename=\"2.jpg\"");

5. 中文文件名的处理

   fileName = URLEncoder.encode(fileName,"UTF-8");

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值