框架(一)struts2——文件上传与下载

本文介绍Struts2框架下文件的上传与下载实现方法,包括单个及批量文件上传的不同技术方案,并演示文件下载的基本流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


引言:

               一系列的知识研究,可以有助于构建你强大的知识网。

概述:           

              struts2也能实现简单的文件上传与下载,为什么说它能简单实现哪?因为项目中文件的上传和下载基本都与项目的业务逻辑所绑定,从功能和性能上,或许struts2不是很适用,但是作为一种实现方式,我们确可以了解一下。

内容:         

           一 单个文件的上传:                   

               1 实现原理:                 
                    (1):第一步,将上传流写入本地临时文件夹里,生成一个临时文件。
                    (2):第二步,临时文件对象封装到file对象里。
                    (3):第三步,通过fileupload拦截器将封装好的file对象注入到action中。                  
                注意:在这里我们并不关心前俩不,这个都是struts2框架为我们准备好的,关键是第三步需要我们自己配置的。             
               2 实现示例:                   
                  实现方法有三种:
                   (1)基础实现方式,新建文件流;
                   (2)通过FileUtils包里面的一个copy()方法;
                   (3)通过java中文件读写的封装类,BufferedReader和BufferedWriter。                  
               3 代码示例:                        

                   (1)业务逻辑层代码:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport{
	private File upload;           //要与jsp页面的控件命名一样。<input type="file" name="upload">
	
	private String uploadFileName;                 //获取文件名称,通过File可以获得临时文件的名称
	
	private String uploadContentType;              //获取文件类型
	
	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}


	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	@Override
	public String execute() throws Exception {
		File uploadFile =new File(ServletActionContext.getServletContext().getRealPath("upload"));
		
		if(!uploadFile.exists())
		{
			uploadFile.mkdir();           //创建一个文件
		}						
		//第一种基础写法
		//新建文件流
		/*InputStream input = new FileInputStream(upload);                            //输入流
		FileOutputStream out = new FileOutputStream(uploadFile + "\\" +uploadFileName); //输出流
		try{
			byte[] b = new byte[1024];     //字节数组,读多大的文件,1024为读1KB的数据
			int i = 0;                     //定义记录位置
			while((i = input.read(b))>0){
				out.write(b, 0, i);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//关闭输入输出流,不然占资源
			input.close();
			out.close();
		}*/
		
		//第二种:实现读写功能,利用FileUtils包下面的一个方法
		//FileUtils.copyFile(upload, new File(uploadFile + "\\" +uploadFileName));
		
		//第三种方法:struts上次文件默认大小为2M,可以在struts2种配置
		BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(upload)));
		BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(uploadFile + "\\" +uploadFileName)));
		
		try {
			char[] c = new char[1024];
			int i = 0;
			while((i = bReader.read(c)) >0){
				bWriter.write(c, 0, i);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			bReader.close();
			bWriter.close();
			upload.delete();
		}
		return "success";
	}

}
                          2)jsp页面代码:                            
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>单个文件上传</title>
</head>
<body>
	<!-- form的action为struts.xml中package的命名空间/action的名字。 -->
	<form action="file/upload" method="post" enctype="multipart/form-data">
		<input type="file" name="upload">
		<input type="submit" name="btnUpload" value="上传">
	</form>
</body>
</html>
                          3)sturts2配置文件:
<package name="upload" namespace="/file" extends="struts-default">
		<!-- 单文件上传,配置action -->
		<action name="upload" class="com.action.UploadAction">
			<result name="success">/success.jsp</result>
			<result name="error">/error.jsp</result>
			<result name="input">/index.jsp</result>
			<!-- 拦截器设置 -->
			<!-- <interceptor-ref name="fileUpload">
				<param name="maximumSize">1000000</param>
				<param name="allowedTypes"></param>
			</interceptor-ref>
			<interceptor-ref name="defaultStack"></interceptor-ref> -->
			<!-- 直接action设置 ,在相应的Action设置接收参数的变量-->
			<param name="maximumSize">1000000</param>
			<param name="allowedTypes"></param>
		</action>
</package><span style="font-size:18px;"><strong></strong></span><span style="font-size:18px;"><strong>              </strong></span><span style="font-size:18px;">                                </span>

             3 实现方法的联系与区别:

                                   (1)字符与字节:FileInputStream类操作的是二进制字节流,I/O速度快且效率高,但是它的read()方法读取到的是字节,不利于人们阅读,而且无法对文件中的字符进行操作,例如查找和替换;BufferedReader类弥补了这个缺陷,操作文本格式进行输入输出 ,可以对文本内容进行操作,例如:可以使用BufferedReader的readLine()方法一行一行读取文本。

                     (2)编码:BufferedReader进行文件的上传可能出现乱码,但是FileInputStream以二进制方式处理不会出现乱码。

                     (3)缓冲区:BufferedReader类用来包装所有其read()操作可能开销很高的Reader(如FileReader和InputStreamReader)

                     (4)第二种文件上传的方法,引用了文件工具FileUtils包下面的copyFile方法,相当于将已存在的文件copy了一份。

         二 批量文件上传:

                      1 实现原理:与单个上传文件一致。

                     2 代码实现:

                     (1)业务逻辑层代码:                            

package com.action;

import java.io.File;
import java.util.List;

public class UploadsAction  {
	//多个单文件上传
	private File[] upload;	
		
	private String[] uploadFileName;
		
	private String[] uploadContentType;
	
	public File[] getUpload() {
		return upload;
	}

	public void setUpload(File[] upload) {
		this.upload = upload;
	}

	public String[] getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String[] uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String[] getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String[] uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	
	/*//文件集合上传
	private List<File> upload;
	private List<String> uploadFileName;
	private List<String> uploadContentType;
	
		
	public List<File> getUpload() {
		return upload;
	}

	public void setUpload(List<File> upload) {
		this.upload = upload;
	}

	public List<String> getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(List<String> uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public List<String> getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(List<String> uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
*/
	public String execute() throws Exception{
		return "success";
	}
}
                      (2) JSP页面代码:                              
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>多文件上传</title>
</head>
<body>
	<!-- form的action为struts.xml中package的命名空间/action的名字。 -->
	<form action="file/uploads" method="post" enctype="multipart/form-data">
		<input type="file" name="upload"><br>
		<input type="file" name="upload"><br>
		<input type="file" name="upload"><br>
		<input type="file" name="upload"><br>		
		<input type="submit" name="btnUpload" value="上传">
	</form>
</body>
</html>
                     (3)sturts2配置代码:在package name="upload"里面。           
<!-- 多文件上传配置action -->
		<action name="uploads" class="com.action.UploadsAction">
			<result name="success">/success.jsp</result>
			<result name="error">/error.jsp</result>
		</action>

         三 文件下载:

                      1 实现原理:sturts2配置文件进行参数化传递,在result标签中进行(type=“stream”) 的设置即可。  

                      2 代码示例 :

                      (1)业务逻辑层代码:                             

package com.action;

import java.io.InputStream;

import org.apache.struts2.ServletActionContext;

public class DownLoadAction {

	private InputStream fileInput;
	
	private String fileName;  //页面的文件名称,以参数形式传递
	
	public InputStream getFileInput() {
		//第一种写法
		return ServletActionContext.getServletContext().getResourceAsStream("upload\\" + fileName);//文件名不一定是fileName,是服务器端的实际文件名称。
		//return fileInput;
	}

	public void setFileInput(InputStream fileInput) {
		this.fileInput = fileInput;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String execute() throws Exception{
		/*//第二种写法:
		fileInput =ServletActionContext.getServletContext().getResourceAsStream("upload\\" + fileName);//文件名不一定是fileName,是服务器端的实际文件名称。
*/		return "success";
	}
	
	
}
                      (2)JSP页面代码:                          
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件下载</title>
</head>
<body>
	<a href="file/download?fileName=123.txt">123.txt</a>
</body>
</html>
                      (3)struts2文件配置代码:                                 
<!-- 下载文件配置action -->
		<action name="download" class="com.action.DownLoadAction">
			<result name="success" type="stream">
				<param name="inputName">fileInput</param>
				<param name="contentDisposition">attachment;filename="${fileName}"</param>
			</result>
			<result name="error">/error.jsp</result>
		</action>

总结:

              sturts的核心知识点一个是拦截器,一个就是文件的上传与下载。但是文件的上传与下载还应该结合项目的业务逻辑要求,我们也可以不用sturts2封装的这些类,通过其他的方法实现文件的上传和下载。小编总结就到这里,请读者多多点评。


评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值