验证中...
11月18日 珠海源创会报名倒计时,红薯约你一起来聊聊开源技术~
Struts2实现文件的上传与下载.md
原始数据 复制代码

Struts2实现文件的上传与下载

上传

第一步:静态展示页面

<h1>文件上传</h1>
<form action="/StrutsDay1/test/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="pic" ><br />
    <input type="submit" value="上传">
</form>

注意:

  • method="post",只有post支持二进制的传输方式,
  • 添加enctype属性,并且设置值为“multipart/form-data”,将表单数据以二进制流的形式发送到服务器
  • input type的类型为“file”

第二步:Action接收表单提交的数据,获取到提交的文件,并将获取的文件拷贝到服务器项目所在的目录下

public class FIleUploadAction {
	private File pic;
	private String picFileName;//自动获取文件名
	
	public String getPicFileName() {
		return picFileName;
	}
	public void setPicFileName(String picFileName) {
		this.picFileName = picFileName;
	}
	public File getPic() {
		return pic;
	}
	public void setPic(File pic) {
		this.pic = pic;
	}
	public String upload() throws IOException{
		//获得真实路径
		ServletContext sc = ServletActionContext.getServletContext();
		String realPath = sc.getRealPath("/picture");
		//输出文件(将文件拷贝到服务器中项目的目录)
        /*
        *其实就是一个文件拷贝的过程,https://gitee.com/sixiaojie/codes/3ouditmhkznlyjv0efcx731
        *这个链接介绍了通过IO实现的六种拷贝方式,我在这里选择了其中的一种
        */
		FileInputStream fis = new FileInputStream(pic);
		FileOutputStream fos = new FileOutputStream(realPath+"/"+picFileName);
		FileChannel channel1 = fis.getChannel();
		FileChannel channel2 = fos.getChannel();
		channel1.transferTo(0, channel1.size(), channel2);
		channel1.close();
		channel2.close();
        
		return "upload";
	}
}

第三步:在struts.xml中注册Action

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="test" extends="struts-default" namespace="/test">
	<!-- 文件上传 -->
	<action name="upload" class="demo1.FIleUploadAction" method="upload">
		<result name="upload" type="redirect">/index.jsp</result>
	</action>	
</package>
</struts>

现在其实就可以在页面选择文件,然后保存到服务器了,但是,目前的程序是存在很多问题的,还有很多需要优化的地方,下面开始优化!

优化文件上传程序

  • 上传的文件大小问题,Struts2默认接收上传文件的最大限度为2M;

    文件上传大小的上限是可以修改的,在Struts.xml文件中配置常量,标签为:

    默认的maxSize为2097152,是以字节为单位,也就是2M
    <constant name="struts.multipart.maxSize" value="100000000"></constant>
    
  • 文件名问题,用户上传文件的文件名可能在服务器端冲突,为了解决这个问题,可以使用UUID生成唯一的名字作为文件名,代码:

    UUID.randomUUID().toString();
    

    文件名设计为 UUID.后缀,后缀名可以通过接收到的picFileName问价名获取,获取方式:

    String name = UUID.randomUUID().toString()+picFileName.substring(picFileName.lastIndexOf('.'));
    
  • 文件保存路径问题,保存文件的目录写死在代码中,耦合,不便于维护,解决办法:保存目录名转移到struts.xml配置文件中,在原来基础上使用到一个param标签

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    	"http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
    <package name="test" extends="struts-default" namespace="/test">
    	<!-- 文件上传 -->
    	<action name="upload" class="demo1.FIleUploadAction" method="upload">
    		<param name="filePath">/picture</param>
             <result name="upload" type="redirect">/index.jsp</result>
    	</action>	
    </package>
    </struts>
    

    当浏览器请求name为upload的Action的时候,会自动将param中的值以请求参数的方式发送给Action,这样就可以在Action中接收到“filePath”的值为/picture,同样使用属性名的方式接收

  • 文件拷贝的代码简化,在搭建Struts2开发环境的时候,导入了一些jar包,其中有一个commons-io的jar包,这个jar包中封装拷贝文件的方法:

    FileUtils.copyFile(Pic, new File(picturePath));
    

    第一个参数为被拷贝的文件对象,第二个参数为拷贝之后的文件对象,picturePath为目标的文件的路径

那么优化之后的Action的文件为

public class FIleUploadAction {
	private File pic;
	private String picFileName;
	private String filePath;
	
	public String getFilePath() {
		return filePath;
	}
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	public String getPicFileName() {
		return picFileName;
	}
	public void setPicFileName(String picFileName) {
		this.picFileName = picFileName;
	}
	public File getPic() {
		return pic;
	}
	public void setPic(File pic) {
		this.pic = pic;
	}
    
	public String upload() throws IOException{
		//获得真实路径
		ServletContext sc = ServletActionContext.getServletContext();
		String realPath = sc.getRealPath(filePath);
		//文件名
		String fileName = UUID.randomUUID().toString()+picFileName.substring(picFileName.lastIndexOf('.'));
		//拷贝输出文件
		FileUtils.copyFile(pic, new File(realPath+"/"+fileName));
		return "upload";
	}
}

下载

当浏览器访问action的时候,action将文件发送到浏览器,供浏览器下载

文件下载相对较为简单,下面为action中的一个方法:

public void download() throws Exception {
		//以这个文件为例,为了演示所以直接给出了文件名
		String fileName = "cc21afb1-88f0-45e4-928e-bb0046aac045.jpg";
		//1. 设置下载信息以文件保存(filename指定文件名)
		//URLEncoder.encode(fileName, "UTF-8"),设置编码格式,否则中文不会显示
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
		// 1. 读入服务器端文件输入流
		// 路径
		String realPath = ServletActionContext.getServletContext().getRealPath(
				"/upload");
		String filePath = realPath + "/" + fileName;
		
		//2. 将服务器端要下载文件-----(拷贝到)----》响应输出流
		File srcFile = new File(filePath);
		ServletOutputStream os = response.getOutputStream();
		// 将srcFile文件读入,写出到os对应输出流中。
		// 3. 边读边写。
		FileUtils.copyFile(srcFile, os);
	}

只要浏览器访问该浏览器,浏览器就会将服务器端的文件通过响应输出流发送到浏览器,浏览器就会弹出一个下载框,提示下载该文件。

评论列表( 0 )

你可以在登录后,发表评论

搜索帮助

12_float_left_people 12_float_left_close