文件上传与下载

一 概述

1.什么是文件上传?

将本地文件保存到服务器上的过程,叫做文件上传。

2.什么是文件下载?

广义上,任何从服务器端获取数据的过程都属于文件下载,默认情况下由浏览器打开展示。狭义的文件下载,指的是将从服务器端获取的数据以附件的形式保存到本地。因此下载文件时,需要重新设定浏览器处理响应内容的方式:

response.setHeader("Content-disposition","attachment;filename=xxxxxx");

由于响应报头只支持ISO-8859-1的编码方式,如果文件名含有中文,将出现乱码,因此文件名必须转化为ISO-8859-1编码形式:

String filenameStr="图片.jpg"//定义中文文件名
byte[] buf=filenameStr.getBytes("UTF-8");//将文件名转化为UTF-8编码系统下的字节码(工作空间采用UTF-8编码)
String filename =new String(buf,"ISO-8859-1");//采用ISO-8859-1对字节码重新进行编码

二 上传

1.文件上传对请求的要求

请求方式:POST。
数据类型:

enctype="multipart/form-data"

表单编写:

<form action="${pageContext.request.contextPath }/fc01.do"method="post" enctype="multipart/form-data">
      <input type="file" name="img">
      <input type="submit" value="上传文件">
</form>

2.文件上传的关键

上传文件在服务器上的目录一般已固定,只需要获取了输入流,就可以完成上传任务。上传文件在客户端的路径由用户指定,不能采用:

FileInputStream is=new FileInputStream(String sourcePath)

确定,因此创建输入流是文件上传的关键。

3.不同的框架提供了不同的获取输入流的方式。

4.Servlet上传

Servlet提供了Part对象获取输入流。

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet("/uploadServlet")
@MultipartConfig()
public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");
        Part part = request.getPart("fileName");
        //利用自定义工具从Content-disposition请求头中获取文件名
        String fileName = UploadUtils.getFileName(part); 
        String path = request.getServletContext().getRealPath("/Files");
        part.write(path + File.separator + fileName);
    }

}

5.SpringMVC上传

SpringMVC提供了MultipartFile对象实现文件上传。
配置文件:

<mvc:annotation-driven />
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
     <!--单次允许上传的最大值 -->
     <property name="MaxUploadSize" value="1048576" />
     <!--设置文件上传时的编码方式,解决文件名为中文时的乱码问题 -->
     <property name="defaultEncoding" value="UTF-8" />
</bean>

java代码:

import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping
public class FileUploadController {

    @RequestMapping("/fc01.do")
    public String doUpload01(HttpSession session, MultipartFile img, Model model)
            throws IllegalStateException, IOException {
        if (img.getSize() > 0) {
            String filename = img.getOriginalFilename();
            System.out.println("filename=" + filename);
            if (filename.endsWith("jpg")) {
                String path = "d:/uploadFiles";
                File file = new File(path, filename);
                img.transferTo(file);
            } else {
                model.addAttribute("fileTip", "不支持格式");
                return "/fileUpload/index.jsp";
            }
            
        } else {
            model.addAttribute("fileTip", "请选择文件");
            return "/fileUpload/index.jsp";
        }

        return "/fileUpload/success.jsp";
    }

}

6.Struts2上传

基本原理:fileUpload拦截器先将文件上传到临时文件中,然后注入到Action中。
核心代码:

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class SingleuploadAction extends ActionSupport {

    private static final long serialVersionUID = 7322039059983814357L;
    private File img;
    private String imgFileName;

    public File getImg() {return img;
    }

    public void setImg(File img) {
this.img = img; } public String getImgFileName() {
return imgFileName; } public void setImgFileName(String imgFileName) {
this.imgFileName = imgFileName; } public String doFileupload() throws Exception {
if (img != null) { String fileName = img.getName(); String path = ServletActionContext.getServletContext().getRealPath("/imgs"); File destFile = new File(path, imgFileName); FileUtils.copyFile(img, destFile); return SUCCESS; } return INPUT; } }

三 下载

1.下载的关键

下载是从服务器固定目录获取文件,输入流可知,输出路径由用户定义,因此关键是创建输出流。

2.Struts2下载

Struts2采用跳转方式stream创建输出流。
配置文件:

<package name="down" extends="struts-default">
     <action name="download" class="com.struts2.download.DownloadAction">
            <result type="stream">
                  <!--指明输入流,以便系统获取 -->
                  <param name="inputName">inputStream</param>
                  <param name="contentDisposition">attachment;filename=${fileName}</param>
            </result>
     </action>
</package>

java代码:

import java.io.InputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class DownloadAction extends ActionSupport {

    private static final long serialVersionUID = 1L;

    private InputStream inputStream;
    private String fileName;

    public InputStream getInputStream() {
return inputStream; } public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream; } public String getFileName() {
return fileName; } public void setFileName(String fileName) {
this.fileName = fileName; } public String execute() { fileName = "1.jpg"; inputStream = ServletActionContext.getServletContext().getResourceAsStream("/Files/1.jpg");
return SUCCESS; } }

3.Servlet下载

Servlet提供了ServletOuputStream作为文件下载的输出流。

核心代码:

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * 请求报头与响应报头只支持ISO-8859-1的编码方式,任何出现的报头中的字符都必须能够被ISO-8859-1编码,
     * 不能的必须先转化为ISO-8859-1编码,比如中文。
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.setContentType("text/html;charset=UTF-8");// 设置响应体中内容的编码方式

        /*
         * 将含有中文的文件名转化为ISO-8859-1编码形式
         */
        String filenameStr = "图片A";
        byte[] bytes = filenameStr.getBytes("UTF-8");
        String filename = new String(bytes, "ISO-8859-1");// 设置浏览器以附件形式处理响应
        response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".jpg");
        InputStream is = getServletContext().getResourceAsStream("/Files/upload.txt");// 以输入流形式获取上传文件
        ServletOutputStream os = response.getOutputStream();// 获取向客户端输出的输出流

        /*
         * 输入流与输出流结合,先获取文件内容,再将内容输出
         */
        int len = -1;
        byte[] buf = new byte[1024];
        while ((len = is.read(buf)) != -1) {
            os.write(buf);
        }
        os.close();
        is.close();
    }

}
原文地址:https://www.cnblogs.com/tonghun/p/6916386.html