利用Struts2来处理文件的下载的问题时,能够解决下载文件的文件名为中英文等,都不出现乱码。此外,还能够在用户下载之前进行检查,判断用户是否有足够的权限来下载该文件等。下面用一个示例来讲解文件的下载:
注意:在处理文件时候尽量不使用特殊字符,路径和文件夹使用英文,文件名可以使用中文、空格、括号,不使用+、¥、%等特殊字符,这个在文件的上传(源头)时候就进行限制,避免在代码中进行处理这些特殊字符
(1) 先写一个下载页面:(index.jsp)
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
下载页面
1.Struts2多文件文件下载(超链接中有固定的文件名,后台指定路径)
请下载中文课件:
中
请下载英文课件:
英
在该页面中对文件名进行了编码,避免IE中文乱码,在后台解码即可得到相应参数
(2)在Struts2框架文件下载Action类中,需要提供一个返回InputStream流方法,该输入流代表了被下载文件的入口。该Action类代码如下所示:(DownLoadAction.java)
package cn.tedu.action;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.tedu.util.MyUtil;
import cn.tedu.web.BaseAction;
@Controller
@Scope("prototype")
public class DownLoadAction extends BaseAction{
private String downPath; // 下载时的文件名
private String contentType; // 保存文件类型
private String filename; // 保存时的文件名
public String getDownPath() {
return downPath;
}
//做了些细微调整
public void setDownPath(String downPath) {
this.downPath = downPath;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
//提供struts配置文件使用
private InputStream inputStream;
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
//下载时候调用
public String downloadFile() throws UnsupportedEncodingException{
// 下载保存时的文件名和被下载的文件名一样
downPath = java.net.URLDecoder.decode(downPath,"UTF-8");
filename = downPath;
// 下载的文件路径,请在webapps目录下创建download目录,并预先放置好两个文件备用
downPath = "download/" + downPath;
System.out.println("downPath:"+downPath);
System.out.println("filename:"+filename);
inputStream = ServletActionContext.getServletContext().getResourceAsStream(downPath);
System.out.println(inputStream);//若传过来的参数乱码,则inputStream为null
// 保存文件的类型
contentType = "application/x-msdownload";
//对下载的文件名按照UTF-8进行编码,解决下载窗口中的中文乱码问题
filename = MyUtil.toUTF8String(filename);
System.out.println(filename);
System.out.println("=============结束============");
return SUCCESS;
}
}
(3) 在上述的Action类中定义了一个工具类MyUtil,该类中有一个静态方法toUTF8String实现对下载的文件名按照UTF-8进行编码,解决下载窗口中中文乱码的问题:(MyUtil.java)
package cn.tedu.util;
import java.io.UnsupportedEncodingException;
public class MyUtil {
// 对下载文件按照 UTF-8 进行编码
public static String toUTF8String(String str){
StringBuffer sb = new StringBuffer();
int len = str.length();
for (int i = 0; i < len; i++)
{
// 取出字符中的每个字符
char c = str.charAt(i);
// Unicode码值在0~255之间,不做处理
if(c>=0 && c <= 255){
sb.append(c);
}else {
// 转换 UTF-8 编码
byte b[];
try{
b = Character.toString(c).getBytes("UTF-8");
}catch(UnsupportedEncodingException e){
e.printStackTrace();
b = null;
}
// 转换为%HH的字符串形式
for(int j = 0;j < b.length ; j++){
int k = b[j];
if(k < 0){
k &= 255;
}
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}
(4) 最后,完成Action的配置,关键是要配置一个类型为stream的结果,配置时需要指定如下四个属性:
struts.xml如下:
/index.jsp
${contentType}
inputStream
attachment;filename=${filename}
4096
总结:以上代码在谷歌和IE中均测试通过,兼容浏览器
在实际中,可能是在某路径的文件夹下,将该文件夹下的文件以列表显示,单击下载,与上述多文件下载类似,代码在之前上添加即可,代码改动如下:
index.jsp页面:
<%@page import="java.net.URLEncoder"%>
<%@ page import="cn.tedu.util.MyUtil"%>
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
下载页面(在入口处限制文件名中不能含有特殊字符例如“+”号)
<%
String tomcatPath = MyUtil.getTomcatPath(request);
tomcatPath = URLEncoder.encode(tomcatPath, "UTF-8");//先编码
//System.out.println(tomcatPath);//E:\apache-tomcat-7.0.81\down
%>
1.Struts2多文件文件下载(超链接中有固定的文件名,后台指定路径)
请下载中文课件:
中
请下载英文课件:
英
2.Struts2多文件文件下载(列表显示可下载文件)
文件名
操作
点击下载时候发送GET请求,将路径和文件名都进行了编码,后台中分别进行解码
struts.xml文件添加如下代码:
text/html
${contentType}
inputStream
attachment;filename=${fileName}
4096
Action控制器如下:
package cn.tedu.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.tedu.util.MyUtil;
import cn.tedu.web.BaseAction;
@Controller
@Scope("prototype")
public class DownLoadAction extends BaseAction{
private String downPath; // 下载时的文件名
private String contentType; // 保存文件类型
private String filename; // 保存时的文件名
public String getDownPath() {
return downPath;
}
//做了些细微调整
public void setDownPath(String downPath) {
this.downPath = downPath;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
//提供struts配置文件使用
private InputStream inputStream;
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
//下载时候调用
public String downloadFile() throws UnsupportedEncodingException{
// 下载保存时的文件名和被下载的文件名一样
downPath = java.net.URLDecoder.decode(downPath,"UTF-8");
filename = downPath;
// 下载的文件路径,请在webapps目录下创建download目录,并预先放置好两个文件备用
downPath = "download/" + downPath;
System.out.println("downPath:"+downPath);
System.out.println("filename:"+filename);
inputStream = ServletActionContext.getServletContext().getResourceAsStream(downPath);
System.out.println(inputStream);//若传过来的参数乱码,则inputStream为null
// 保存文件的类型
contentType = "application/x-msdownload";
//对下载的文件名按照UTF-8进行编码,解决下载窗口中的中文乱码问题
filename = MyUtil.toUTF8String(filename);
System.out.println(filename);
System.out.println("=============结束============");
return SUCCESS;
}
private String path;//查找文件夹的路径,由jsp页面传递过来
private List names;//返回查询出的文件名
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public List getNames() {
return names;
}
public void setNames(List names) {
this.names = names;
}
//查找文件列表
public String findFilesByDir() throws UnsupportedEncodingException{
//由于jsp对改路径进行了编码,此处要进行解码
path = java.net.URLDecoder.decode(path,"UTF-8");
//System.out.println("解码后路径:"+path);//E:\apache-tomcat-7.0.81\down
names= new ArrayList();
File file = new File(path);
if(file.isDirectory()){//是文件夹
File[] listFiles = file.listFiles();
for(int i=0;i
页面显示列表如下:
点击下载按钮即可弹框下载
注意:这个案例是先在指定文件夹查询文件显示列表,然后单击按钮下载,需要存在该文件夹,案例中的文件夹路径为:
E:\apache-tomcat-7.0.81\down