• 文件上传与下载


    一 概述

    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();
        }
    
    }
  • 相关阅读:
    [BZOJ3745][Coci2015]Norma
    [OJ#15]TR #2 画心
    [BZOJ3585][BZOJ3339]mex
    [OJ#63]树句节够提
    [LOJ#2255][BZOJ5017][Snoi2017]炸弹
    [LOJ#525]「LibreOJ β Round #4」多项式
    【字符编码】Java字符编码详细解答及问题探讨
    【Java基础】序列化与反序列化深入分析
    【目录】JVM目录
    【知识积累】随机数生成的几种方法
  • 原文地址:https://www.cnblogs.com/tonghun/p/6916386.html
Copyright © 2020-2023  润新知