文件上传与下载的功能实现

文件上传

文件上传原理分析

1、文件上传的必要前提: 
一、进行文件上传时只能使用post方式提交表单 
二、表单必须添加一个属性:enctype=”multipart/form-data” 
三、用于上传文件的元素必须时

2、enctype属性 
作用:告知服务器请求正文的MIME类型,作用与content-type一致。 
可选值: 
a)application/x-www-form-urlencoded(默认) 
b)multipart/form-data: 
通过字符串把普通项和文件上传项分开 
request.getParameter(String)方法获取指定的表单字段字符内容,但文件上传表单已经不在是字符内容,而是字节内容,所以失效。 
用传统取得提交参数的方式得到表单中提交的文本输入框中的内容 
在使用enctype=”multipart/form-data”提交表单后,文件内容可以被导航才到服务器,但同时,表单中的其他普通项不能再使用传统的getPatameter等方式取得其值。

实现文件上传功能

1、fileupload 
fileupload是由apache的commons组件提供的上传组件。它最主要的工作就是帮我们解析request.getInputStream()。 
导入commons-fileupload相关jar包 
- commons-fileupload.jar,核心包; 
- commons-io.jar,依赖包。

//通过请求对象的输入流可以得到上传的内容(文件内容和普通参数) 
ServletInputStream is = req.getInputStream();

2、fileupload的核心类的使用 
DiskFileItemFactory、ServletFileUpload、FileItem

使用fileupload组件的步骤如下: 
1.创建工厂类DiskFileItemFactory对象: 
DiskFileItemFactory factory = new DiskFileItemFactory() 
2.使用工厂创建解析器对象: 
ServletFileUpload fileUpload = new ServletFileUpload(factory) 
3.使用解析器来解析request对象: 
List list = fileUpload.parseRequest(request)

FileItem对象: 
FileItem对象对应一个表单项(表单字段)。可以是文件字段或普通字段 
- boolean isFormField():判断当前表单字段是否为普通文本字段,如果返回false,说明是文件字段; 
- String getFieldName():获取字段名称,例如:,返回的是username; 
- String getString():获取字段的内容,如果是文件字段,那么获取的是文件内容,当然上传的文件必须是文本文件; 
- String getName():获取文件字段的文件名称;(b.txt) 
- String getContentType():获取上传的文件的MIME类型,例如:text/plain。 
- int getSize():获取上传文件的大小; 
- InputStream getInputStream():获取上传文件对应的输入流; 
- void write(File):把上传的文件保存到指定文件中。 
- delete();

代码实现:

import java.io.FileOutputStream;
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;

/**
 * 用于文件上传测试的servlet
 * 进行文件上传时,只能使用post方式提交表单
 * @author Administrator
 *
 */
public class TestUploadServlet extends HttpServlet{

    /**
     * 测试文件上传工具:commons-fileupload的使用方式
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //用于设置文件上传时的临时文件的目录等信息
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //生成核心对象
        ServletFileUpload upload = new ServletFileUpload(factory);
        //使用核心对象对请求输入流进行解析
        try {
            List<FileItem> parseRequest = upload.parseRequest(req);
            for (FileItem fileItem : parseRequest) {
                if (fileItem.isFormField()) {
                    //普通上传项(得到名和值)
                    String fieldName = fileItem.getFieldName();
                    String value = fileItem.getString();
                    //测试普通项
                    System.out.println(fieldName+"="+new String(value.getBytes("ISO-8859-1"),"UTF-8"));
                } else {
                    //文件上传项(得到名,文件名,文件内容输入流,创建文件输出流,把上传文件写入服务器磁盘)
                    //从文件项对象中得到输入流
                    InputStream is = fileItem.getInputStream();
                    //创建一个磁盘文件的输出流
                    FileOutputStream fis = new FileOutputStream(getServletContext().getRealPath("/demo1/upfile")+"\\"+fileItem.getName());
                    System.out.println(getServletContext().getRealPath("/demo1/upfile"));
                    //流对接
                    byte[] buf= new byte[1024];
                    int len;
                    while ((len = is.read(buf)) > 0) {
                        fis.write(buf, 0, len);
                    }

                    fis.close();
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<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.servlet" method="post" enctype="multipart/form-data">
        <input type="text" name="msg" /><br/>
        <input type="file" name="upload" /><br/>
        <input type="submit"  />
    </form>
</body>
</html>

文件上传注意事项

a、保证服务器的安全 
把保存上传文件的目录放在用户直接访问不到的地方。 
b、避免文件被覆盖 
让文件名唯一即可 
c、避免同一个文件夹中的文件过多 
方法一:按照日期进行打散存储目录 
方法二:用文件名的hashCode计算打散的存储目录:二级目录 
d、限制文件的大小:web方式不适合上传大的文件 
单个文件大小: 
ServletFileUpload.setFileSizeMax(字节) 
总文件大小:(多文件上传) 
ServletFileUpload.setSizeMax(字节) 
e、上传字段用户没有上传的问题 
通过判断文件名是否为空即可 
f、临时文件的问题 
DiskFileItemFactory: 
作用:产生FileItem对象 
内部有一个缓存,缓存大小默认是10Kb。如果上传的文件超过10Kb,用磁盘作为缓存。 
存放缓存文件的目录默认是系统的临时目录。 
如果自己用IO流实现的文件上传,要在流关闭后,清理临时文件。 
FileItem.delete();

文件下载

案例:实现一个具有文件下载功能的网页,下载图片

代码实现:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 下载图片
 * @author Administrator
 *
 */
public class TestDownLoad extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取需要下载文件的名字
        String fileName = req.getParameter("fileName");
        //转换编码
        byte[] bytes = fileName.getBytes("ISO-8859-1");
        fileName = new String(bytes,"UTF-8");

        //通知浏览器以下载的方式打开文件,如果下载框中显示的文字是中文的话,又要编码,浏览器弹出的下载框来解码
        resp.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));

        //假设用户选中“保存”,/表示web项目
        InputStream is = this.getServletContext().getResourceAsStream("/images/上海地铁图.gif");
        OutputStream os = resp.getOutputStream();

        byte[] buf = new byte[1024*4];
        int len = 0;
        while ((len=is.read(buf))!=-1) {
            os.write(buf,0,len);
        }

        is.close();
        os.close();
    }
}

jps页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>图片下载</title>
</head>
  <body>
    <!-- /表示webapps目录
         对于GET请求后边带中文的情况下,需要进行UTF-8编码后,再传递到服务器
     -->
    <a href="/javaweb/demo11?fileName=%E4%B8%8A%E6%B5%B7%E5%9C%B0%E9%93%81%E5%9B%BE.gif" style="text-decoration:none;">上海地铁图.gif</a>
  </body>
</html>

   原文地址:https://blog.csdn.net/shuaicihai/article/details/53885357


猜你喜欢

转载自blog.csdn.net/sou_time/article/details/80769795