zoukankan      html  css  js  c++  java
  • n文件的上传和下载,struts2和springmvc

    首先,struts2的上传下载的配置

    因为struts2是配置的上传的拦截器,很简单的步揍就可以上传,

    首先是配置struts的action映射

    <!-- 4. 修改上传文件的最大大小为30M -->
    <constant name="struts.multipart.maxSize" value="31457280"/>
    
    <!-- 注意: action 的名称不能用关键字"fileUpload" -->
            <action name="fileUploadAction" class="cn.itcast.e_fileupload.FileUpload">
            
                <!-- 限制运行上传的文件的类型 -->
                <interceptor-ref name="defaultStack">
                    
                    <!-- 限制运行的文件的扩展名 -->
                    <param name="fileUpload.allowedExtensions">txt,jpg,jar</param>
                    
                    <!-- 限制运行的类型   【与上面同时使用,取交集】
                    <param name="fileUpload.allowedTypes">text/plain</param>
                    -->
                </interceptor-ref>
                
                <result name="success">/e/success.jsp</result>
                
                <!-- 配置错误视图 -->
                <result name="input">/e/error.jsp</result>
            </action>

    配置好了之后,在所配置的类里写代码,

    在这里,需要根据表单上传文件jsp中的

    文件:<input type="file" name="file1"><br/>  //其中的“file1”很重要

    因为再接下来的上传代码中,如下

    package cn.itcast.e_fileupload;
    
    import java.io.File;
    
    import org.apache.commons.io.FileUtils;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class FileUpload extends ActionSupport {
    
        // 对应表单:<input type="file" name="file1">
        private File file1; //根据表单中的file1得到对应的选择的需要上传的文件,
        // 文件名
        private String file1FileName;//这个是上传文件的文件名
        // 文件的类型(MIME)
        private String file1ContentType;//上传文件的类型
        public void setFile1(File file1) {
            this.file1 = file1;
        }
        public void setFile1FileName(String file1FileName) {
            this.file1FileName = file1FileName;
        }
        public void setFile1ContentType(String file1ContentType) {
            this.file1ContentType = file1ContentType;
        }
        
        
        @Override
        public String execute() throws Exception {
            /******拿到上传的文件,进行处理******/
            // 把文件上传到upload目录
            // 获取上传的目录路径
            //String path = ServletActionContext.getServletContext().getRealPath("/upload");
            String path = "E:\upload";//上传到的存储位置
            // 创建目标文件对象
            File destFile = new File(path,file1FileName);
            // 把上传的文件,拷贝到目标文件中
            FileUtils.copyFile(file1, destFile);
            return SUCCESS;
        }
    }

    上面的单个文件上传,就是得到网页传过来的内容,存储内容到指定得位置。

    下面有一个多个文件的上传

    首先是上传的表单,表单type=file的

    <input type="file" name="photo"><br/>

    <input type="file" name="photo"><br/>

    的名字相同name=photo,

    下面是后台文件

    package com.itheima.action;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.servlet.ServletContext;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionSupport;
    //多文件上传
    //动作类作为模型
    public class Upload2Action extends ActionSupport {
        
        private String name;
        private File[] photo;//必须是File数组或者List<File>
        private String[] photoFileName;//上传文件的文件名。XXXFileName固定写法
        private String[] photoContentType;//上传文件的MIME类型。XXXContentType固定写法
        
        public String upload() throws Exception{
            //完成上传
            ServletContext sc = ServletActionContext.getServletContext();
            String directory = sc.getRealPath("/files");//得到存放文件的真实目录
            if(photo!=null&&photo.length>0){
                for(int i=0;i<photo.length;i++){
                    //构建目标文件
                    File target = new File(directory, photoFileName[i]);
                    FileUtils.copyFile(photo[i], target);
                }
            }
            return SUCCESS;
        }
        
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    
    
        public File[] getPhoto() {
            return photo;
        }
    
    
        public void setPhoto(File[] photo) {
            this.photo = photo;
        }
    
    
        public String[] getPhotoFileName() {
            return photoFileName;
        }
    
    
        public void setPhotoFileName(String[] photoFileName) {
            this.photoFileName = photoFileName;
        }
    
    
        public String[] getPhotoContentType() {
            return photoContentType;
        }
    
    
        public void setPhotoContentType(String[] photoContentType) {
            this.photoContentType = photoContentType;
        }
        
    }

    遍历photo就可以了。

    下面是下载,

    同使用传统的下载一样,需要首先把能下载的list列出来。

    在这之前,还是配置一个拦截器

    <action name="down_*" class="cn.itcast.e_fileupload.DownAction" method="{1}">
                <!-- 列表展示 -->
                <result name="list">/e/list.jsp</result>
                <!-- 下载操作 -->
                <result name="download" type="stream">
                
                    <!-- 运行下载的文件的类型:指定为所有的二进制文件类型 -->
                   <param name="contentType">application/octet-stream</param>
                   
                   <!-- 对应的是Action中属性: 返回流的属性【其实就是getAttrInputStream()】 -->
                   <param name="inputName">attrInputStream</param>
                   
                   <!-- 下载头,包括:浏览器显示的文件名 -->
                   <param name="contentDisposition">attachment;filename=${downFileName}</param>
                 
                     <!-- 缓冲区大小设置 -->
                   <param name="bufferSize">1024</param>
                </result>
    </action>

    这里的downFileName为下载下来后,输出到浏览器的文件名,

    <param name="inputName">attrInputStream</param>为里面的输入流,名字为attrInputStream。方法里有个get方法,同理downFileName也是有个get方法,代码如下
        /*************2. 文件下载*********************/
        
        // 1. 获取要下载的文件的文件名
        private String fileName;
        public void setFileName(String fileName) {
            // 处理传入的参数中问题(get提交),中文需要转码请求的url为,down_down?fileName=jstl-impl.jar
            try {
                fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            // 把处理好的文件名,赋值
            this.fileName = fileName;
        }
        
        //2. 下载提交的业务方法 (在struts.xml中配置返回stream)
        public String down() throws Exception {
            //attrInputStream = getAttrInputStream();
            
            //downFileName = getDownFileName();
            return "download";
        }
        
        // 3. 返回文件流的方法
        public InputStream getAttrInputStream() throws IOException {
            //在文件地址中返回所属文件名的文件,这个是返回的是电脑上的
            InputStream is = new FileInputStream(new File("E:\upload\",fileName));
            return is ;
            //return ServletActionContext.getServletContext().getResourceAsStream("/upload" + fileName);
        }
        
        // 4. 下载显示的文件名(浏览器显示的文件名)
        public String getDownFileName() {
            // 需要进行中文编码
            try {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            return "down_"+fileName;
        }
    
        

    以上就是struts2的上传下载,其实下载还有下面的一个方法,inputStream和downfileName写在主方法里面,代码如下

    /*************2. 文件下载*********************/
        
        // 1. 获取要下载的文件的文件名
        private String fileName;
        private InputStream attrInputStream;
        private String downFileName; 
        
        public void setAttrInputStream(InputStream attrInputStream) {
            this.attrInputStream = attrInputStream;
        }
    
        public void setDownFileName(String downFileName) {
            this.downFileName = downFileName;
        }
        
    
        public InputStream getAttrInputStream() {
            return attrInputStream;
        }
    
        public String getDownFileName() {
            return downFileName;
        }
    
        public void setFileName(String fileName) {
            // 处理传入的参数中问题(get提交),中文需要转码请求的url为,down_down?fileName=jstl-impl.jar
            try {
                fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            // 把处理好的文件名,赋值
            this.fileName = fileName;
        }
        
        //2. 下载提交的业务方法 (在struts.xml中配置返回stream)
        public String down() throws Exception {
            downFileName = "down"+fileName;
            attrInputStream = new FileInputStream(new File("E:\upload\",fileName));
            //attrInputStream = getAttrInputStream();
            //downFileName = getDownFileName();
            return "download";
        }

    这里主要就是要为downFileName和attrInputStream注入值,页面下载到的值就是这个的attrInputStream,和名字也为downFileName

    好,下面就来看看springmvc的上传和下载了,springmvc的上传和下载更为简单,通样和struts2的原理一样,要有几个关键的值,

    上传时,上传的文件名,上传的文件流的保存路径,保存的文件名,文件类型。

    下载时,取到下载的文件流及名称,下载后的名称,文件类型

     springMVC,首先需要在springMVC.xml下配置,前提是同样要引入两个jar,commons-fileupload和commons-io两个jar

     <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->  
        <bean id="multipartResolver"    
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
            <!-- 默认编码 -->  
            <property name="defaultEncoding" value="utf-8" />    
            <!-- 文件大小最大值 -->  
            <property name="maxUploadSize" value="10485760000" />    
            <!-- 内存中的最大值 -->  
            <property name="maxInMemorySize" value="40960" />    
        </bean>   

    在springMVC中,最主要的是

    MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)request;

    MultipartFile file = mreq.getFile("file1");

    同时当多个文件的时候,可以使用mreq.getFiles();其主要的一些方法

    byte[] getBVytes[];//它以字节数组的形式返回文件的内容;

    String getContentType();//返回文件的内容类型;

    InputStream getInputStream();//从文件中读取文件的内容;

    String getName();//以多部分的形式返回参数的名称

    String getOriginalFilename();//它返回客户端本地区中的初始文件名。

    long getSize();//以字节为单位,返回文件的大小;、

    boolean isEmpty();//判断被上传的文件是否为空,

    void transferTo(File destination);//将上传的文件保存到指定得文件路径;

    上传代码如下

    package win.qieqie.web.action;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    
    @Controller
    @RequestMapping("/load")
    public class Upload {
        
        @RequestMapping("/up")
        public String uploada(HttpServletRequest request,String userName) throws IOException
        {
                MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)request;
                MultipartFile file = mreq.getFile("file1");
                System.out.println(userName);//表单里不为文件的数据得值
                String fileName = file.getOriginalFilename();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); 
                //保存到工程目录下
                /*FileOutputStream fos = new FileOutputStream(request.getSession().getServletContext().getRealPath("/")+
                        "upload/"+sdf.format(new Date())+fileName.substring(fileName.lastIndexOf('.')));*/
                //传送到指定得位置
                /*FileOutputStream fos = new FileOutputStream("E:\upload\"+sdf.format(new Date())+fileName.substring(fileName.lastIndexOf('.')));
                fos.write(file.getBytes());
                fos.flush();
                fos.close();*/
                //下面这种方式同样可以保存到指定位置,只是速度有点慢
                File dest = new File("E:\upload\"+sdf.format(new Date())+fileName);
                file.transferTo(dest);
            return "success";
        }
    }

    下面是文件的下载,同理,文件的下载需要获取文件列表,文件的内容,传送到页面去

    前台需要一个下载的路径和下载的filename

    这里需要注意一个,get方式请求的中文编码问题,解决办法

    fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");

     重新把file转码成utf-8

    下载的list页面

    <%@ 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>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">
      </head>
      
      <body>
          <table border="1" align="center">
              <tr>
                  <td>编号</td>
                  <td>文件名</td>
                  <td>操作</td>
              </tr>
              <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
              <c:forEach var="fileName" items="${fileNames}" varStatus="vs">
                  <tr>
                      <td>${vs.count }</td>
                      <td>${fileName }</td>
                      <td>
                          <!-- 构建一个url -->
                          <c:url var="url" value="/load/down">
                              <c:param name="fileName" value="${fileName}"></c:param>
                          </c:url>
                          
                          <a href="${url }">下载</a>
                      </td>
                  </tr>
              </c:forEach>
          </table>
      </body>
    </html>

    下载的list请求代码

    @RequestMapping("list")
        public String list(HttpServletRequest request)
        {
            //得到upload目录路径
                    //String path = ServletActionContext.getServletContext().getRealPath("/upload");
                    String path = "E:\upload";
                    // 目录对象
                    File file  = new File(path);
                    // 得到所有要下载的文件的文件名
                    String[] fileNames =  file.list();
                    // 保存
                    request.setAttribute("fileNames", fileNames);
                    return "list";
        }

    下载的download代码,类似于最原始的用commons-fileupload,特别注意中文要对get方式请求的fileName转码

    @RequestMapping("down")
        public String download(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception
        {
            fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
            File file = new File("E:\upload",fileName);
            if(file.exists())
            {
                BufferedInputStream bis = null;
                BufferedOutputStream bos = null;
                try {
                    response.reset();
                    request.setCharacterEncoding("UTF-8");
                    response.setContentType("application/x-msdownload;");
                    // 如果文件名是中文,需要进行url编码
                    fileName = URLEncoder.encode(fileName, "UTF-8");
                    response.setHeader("Content-disposition", "attachment; filename="
                                + fileName);
                    bis = new BufferedInputStream(new FileInputStream(file));
                    bos = new BufferedOutputStream(response.getOutputStream());
                    byte[] buff = new byte[2048];
                    int bytesRead;
                    while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                        bos.write(buff, 0, bytesRead);
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    LogUtil.logger.error("下载失败,出现问题");
                } finally {
                    if(bis!=null)
                    {
                        bis.close();
                    }
                    if(bos!=null)
                    {
                        bos.close();
                    }
                }
                
            }
            
            
            return null;
        }

    至此,struts2和springmvc的基本方式结束

  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/renboqie/p/5679127.html
Copyright © 2011-2022 走看看