`
xwood
  • 浏览: 100156 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Struts1 与 Struts2多文件上传的比较

阅读更多
STRUTS 1 部分

STRUTS 1 的文件上传定义了专门的文件处理接口FormFile。查看源码才知道,FormFile与File完全不是一回事,所以想将FormFile转为File再处理就行不通了。

第一次写上传时,我使用了common-upload组件进行文件上传,后来发现STRUTS在request中根本读不到文件。后来查了一些资料才发现Struts在Action处理逻辑之前已经对request中的表单数据进行了wrap。所以就只能老老实实的按STRUTS自己的文件上传方法写了。

多文件上传与单个文件上传有些不太一样,单文件上传只需要在Form类中给一个FormFile类型的属性,就能接受到页面提交的文件数据。多文件上传时,STRUTS在页面端将多个文件wrap成了一个数组,转给From类时又wrap成了List。所以我们在页面上使用数组形式对文件进行提交,在Form类中用List对文件进行接收。以下是相关的代码:

1.jsp页面代码

<html:file property = "uploadFile[0].file"/>
<html:file property = "uploadFile[1].file"/>


2.Form代码
public class AccuseForm extends ActionForm {
	private List evidences;

        public AccuseForm(){
		evidences = new ArrayList();
		evidences.add(new UploadFile());
	}

        public UploadFile getUploadFile(int index){
		int size = evidences.size();
		if(index > size - 1){
			for(int i = 0; i < index - size + 1; i++){
				evidences.add(new UploadFile());
			}
		}
		return (UploadFile)evidences.get(index);
	}
	
	public List getEvidences() {
		return evidences;
	}

	public void setEvidences(List evidence) {
		this.evidences = evidence;
	}
}
public class UploadFile implements Serializable {
	private FormFile file;
	private String newName;
	public FormFile getFile(){
			//System.out.println("run in uploadFile.getFile()");
		return this.file;
	}
	public void setFile(FormFile file){
		this.file = file;
	}
		
}


3.Action处理代码

public class AccuseAction extends DispatchAction {
        public  ActionForward save(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response){
		
		AccuseForm f = (AccuseForm)form;
                List evidences = f.getEvidences();
                try{
        	String dir = Constants._UPLOAD_DIR;
        	File fDir = new File(dir);
        	if(!fDir.exists())
        		fDir.mkdirs();
            for(int i = 0; i < evidences.size(); i++){
                UploadFile uploadFile = (UploadFile)evidences.get(i);
                uploadFile = renameFile(uploadFile);
                if(uploadFile.getFile() == null){
                    System.out.println("file is null");
                    break;
                }else{ 
                	//System.out.println("filename:::" + file.getFileName());
                    //System.out.println("file size:::" + file.getFileSize());
                	//System.out.println(dir);
                	uploadFile(uploadFile, dir);
                }
            } 
    
        }catch(Exception e){
            e.printStackTrace();
        }
         
        private void uploadFile(UploadFile file, String dir) throws                   FileNotFoundException, IOException{
		InputStream in = file.getFile().getInputStream();
    	OutputStream out = new BufferedOutputStream(
    								new FileOutputStream(
    										dir + file.getNewName()
    										));
    	final int _BUFFERSIZE = 8192;
    	int bytesRead = 0;
    	byte[] buffer = new byte[_BUFFERSIZE];
    	while((bytesRead = in.read(buffer, 0, _BUFFERSIZE)) != -1){
    		out.write(buffer, 0, bytesRead);
    	}
    	
    	out.flush();
    	out.close();
    	in.close();
	}
}



注意,因为我在页面中使用的数组为uploadFile[],所以在Form类中添加了getUploadFile(int index)。因为<html:file/>标签上传的文件在STRUTS中都是由FormFile类接收处理的,所以,在页面中我们使用uploadFile[i].file,它表示的是UploadFile类的file属性,即一个FormFile类对象。

如果,在上传文件中,我们需要对文件进行改名,那么FormFile.setFileName()是用不了的。这个具体为什么我也没有研究,不过我们可以直接将OutputStream输出文件的名字重新换一个就可以了。


STRUTS 2 部分

struts2经过struts1的改进,或者说webwork本身在这方面的功能就比较强大(webwork具体我没怎么研究过),在使用方法上进步了很多,只须以下三步便可以实现多文件的上传。

1.实现action类,使用数组进行存储。需要提供contentType及fileName属性存储相关属性值。
package org.xwood.struts.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.struts2.ServletActionContext;

public class DemoAction{

	private String title;
    private File[] upload;
    private String[] uploadContentType;
    private String[] uploadFileName;
    
    /*
	//接受依赖注入的属性
    private String savePath;
	//接受依赖注入的方法
    public void setSavePath(String value)
	{
        this.savePath = value;
    }
    */
    
    private String getSavePath() throws Exception 
	{
        return ServletActionContext.getServletContext().getRealPath("upload");
    }
	
	public void setTitle(String title) {
		this.title = title; 
	}
	public void setUpload(File[] upload) {
		this.upload = upload; 
	}
	public void setUploadContentType(String[] uploadContentType) {
		this.uploadContentType = uploadContentType; 
	}
	public void setUploadFileName(String[] uploadFileName) {
		this.uploadFileName = uploadFileName; 
	}
	public String getTitle() {
		return (this.title); 
	}
	public File[] getUpload() {
		return (this.upload); 
	}
	public String[] getUploadContentType() {
		return (this.uploadContentType); 
	}
	public String[] getUploadFileName() {
		return (this.uploadFileName); 
	}


	
    public String upload() throws Exception
	{
		File[] files = getUpload();
		String path = getSavePath();
		for (int i = 0 ; i < files.length ; i++)
		{
			//以服务器的文件保存地址和原文件名建立上传文件输出流
			FileOutputStream fos = new FileOutputStream(path + File.separator + getUploadFileName()[i]);
			FileInputStream fis = new FileInputStream(files[i]);
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = fis.read(buffer)) > 0)
			{
				fos.write(buffer , 0 , len);
			}

	         fos.close();// 注意:流应当关闭。
	         fis.close();
		}
        return "success";
	}
}


2.配置action,设置拦截器
<action name = "demo_*" 
	class = "org.xwood.struts.action.DemoAction"
	method = "{1}">
	<result name="success" type="dispatcher">/success.jsp</result>
	<result name="input">index.jsp</result>
	<interceptor-ref name="fileUpload">
		<param name="maximumSize">20000</param>  
		<param name ="allowedTypes"> 
			*
		</param> 
	</interceptor-ref>
	<interceptor-ref name="defaultStack"></interceptor-ref>
</action>


3.配置jsp页面,使用表单上传

注:servlet 2.4之前的版本还得在web.xml中配置clean-up。
<filter>
	<filter-name>struts-cleanup</filter-name>
	<filter-class>
		org.apache.struts2.dispatcher.ActionContextCleanUp
	</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts-cleanup</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics