struts2环境下的文件上传

背景:
文件上传有许多方式可以做到,并不困难,本文仅仅记录struts2框架的文件上传的使用。

前台html:

<!--//重点1:enctype="multipart/form-data" 最好单独做一个表单提交文件。-->
<form id="form1" enctype="multipart/form-data" action="upload!fileUpload.action" method="post">
<!--//重点2:post提交,submit表单。-->
<table cellspacing="0" cellpadding="0" width="100%" id="tab">
    <tbody>
    <tr>                                     
            <th width="30%">
                导入文件:
            </th>
            <td width="50%">                 
                <input style="width:175px;" type="file" name="upFile" id="file" value=""/>
            </td>
            <td width="20%">
                <!--//重点3:name属性要与后台Action的File属性一致。struts2在上传文件时就绑定了File的一些属性,此处在getFile里上传了文件-->
                <input type="button" onclick="getFile();" value="解析" style="margin-left:10px;margin-right:3px;width:40px;overflow:visible;">
            </td>
    </tr>
    </tbody>
</table>
</form>

补充:表单的encType属性:

application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。
multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
常用有两 种:
application/x-www-form-urlencoded和multipart/form-data,默认为application /x-www-form-urlencoded。 当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1& amp;name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url。 当action为post时候,浏览器把form数据封装到http body中,然后发送到server。
如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上 Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件 name)等信息,并加上分割符(boundary)。

$('#form1').ajaxSubmit({                   
//有关 ajaxSubmit 请参考 http://www.cnblogs.com/xiaosama/p/4747848.html 以及百度 
  success:function(date){                  
  //提交整个表单,文件会以二进制作为multidate形式上传。
  if(date=="success"){                      
     geneTableSelect();
  }
}});

这样,就通过表单的action找到struts2相应的处理类,这里 upload!fileUpload.action 对应自己项目的处理类。
文件到达struts2,需要配置(以下配置可二选一):
struts.properies

struts.properies:存放上传文件的临时地址。上传最终是从这个地址里的.tmp文件开始的。
struts.multipart.saveDir=/tmp
...

struts-action.xml

这里配置一些拦截属性,比如文件类型的限制,临时文件保存路径,文件大小的限制等等
<constant name="struts.multipart.saveDir" value="/tmp"></constant>
<constant name="struts.multipart.maxSize" value="1024102400"></constant>
<action name="upload" class="com.tom.hss.bss.action.UploadAction">
</action>

action内部的具体代码:处理文件

//必须的参数,参数名与表单file空间的name属性相同,如果一个表单名对应多个上传文件,
//则必须为数组或List
private File upFile;
//必须的参数,格式:表单file控件的name属性+ContentType,表示上传文件类型
private String upFileContentType;
//必须的参数,格式:表单file控件的name属性+FileName,表示上传的文件名
private String upFileFileName;
get/set......
//核心是copyFile方法,其他的是我自己的业务逻辑,不必在意。
public String fileUpload() throws IOException {
        String type = ServletActionContext.getRequest().getParameter("type");
        String temp_path=ServletActionContext.getServletContext().getRealPath("/upload");
        String bss_path=ServletActionContext.getServletContext().getRealPath("/tmp");
        String realpath = type.equals("")?temp_path:bss_path;
        if (upFile != null) {
            File savefile = new File(new File(realpath), upFileFileName);
            System.out.println(realpath+File.separator+savefile.getName());
            FileUtils.copyFile(upFile, savefile);
        this.setSession(type.equals("")?"upload":type+"tmp",realpath+File.separator+savefile.getName());
            System.out.println(savefile.getName());
            ActionContext.getContext().put("message", "文件上传成功");
            System.out.println("-"+type+"-");
            PrintWriter writer = null;
            writer=getResponse().getWriter();
            writer.write("success");
        }
        return null;
    }

copyFile是commons-io包下的方法:内部 实现如下:

private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
        if(destFile.exists() && destFile.isDirectory()) {
            throw new IOException("Destination \'" + destFile + "\' exists but is a directory");
        } else {
            FileInputStream input = new FileInputStream(srcFile);
            try {
                FileOutputStream output = new FileOutputStream(destFile);
                try {
                    IOUtils.copy(input, output);
                } finally {
                    IOUtils.closeQuietly(output);
                }
            } finally {
                IOUtils.closeQuietly(input);
            }
            if(srcFile.length() != destFile.length()) {
                throw new IOException("Failed to copy full contents from \'" + srcFile + "\' to \'" + destFile + "\'");
            } else {
                if(preserveFileDate) {
                    destFile.setLastModified(srcFile.lastModified());
                }
            }
        }
    }

copy内部:

public static long copyLarge(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[4096];
        long count = 0L;
        int n1;
        for(boolean n = false; -1 != (n1 = input.read(buffer)); count += (long)n1) {
            output.write(buffer, 0, n1);
        }
        return count;
    }

由此可见,这里的copyfile本质上获得上传文件的输入,最后写到目标文件里。
struts2去年爆出了s2-032漏洞,安全性备受质疑,而且struts2也显得太重了,所以现在使用越来越少,之后会介绍springMVC下的文件上传!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值