一、截图展示功能概要:
(1)主界面:
(2)单击浏览后:
(3)选择文件,单击提交,进入文件展示界面(下载功能界面)
(4)单击“下载”按钮,
(5)单击保存进行保存,成功保存
功能展示完毕。
二、代码实现:
1.目录结构
2.struts2.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <!-- struts的开发模式,设置为true,改变此文档中的配置不用重启tomcat --> <constant name="struts.devMode" value="true"></constant> <package name="default" extends="struts-default"> <default-action-ref name="index" /> <action name="index"><result>/jsp/upload.jsp</result></action> </package> <package name="uploadAnddownload" extends="struts-default" namespace="/user"> <result-types> <!-- 用于处理下载文件,提示对话框点击取消时报出异常问题 --> <result-type name="streamx" class="com.sunspoter.lib.web.struts2.dispatcher.StreamResultX"></result-type> </result-types> <action name="upload" class="com.upload.action.UploadAction" method="upload"> <result name="input">/jsp/listfile.jsp</result> <result name="success" type="redirectAction">queryAllFile</result> </action> <action name="queryAllFile" class="com.upload.action.QueryAllFileAction" method="queryAllFile"> <result name="input">/jsp/listfile.jsp</result> </action> <action name="download" class="com.upload.action.DownloadAction" method="download"> <result type="streamx"> <!-- 文件类型 —— application/octet-stream 表示无限制 --> <param name="contentType">application/octet-stream;charset=ISO8859-1</param> <!-- 流对象名 —— 去找Action中的getInputStream方法 --> <param name="inputName">inputStream</param> <!-- 文件名 —— 将调用该Action中的getDownloadFileName方法 --> <param name="contentDisposition">attachment;fileName="${downloadFileName}"</param> <!-- <param name="bufferSize">4096</param> --> </result> </action> </package> </struts>
3.web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
<% response.sendRedirect("index.action"); %>
<%@ page language="java" contentType="text/html; charset=utf-8" 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" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'upload.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"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript"> /* function showPhoto(){ document.getElementById("showPhoto").src=document.getElementById("photo").value; } */ </script> </head> <body> <form action="user/upload.action" method="post" enctype="multipart/form-data"> <input type="file" name="photo" id="photo" onchange="showPhoto()"/> <input type="submit" value="提交"/> </form> <br> <s:a action="queryAllFile.action" namespace="/user"> 进入下载页面 </s:a> <!-- <div> <img id="showPhoto" src="/upload/photo.jpg" style="width:160px;height:120px;"/> </div> --> </body> </html>
<%@ 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 'listfile.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"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 文件列表<br> <table border="1"> <s:iterator id="file" value="fileNameMap"> <tr> <td>${file.value}</td> <td> <s:a action="download.action" namespace="/user"> <s:param name="fileName">${file.value}</s:param> 下载 </s:a> </td> </tr> </s:iterator> </table> </body> </html>
package com.upload.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.io.IOUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport{ private static final long serialVersionUID = 1L; private File photo; private String photoFileName; private String photoContentType; private String savePath; public String upload(){ System.out.println("**********************upload*********************"); //判断目录是否存在,不存在的话要新建 File file = new File(getSavePath()); if(!file.exists() && !file.isDirectory()){ System.out.println(savePath+"目录不存在,需要重建"); file.mkdir(); } if(photo!=null){ try { InputStream is = new FileInputStream(getPhoto()); OutputStream os = new FileOutputStream(getSavePath()+"//"+getPhotoFileName()); IOUtils.copy(is, os); os.flush(); IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return "success"; } public File getPhoto() { return photo; } public void setPhoto(File photo) { this.photo = photo; } public String getPhotoFileName() { return photoFileName; } public void setPhotoFileName(String photoFileName) { this.photoFileName = photoFileName; } public String getPhotoContentType() { return photoContentType; } public void setPhotoContentType(String photoContentType) { this.photoContentType = photoContentType; } public String getSavePath() { return ServletActionContext.getServletContext().getRealPath("/upload"); } public void setSavePath(String savePath) { this.savePath = savePath; } }
package com.upload.action; import java.io.InputStream; import java.io.UnsupportedEncodingException; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class DownloadAction extends ActionSupport{ private static final long serialVersionUID = 1L; private String fileName;//要下载的文件名 private InputStream inputStream; public String download() throws Exception { System.out.println("********************download****************"); System.out.println("getFileName="+getFileName()); inputStream = ServletActionContext.getServletContext().getResourceAsStream("/upload/" + getFileName()); System.out.println("inputStream="+inputStream); return SUCCESS; } //为解决文件名字乱码。struts2.xml中读取的是downloadFileName而不是fileName public String getDownloadFileName() throws UnsupportedEncodingException { String downloadFileName = new String(fileName.getBytes(), "ISO8859-1"); return downloadFileName; } public String getFileName() { return fileName; } public void setFileName(String fileName) throws UnsupportedEncodingException { //this.fileName = fileName; this.fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8"); } public InputStream getInputStream() { return inputStream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } }
package com.upload.action; import java.io.File; import java.util.HashMap; import java.util.Map; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class QueryAllFileAction extends ActionSupport{ /** * */ private static final long serialVersionUID = 1L; private Map<String,String> fileNameMap; public String queryAllFile(){ System.out.println("******************queryAllFile******************"); //获取上传文件的目录 String filePath = ServletActionContext.getServletContext().getRealPath("/upload"); //存储要下载的文件名 fileNameMap = new HashMap<String,String>(); //递归遍历filePath下目录下的所有文件和目录,将文件的文件名存储到map集合中 listFile(new File(filePath),fileNameMap); System.out.println("fileNameMap="+fileNameMap); return "input"; } //file即代表一个文件,也代表一个文件目录;map存储文件名的集合。递归遍历指定目录下的所有文件 private void listFile(File file, Map<String, String> map) { //如果file代表的不是一个文件,而是一个目录 if(!file.isFile()){ //列出该目录下的所有文件和目录 File files[] = file.listFiles(); for(File f : files){ //递归 listFile(f,map); } }else{ map.put(file.getName(), file.getName()); } } public Map<String, String> getFileNameMap() { return fileNameMap; } public void setFileNameMap(Map<String, String> fileNameMap) { this.fileNameMap = fileNameMap; } }
三、小小心得
(1) 做上传功能之前一直纠结:文件是怎么传输到后台的,经过几天的寻找各种资源。明白前台<form action="user/upload.action" method="post" enctype="multipart/form-data">中<input type="file" name="photo">经过jsp解析(enctype="multipart/form-data"是允许将type=file的input解析成流的形式)。后台action中属性:
private File photo;
private String photoFileName;
private String photoContentType;
与jsp中<input type="file" name="photo">对应
(2)下载功能中其实重要的就是struts中的配置,将后台传输过来的文件形成的流和文件名字进行配置,输出到jsp前台
需要注意的是:<param name="contentDisposition">attachment;fileName="${downloadFileName}"</param> 是为了解决中文乱码。附件代码以及上边的粘贴代码中都有注释我就不多解释;
(3)其余的我就不多说了。只要对struts2的基本流程了解。把下边链接中的代码copy到自己的电脑上研究运行。我相信肯定能更加清楚其中原理。
四、完整项目包链接
http://download.csdn.net/detail/zhaoxiaoyueyue/9482979