十三、Struts2实现文件下载

编写Action类

package blog.csdn.net.mchenys.action;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

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

import com.googlecode.sslplugin.annotation.Secured;
import com.opensymphony.xwork2.ModelDriven;

import blog.csdn.net.mchenys.domain.User;
import blog.csdn.net.mchenys.utils.UploadUtils;


public class TestAction extends ActionSupport{

	private static final long serialVersionUID = 1L;
	
	// 文件下载
	private String fileName;// 文件名称
	private String downloadPath;//文件下载路径

	//属性驱动方式注入值
	public void setFileName(String fileName) {
		System.out.println("===setFileName==="+fileName);
		this.fileName = fileName;
	}

	/**
	 * 返回文件名,对应struts.mlx中的<param name="contentDisposition">中的filename=${fileName}
	 * @return
	 */
	public String getFileName() {
		System.out.println("===getFileName==="+fileName);
		return fileName;
	}

	/**
	 * 返回InputStream,对应struts.mlx中的<param name="inputName">inputStream</param>
	 *
	 * @return
	 */
	public InputStream getInputStream() {
		System.out.println("====getInputStream====");
		try {
			//转换格式,否则输出的文件名有中文时,浏览器不会显示
			this.fileName=new String(fileName.getBytes(),"iso-8859-1");
			//返回文件下载流
			return new FileInputStream(new File(downloadPath));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 文件下载
	 * 
	 * @return
	 */
	public String download() {
		System.out.println("====download====");
		// 获取绝对路径
		this.downloadPath = ServletActionContext.getServletContext().getRealPath("/download/"+fileName);
		System.out.println("downloadPath:"+downloadPath);
		/*try {
			// 解决下载的文件名是中文的文件获取文件名时乱码问题,如果已经配置过编码拦截器的可以不需要处理
			this.downloadPath = new String(downloadPath.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}*/
		return "downloadOK";
	}

}

编辑struts.xml文件

<?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">

		<interceptors>
			<interceptor name="encoding"
				class="blog.csdn.net.mchenys.intercept.EncodingIntereptor" />
			<!-- 定义拦截器栈 -->
			<interceptor-stack name="myStack">
				<!-- 引入自定义的拦截器 -->
				<interceptor-ref name="encoding" />
				<!-- 引入默认的拦截器 -->
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>

		<action name="*" class="blog.csdn.net.mchenys.action.TestAction" method="{1}">
			<!-- 引入拦截器栈 -->
			<interceptor-ref name="myStack" />

			<!-- 文件下载 -->
			<!-- result类型是流(stream)类型 -->
			<result name="downloadOK" type="stream">
				<!-- inputName指向被下载文件的来源,对应Action中返回的InputStream -->
				<param name="inputName">inputStream</param>
				<!-- 指定文件下载的处理方式,内联(inline)和附件(attachment)两种方式,attachment会弹出文件保存对话框 -->
				<param name="contentDisposition">attachment;filename=${fileName}</param>
				<!--指定下载文件的缓冲大小 -->
				<param name="bufferSize">4096</param>
			</result>

		</action>
	</package>

</struts>

编写请求参数编码拦截器

这里我直接使用的是上一篇文章的拦截器,详情

编写下载链接

<%@ 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>Insert title here</title>

<style type="text/css">
	h1{font-size: 30px;}
</style>

<script type="text/javascript">
	
</script>
</head>
<body>

<h1><a href="${pageContext.request.contextPath }/test/download?fileName=我看好你哦.jpg">我看好你哦.jpg</a></h1>
<h1><a href="${pageContext.request.contextPath }/test/download?fileName=c.mp4">c.mp4</a></h1>
</body>
</html>

添加下载资源

在这里插入图片描述

测试

在这里插入图片描述
在这里插入图片描述
鼠标移动到链接上,可以看到完整的下载路径,点击下载后,也能正确的显示下载的文件名
在这里插入图片描述
查看控制台输出的内容,可以看出Action中那几个方法的调用顺序
在这里插入图片描述
可以看到setFileName是最先执行的,因为请求参数注入fileName的时候会调用,然后是调用download方法,该方法是action的方法是必定执行的,接着是getInputStream方法获取文件读取流,也就是需要下载的文件,最后是getFileName,这个是文件下载后显示的名称,细心的你会发现中文显示了乱码,这个是因为getInputStream方法中我对文件名进行了编码,如果不这样处理的话,浏览器下载文件名显示不了中文,至于控制台输出是乱码,那是因为我的web项目的编码是utf-8的格式。

搞定~~

补充一点,如果要返回contentLength给客户端,可以在Action中添加多一个方法

private String contentLength;//文件下载的长度
	
/**
 * 返回文件的长度,对应struts.xml中的<param name="contentLength">contentLength</param>
 * @return
 */
public String getContentLength() {
	System.out.println("===getContentLength==="+contentLength);
	return contentLength;
}

修改download方法,设置文件长度

/**
 * 文件下载
 * 
 * @return
 */
public String download() {
	System.out.println("====download====");
	// 获取绝对路径
	this.downloadPath = ServletActionContext.getServletContext().getRealPath("/download/"+fileName);
	//指定文件长度
	this.contentLength = String.valueOf(new File(downloadPath).length());
	System.out.println("downloadPath:"+downloadPath);
	/*try {
		// 解决下载的文件名是中文的文件获取文件名时乱码问题,如果已经配置过编码拦截器的可以不需要处理
		this.downloadPath = new String(downloadPath.getBytes("ISO-8859-1"), "UTF-8");
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	}*/
	return "downloadOK";
}

修改struts.xml,在<result name="downloadOK" type="stream"></result>内指定文件长度

<param name="contentLength">contentLength</param>

这样,客户端就可以拿到contentLength,如下所示:
在这里插入图片描述
附上控制台输出log
在这里插入图片描述
可见getContentLength是优先getInputStream方法执行的.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值