Struts2 文件上传下载 含下载时中文乱码
对于struts2一直都是看过,很少去动手写里面的功能,今天花了一点时间算整理整理。
整体的项目大致如下:
1:文件上传
uploadAction.java
package action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport { private static final long serialVersionUID = -8920466592471253212L; private String title; private File file; // 上传的文件 private String fileFileName; // 文件名称 private String fileContentType; // 文件类型 private String savePath; private String contents = ""; public String execute() throws Exception { // String url = getSavePath() + File.separator + getFileFileName(); String url = getSavePath(); System.out.println("url==" + url + ",,," + getFileContentType()); FileOutputStream fos = null; FileInputStream fis = null; try { // fos = new FileOutputStream(url); File uploadFile = new File(url, this.getFileFileName()); fos = new FileOutputStream(uploadFile); fis = new FileInputStream(getFile()); byte[] buffer = new byte[1024 * 1024]; int len = 0; while ((len = fis.read(buffer)) > 0) { fos.write(buffer, 0, len); setContents(getContents() + new String(buffer)); } fos.flush(); } catch (Exception e) { e.printStackTrace(); return INPUT; } finally { close(fos, fis); } return SUCCESS; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public String getFileFileName() { return fileFileName; } public void setFileFileName(String fileFileName) { this.fileFileName = fileFileName; } public String getFileContentType() { return fileContentType; } public void setFileContentType(String fileContentType) { this.fileContentType = fileContentType; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getSavePath() { String result = ServletActionContext.getServletContext().getRealPath( savePath); return result; } public void setSavePath(String savePath) { this.savePath = savePath; } public String getContents() { return contents; } public void setContents(String contents) { this.contents = contents; } private void close(FileOutputStream fos, FileInputStream fis) { if (fis != null) { try { fis.close(); } catch (IOException e) { System.out.println("FileInputStream关闭失败"); e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { System.out.println("FileOutputStream关闭失败"); e.printStackTrace(); } } } }
上传页面upload.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>上传文件</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <s:form action="uploads" method="post" enctype="multipart/form-data"> <s:textfield id="title" name="title" label="文件标题"/> <s:file name="file" label="上传文件"/> <s:submit value="提交"/> </s:form> </body> </html>
上传成功uploadSuccess.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> 上传文件:<s:property value="title" /><br/> 文件内容: <s:if test="%{fileContentType.indexOf('image')>=0}"> <img src="<s:property value="'upload/'+fileFileName"/>"/> </s:if> <s:else> <s:property value="contents"/> </s:else> </body> </html>
主要的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> <constant name="struts.devMode" value="true" /> <constant name="struts.i18n.encoding" value="UTF-8" /> <package name="myDemo" extends="struts-default" namespace="/"> <action name="uploads" class="action.UploadAction" > <param name="savePath">/upload</param> <result name="input">/upload.jsp</result> <result name="success">/uploadSuccess.jsp</result> </action> <action name="downloads" class="action.DownloadAction"> <param name="inputPath">upload</param> <result name="input">/downloadSuccess.jsp</result> <result name="success" type="stream"> <param name="contentType">application/octet-stream;charset=ISO8859-1 </param> <param name="inputName">downloadFile</param> <param name="contentDisposition">attachment;filename="${downloadFileName}"</param> <param name="bufferSize">4096</param> </result> </action> <action name="download" class="action.DownloadAction" method="download"> <param name="inputPath">upload</param> <result name="success" >/download.jsp </result> </action> <!-- <action name="*"> <result>/{1}.jsp</result> </action> --> </package> </struts>
对于上传主要在action哩,主要有3个属性:***、***FileName、***ContentTyp。我的例子**为file。
成功后,页面若是图片形式,我把它显示出来,如果不是就显示里面的内容。
2:文件下载
文件下载主要配置在struts.xml里。
一般使用result=“stream” 在struts中进行文件下载
有4个参数:contentType(主要)、contentDisposition(主要)、inputName、bufferSize,相对于这2个主要些。
详细的可以参考这个页面:强烈碰击
常常也会在下载的时候碰到一个异常:Can not find a java.io.InputStream with the name [downloadFile] in the invocation stack. Check the <param name="inputName"> tag specified for this action.
主要为2中情况:
第一:文件路径不对,没有取到文件,只需要在return之前,把流放在system.out.println()中输出一下,是null的话,就是路径不对。
第二:action中需要配置"<param name="inputName">"后面属性的那个get方法。
下载action:downloadAction.java
package action; import java.io.File; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class DownloadAction extends ActionSupport { private static final long serialVersionUID = -5772950074616179246L; // the download file private String fileName; // the download folder private String inputPath; // all files of the download folder private List<String> fileNames; public String getFileName() { return fileName; } public void setFileName(String fileName) { //System.out.println("----"+fileName); try { fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //System.out.println("----"+fileName); this.fileName = fileName; } public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } public InputStream getDownloadFile() { String urll = File.separator + inputPath + File.separator + fileName; InputStream is = ServletActionContext.getServletContext() .getResourceAsStream(urll); //System.out.println(urll+"-----"+fileName+"---"+is); return is; } public String getDownloadFileName() { String downFileName = fileName; //System.out.println("----"+downFileName); try { downFileName = new String(downFileName.getBytes(), "ISO8859-1"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //System.out.println("----"+downFileName); return downFileName; } public String download() throws Exception { String downloadDir = ServletActionContext.getServletContext() .getRealPath(File.separator + inputPath); File rootFile = new File(downloadDir); File[] files = rootFile.listFiles(); fileNames = new ArrayList<String>(); for (File f : files) { if (!f.isDirectory()) { String name = f.getName(); //System.out.println(name); fileNames.add(name); } } return SUCCESS; } public List<String> getFileNames() { return fileNames; } public void setFileNames(List<String> fileNames) { this.fileNames = fileNames; } }
下载页面download.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <font color="blue">--------------------------</font> <br> <s:iterator value="fileNames" var="file"> <s:set value="file" id="files" name="files" scope="Request"/> <% String fname = (String)request.getAttribute("files"); fname = java.net.URLEncoder.encode(fname, "UTF-8"); %> <a href="downloads.action?fileName=<%=fname %>"> <s:property value="file" />下载 </a> <br /> </s:iterator> </body> </html>
3个乱码的地方:
a:前台中文,后台获取:
public void setFileName(String fileName) { //System.out.println("----"+fileName); try { fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //System.out.println("----"+fileName); this.fileName = fileName; }
在未URLEncoder之前:
b:下载时显示中文名字:
public String getDownloadFileName() { String downFileName = fileName; //System.out.println("----"+downFileName); try { downFileName = new String(downFileName.getBytes(), "ISO8859-1"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //System.out.println("----"+downFileName); return downFileName; }
<action name="downloads" class="action.DownloadAction"> <param name="inputPath">upload</param> <result name="input">/downloadSuccess.jsp</result> <result name="success" type="stream"> <param name="contentType">application/octet-stream;charset=ISO8859-1 </param> <param name="inputName">downloadFile</param> <param name="contentDisposition">attachment;filename="${downloadFileName}"</param> <param name="bufferSize">4096</param> </result> </action>
主要为action配置时配置contentDisposition参数,attachment;filename="${downloadFileName}",
取的就为getDownloadFileName()的值。
c:链接中的中文编码
<s:iterator value="fileNames" var="file"> <s:set value="file" id="files" name="files" scope="Request"/> <% String fname = (String)request.getAttribute("files"); fname = java.net.URLEncoder.encode(fname, "UTF-8"); %> <a href="downloads.action?fileName=<%=fname %>"> <s:property value="file" />下载 </a> <br /> </s:iterator>
本Demo可以自这里下载到: 惨不忍睹的点击