struts2 下进行文件的上传下载

今天在做文件的上传下载,虽然简单,但还是遇到狠多问题。在这记录一下。

1、先说文件的上传。前台jsp使用的是easyUI filebox来做控件,其实就是简单的一个input框。

<input class="easyui-filebox" name="file" 
data-options="prompt:'Choose a file...'" style="width: 100%">

然后放在一个表单里,提交表单。

2、后台,后台通过直接获取文件对象,文件名然后通过apache的jar包拷贝文件到指定目录,就可以了,但请注意,在这里将会遇到一个问题。
当我们通过getParameter(“file”);file为前端的name属性的值。获取一个
file对象,我们通过debug会发现,file的文件路径,文件名都与我们上传的文件有很大的区别,可以发现这个文件是一个临时文件,这就是说,我们不能使用file.getName()的方法获取文件名了,因为那不是真正的文件。

虽然上面的这个临时文件不影响我们上传,不过当我们上传要创建一个文件用于拷贝,所以需要用到文件类型,或者我们需要存储上传文件的文件名,这时就需要获取文件名了。使用file.getName(),很遗憾,这是错的,不要担心,我们可以直接getFileName(“file”);获取。

获取到文件名了,也有文件对象,直接使用File.copyFile(srcFIle,destFile)就解决了文件上传。
下满是代码片段:

创建一些工具类:
RequestUtils用于装载参数,这个例子,请看getFile,getFileName 的方法。
/*##########################################/
/*##########################################/
/*##########################################/

package com.ulwx.tool;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

public class RequestUtils
{
    private Map<String, Object[]> rParms = new HashMap<String, Object[]>();
    private Map<String, Object[]> objs = new HashMap<String, Object[]>();
    private static Logger log = Logger.getLogger(RequestUtils.class);

    public RequestUtils(Map requestParameters)
    {
        rParms = requestParameters;
    }

    public RequestUtils()
    {
        rParms = new HashMap<String, Object[]>();
    }

    public void setString(String name, String value)
    {
        rParms.put(name, new String[] { value });
    }

    public void setStrings(String name, String[] values)
    {
        rParms.put(name, values);
    }

    public Map<String, Object[]> getrParms()
    {

        return rParms;
    }

    public void setrParms(Map<String, Object[]> rParms)
    {
        this.rParms = rParms;
    }

    public void setInt(String name, Integer value)
    {
        rParms.put(name, new String[] { value + "" });
    }

    public void setFloat(String name, Float value)
    {
        rParms.put(name, new String[] { value + "" });
    }

    public void setDouble(String name, Double value)
    {
        rParms.put(name, new String[] { value + "" });
    }

    public void setObject(String name, Object value)
    {
        objs.put(name, new Object[] { value });
    }

    public void setObjects(String name, Object[] values)
    {
        objs.put(name, values);
    }

    public Object getObject(String name)
    {
        try
        {
            Object value = ArrayUtils.getFirst((Object[]) objs.get(name));
            if (value == null)
                return null;
            return value;
        } catch (Exception e)
        {
            return null;
        }
    }

    public Object[] getObjects(String name)
    {
        try
        {
            Object[] value = (Object[]) objs.get(name);
            return value;
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }
    }

    public String getString(String name)
    {
        try
        {
            String value = ArrayUtils.getFirst((String[]) rParms.get(name));
            if (value == null)
                return "";
            return value;
        } catch (Exception e)
        {
            return null;
        }
    }

    public File getFile(String name)
    {
        try
        {
            File value = ArrayUtils.getFirst((File[]) rParms.get(name));
            return value;
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }

    }

    public String getFileContentType(String name)
    {
        return this.getString(name + "ContentType");
    }

    public String[] getFileContentTypes(String name)
    {
        return this.getStrings(name + "ContentType");
    }

    public String getFileName(String name)
    {
        return this.getString(name + "FileName");
    }

    public String[] getFileNames(String name)
    {
        return this.getStrings(name + "FileName");
    }

    public File[] getFiles(String name)
    {
        try
        {
            return (File[]) rParms.get(name);
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }

    }

    public Integer getInt(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return Integer.parseInt(value);
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }
    }

    public Float getFloat(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return Float.parseFloat(value);
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }
    }

    public Double getDouble(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return Double.parseDouble(value);
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }
    }

    public Byte getByte(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return Byte.parseByte(value);
        } catch (Exception e)
        {
            // log.error("", e);
            // TODO Auto-generated catch block
            return null;
        }
    }

    public Boolean getBoolean(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return Boolean.valueOf(value);
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }

    }

    public String[] getStrings(String name)
    {
        try
        {
            String[] value = (String[]) rParms.get(name);
            return value;
        } catch (Exception e)
        {
            // log.error("", e);
            return null;
        }
    }

    public void setInts(String name, Integer[] values)
    {
        rParms.put(name, ArrayUtils.toStringArray(values));
    }

    public void setBoolean(String name, Boolean value)
    {
        rParms.put(name, new String[] { value + "" });
    }

    public void setBooleans(String name, Boolean[] values)
    {
        rParms.put(name, ArrayUtils.toStringArray(values));
    }

    public void setBytes(String name, Byte[] values)
    {
        rParms.put(name, ArrayUtils.toStringArray(values));
    }

    public void setByte(String name, Byte value)
    {
        rParms.put(name, new String[] { value + "" });
    }

    public Date getDayDate(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return CTime.parseDayDate(value);
        } catch (Exception e)
        {
            return null;
        }
    }

    public Date[] getDayDates(String name)
    {
        String[] value = (String[]) rParms.get(name);
        if (value == null)
            return null;
        Date[] res = new Date[value.length];
        for (int i = 0; i < value.length; i++)
        {
            try
            {
                res[i] = CTime.parseDayDate(value[i]);
            } catch (Exception e)
            {
                res[i] = null;
            }
        }

        return res;
    }

    public void setWholeDate(String name, Date value)
    {
        String str = CTime.formatWholeDate(value);

        rParms.put(name, new String[] { str });
    }

    public void setWholeDates(String name, Date[] values)
    {
        String[] strs = new String[values.length];
        for (int i = 0; i < strs.length; i++)
        {
            try
            {
                strs[i] = CTime.formatWholeDate(values[i]);
            } catch (Exception e)
            {
                strs[i] = null;
            }
        }
        rParms.put(name, strs);
    }

    public Date getWholeDate(String name)
    {
        String value = ArrayUtils.getFirst((String[]) rParms.get(name));
        if (value == null)
            return null;
        try
        {
            return CTime.parseWholeDate(value);
        } catch (Exception e)
        {
            return null;
        }
    }

    public Date[] getWholeDates(String name)
    {
        String[] value = (String[]) rParms.get(name);
        if (value == null)
            return null;
        Date[] res = new Date[value.length];
        for (int i = 0; i < value.length; i++)
        {
            try
            {
                res[i] = CTime.parseWholeDate(value[i]);
            } catch (Exception e)
            {
                res[i] = null;
            }
        }

        return res;
    }

    public Integer[] getInts(String name)
    {
        String[] value = (String[]) rParms.get(name);
        if (value == null)
            return null;
        Integer[] res = new Integer[value.length];
        for (int i = 0; i < value.length; i++)
        {
            try
            {
                res[i] = Integer.parseInt(value[i]);
            } catch (Exception e)
            {
                // TODO Auto-generated catch block
                // log.error("", e);
                res[i] = null;
            }
        }

        return res;
    }

    public Boolean[] getBooleans(String name)
    {
        String[] value = (String[]) rParms.get(name);
        if (value == null)
            return null;
        Boolean[] res = new Boolean[value.length];
        for (int i = 0; i < value.length; i++)
        {
            try
            {
                res[i] = Boolean.valueOf(value[i]);
            } catch (Exception e)
            {
                // TODO Auto-generated catch block
                res[i] = null;
            }
        }

        return res;
    }

    public Byte[] getBytes(String name)
    {
        String[] value = (String[]) rParms.get(name);
        if (value == null)
            return null;
        Byte[] res = new Byte[value.length];
        for (int i = 0; i < value.length; i++)
        {
            try
            {
                res[i] = Byte.parseByte(value[i]);
            } catch (Exception e)
            {
                // TODO Auto-generated catch block
                res[i] = null;
            }
        }

        return res;
    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub

        RequestUtils ru = new RequestUtils();
        ru.setBooleans("sss", new Boolean[] { true, false });
        System.out.println(ArrayUtils.toJsonString(ru.getBooleans("sss")));

    }

}

/*############################################/
/*############################################/
/*############################################/
在baseAction 中加入这一段

/**
     * 从请求中取出参数,又将参数放回请求中
     * 
     * @param ctx
     * @return
     */
    @SuppressWarnings("rawtypes")
    public RequestUtils getRequestUtils() {
        ActionContext ctx = ActionContext.getContext();

        Map<String, Object> rParms = ctx.getParameters();
        RequestUtils ru = new RequestUtils((Map)rParms);
        return ru;
    }

/*############################################/
/*############################################/
/*############################################/
在action中加入代码片段

public String upload()
    {
        ActionContext ctx = ActionContext.getContext();
        RequestUtils ru = this.getRequestUtils();
        File[] files = ru.getFiles("file"); //根据文件参数获取文件
        String[] fileNames = ru.getFileNames("fileName"); //根据文件参数获取文件名
        String[] result = null;
        try
        {
            if (files != null && files.length > 0)
            {
                result = FileUtil.uploadFiles(files, fileNames); //上传文件
            }
            logger.info("上传文件完成!!");
            ctx.put("json", "ok");
        }
        catch (Exception e)
        {
            logger.error("上传文件失败!!" + e);
            ctx.put("json", "error");
        }
        return "json";
    }

/*############################################/
/*############################################/
/*############################################/
上传文件的代码,这里是整个工具类FileUtil,上传只需要看uploadFile方法,GlobalConfig是用于都配置文件的,你也可以自己写一个类用于读配置文件,然后将该类放到监听器中,也可以直接将配置文件在web.xml中配置,然后通过上下文获取配置信息。

package com.ulwxbase.web.action.file;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import com.ulwxbase.utils.DateUtil;
import com.ulwxbase.utils.EmptyUtils;
import com.ulwxbase.utils.GlobalConfig;

/**
* @author lizq E-mail: 825332548@qq.com
* @version 创建时间:2016年7月11日 下午3:23:22
*
* The class is use for ...
*/

public class FileUtil
{
    private static final Logger logger = Logger.getLogger(FileUtil.class);
    private final static String FILE_UPLOAD_PATH =   GlobalConfig.getRealPathProperty("config", "file.upload.path",
            "D:testUploadFile/webapps/ROOT/upload");

    /**
     * 上传单个文件
     * @param file 需要上传的文件
     * @return 返回上传文件后的路径
     */
    public static String uploadFile(File file)
    {
        String destFilePath = null; //上传文件的路径
        if (file != null)
        {
            String fileName = file.getName(); //获取文件名
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); //获取文件类型

            logger.info("文件名:" + fileName);
            logger.info("文件类型:" + fileType);

            File dir = new File(createFilePath(fileType)); //构造文件目录
            if (!dir.exists()) //不存在文件目录,创建目录
            {
                dir.mkdirs();
            }

            // 构造上传文件的路径
            destFilePath = createFilePath(fileType) + File.separator + createFileName() + "." + fileType;

            logger.info("上传文件路径:" + destFilePath);
            copyFile(file, new File(destFilePath)); //将原文件复制到目标文件
        }

        return destFilePath; //返回上传文件的路径
    }

    /**
     *  单文件上传,此方法需要文件名,主要用于struts文件上传,struts会将文件放到一个临时存储文件的tmp中,
     * 所以不能使用file.getName();方法获取文件名,但struts会把文件名作为参数。
     * @param file 文件对象
     * @param fileName 文件名
     * @return 上传的文件路径
     */
    public static String uploadFile(File file, String fileName)
    {
        String destFilePath = null; //上传文件的路径
        if (file != null && !EmptyUtils.isEmptyString(fileName))
        {
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); //获取文件类型

            logger.info("文件名:" + fileName);
            logger.info("文件类型:" + fileType);

            File dir = new File(createFilePath(fileType)); //构造文件目录
            if (!dir.exists()) //不存在文件目录,创建目录
            {
                dir.mkdirs();
            }

            // 构造上传文件的路径
            destFilePath = createFilePath(fileType) + File.separator + createFileName() + "." + fileType;

            logger.info("上传文件路径:" + destFilePath);
            copyFile(file, new File(destFilePath)); //将原文件复制到目标文件
        }

        return destFilePath; //返回上传文件的路径
    }

    /** 
     *  多个文件上传,此方法需要文件名,主要用于struts文件上传,struts会将文件放到一个临时存储文件的tmp中,
     * 所以不能使用file.getName();方法获取文件名,但struts会把文件名作为参数。
     * @param files  文件对象数组
     * @param fileNames 文件名数组
     * @return 文件上传的路径数组
     */
    public static String[] uploadFiles(File[] files, String[] fileNames)
    {
        String filePath[] = new String[fileNames.length];
        for (int i = 0; i < files.length; i++)
        {
            filePath[i] = uploadFile(files[i], fileNames[i]);
        }

        return filePath;
    }

    /**
     * 下载文件
     * @param srcPath 需要下载的文件的路径
     * @param fileName 下载文件的文件名
     * @param response 响应对象,用于设置文件的响应头
     * @throws Exception 
     */

    /**
     * 下载文件
     * @param srcPath   需要下载的文件的路径
     * @param fileName  下载文件的文件名
     * @param response  响应对象,用于设置文件的响应头
     * @return Boolean 下载文件失败,return false ,otherwise true
     */
    public static Boolean downloadFile(String srcPath, String fileName, HttpServletResponse response)
    {
        logger.debug("下载文件开始。。。");
        logger.info("下载文件路径:" + srcPath + " " + "下载文件名:" + fileName);

        OutputStream out = null;
        try (BufferedInputStream bufferStream = new BufferedInputStream(new FileInputStream(srcPath)))
        {
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + new String(fileName.getBytes("UTF-8"), "ISO8859-1"));

            out = response.getOutputStream();
            copy(bufferStream, response.getOutputStream());
            closeQuietly(bufferStream);
            logger.debug("下载文件结束。。。");
        }
        catch (Exception e)
        {
            logger.error("下载文件出现异常", e);
            return false;
        }
        finally
        {
            try
            {
                out.flush();
                out.close();
            }
            catch (IOException e)
            {
            }
        }

        return true;
    }

    /**
     * 下载文件
     * @param file 需要下载的文件对象
     * @param response 响应对象,用于设置文件的响应头
     */
    public static void downloadFile(File file, String fileName, HttpServletResponse response)
    {
        if (file != null)
        {
            InputStream in = null;
            OutputStream os = null;
            try
            {
                os = response.getOutputStream();
                response.setContentType("application/x-download; charset=utf-8");
                response.setHeader("Content-disposition",
                        "attachment; filename=" + new String(fileName.getBytes("UTF-8"), "ISO8859-1"));
                in = new BufferedInputStream(new FileInputStream(file));
                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = in.read(buffer, 0, 8192)) != -1)
                {
                    os.write(buffer, 0, bytesRead);
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                if (os != null)
                {
                    try
                    {
                        os.close();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
                if (in != null)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
                in = null;
            }
        }
    }

    /**
     * 复制文件
     * @param srcFile 原文件
     * @param destFile 目标文件
     */
    public static void copyFile(File srcFile, File destFile)
    {
        try
        {
            FileUtils.copyFile(srcFile, destFile);
        }
        catch (IOException e)
        {
            logger.error("复制文件失败!!", e);
        }
    }

    /**
     * 复制输入输出流,将输入流写到输出流
     * @param input 输入流
     * @param output 输出流
     * @return
     * @throws IOException
     */
    private static int copy(InputStream input, OutputStream output) throws IOException
    {
        return IOUtils.copy(input, output);
    }

    /**
     * 关闭流
     * @param input
     */
    private static void closeQuietly(InputStream input)
    {
        IOUtils.closeQuietly(input);
    }

    /**
     * 构造上传文件的目录
     * @param FileType 文件类型
     * @return 文件目录路径
     */
    public static String createFilePath(String FileType)
    {
        return FILE_UPLOAD_PATH + File.separator + FileType + File.separator
                + DateUtil.formatDate("yyyy-MM-dd", new Date());
    }

    /**
     * 构造文件名,使用的是UUID来作为文件名
     * @return UUID字符串
     */
    public static String createFileName()
    {
        return UUID.randomUUID().toString();
    }
}

上传文件结束,基本的代码都已经贴出来了,主要就是要知道struts上传的文件会放到临时目录中,获取文件对象和获取文件名都可以直接获取。
/*##########################################/
/*##########################################/
/*##########################################/

上传完成,下面就是下载,下载也遇到一个问题,就是
getOutputStream() has already been called for this response
异常,这是问题是在释放在jsp中使用的对象,调用response.getWriter(),因为这个方法是和response.getOutputStream()相冲突的!所以出错。
网上很多例子都是什么out.clear();out = pageContext.pushBody();解决。
但是其实很多时候我们都是在后台做下载,然后返回到jsp,根本就是out。
怎么解决昵?我们在做下载的时候,经常都是表单提交下载文件路径和文件名,根本就不需要返回到jsp的,所以我们在action中return的时候不让他返回到jsp,直接return null;这样就可以解决了。
当然还有一种解决方式,就是在jsp页面调用下载文件的方法。例如我上面的fileUtil的下载文件方法。然后我在action中返回一个jsp页面

public String download()
{
    RequestUtils ru = this.getRequestUtils();
    String srcPath = ru.getString("srcPath");
    String fileName = ru.getString("fileName");
    if (!EmptyUtils.isEmptyString(srcPath) && !EmptyUtils.isEmptyString(fileName))
    {
        FileUtilProxy.download(new File(srcPath), fileName);
    }
    return this.DOWNLOAD;
}

/*##########################################/
/*##########################################/
/*##########################################/
jsp的代码

<%@page import="com.ulwxbase.utils.MyConstants"%>
<%@page import="java.io.File"%>
<%@page import="com.ulwxbase.web.action.file.FileUtil"%>
<%@ page language="java" pageEncoding="UTF-8"%>
<%
    File file = (File) request.getAttribute(MyConstants.Action.URL_DOWNLOAD);
    String fileName = (String) request.getAttribute("fileName");
    FileUtil.download(file, fileName);
%>

这样也是可以解决这个getOutputStream()异常的。

下载也到这完成。
/*##########################################/
/*##########################################/
/*##########################################/

小结:其实上传下载很简单,但是要注意几个问题:
1、上传要注意临时文件的问题,文件名和文件对象可以直接get出来。
2、下载要注意getOutputStream()问题,我们在做下载的时候一是直接return null可以解决,另一种方式是返回到jsp页面去做,也不会出现异常,还是一种就是网上很多帖子的out.clear();out = pageContext.pushBody();解决。这一种我们试过,所以不知道效果如何。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值