Struts2之文件上传下载
本篇文章主要介绍如何利用struts2进行文件的上传及下载,同时给出我在编写同时所遇到的一些问题的解决方案。
文件上传
前端页面
<!-- 引入struts标签 -->
<%@taglib prefix="s" uri="/struts-tags"%> <!--
使用struts中的<s:file></s:file>标签来选择文件。
设置name属性,则提交后将传递后给后台一个name属性值(upload)的文件类型的文件。
同时,将随同传递该文件的名字(uploadFileName)及文件类型(uploadContentType)
表单中增加编码格式(enctype)为multipart/form-data
-->
<form action="upload" enctype="multipart/form-data" method="post">
<s:file name="upload" label="Select File"/>
<button type="submit">Submit</button>
</form>
home.jsp
struts.xml
<!-- 指定上传的文件暂时保存的位置 -->
<constant name="struts.multipart.saveDir" value="/tmp"/>
<package name="default" extends="struts-default">
<!-- 上传文件action -->
<action name="home">
<result>/WEB-INF/content/home.jsp</result>
</action>
<action name="upload" class="com.wsy.action.UploadAction">
<!-- 引入拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 文件允许类型,可自行搜索查表,未指定则为默认所有类型 -->
<param name="allowedTypes">image/jpeg,image/gif,text/plain</param>
<!-- 文件最大大小 -->
<param name="maximumSize">1024*1024</param>
</interceptor-ref>
<!-- 一定要引入defaultStack,否则将无法提交数据至后台 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 上传成功,返回首页 -->
<result type="redirect">home.action</result>
<!-- 上传不成功,设置input逻辑视图,进入报错页面 -->
<result name="input">/WEB-INF/content/error.jsp</result>
</action>
</package>
struts.xml
文件上传action
package com.wsy.action;
import java.io.*;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private File upload; // 上传的文件
private String uploadContentType; // 上传的文件的类型
private String uploadFileName; // 上传的文件的名字
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
@Override
public String execute() throws Exception
{
String path = ServletActionContext.getServletContext().getRealPath("/WEB-INF/uploadFiles");
File file = new File(path);
// 创建文件保存文件夹
if (!file.exists())
file.mkdirs();
FileOutputStream fos = new FileOutputStream(path + File.separator + getUploadFileName());
FileInputStream fis = new FileInputStream(getUpload());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
fos.write(buffer , 0 , len);
}
fis.close();
fos.close();
return SUCCESS;
}
}
UploadAction.java
原理:Struts2文件上传通过将HTTP上传的数据先保存到临时文件夹(本文中为/tmp),然后使用fileUpload拦截器将文件绑定到Action的实例中,从而就能够以本地文件方式的操作浏览器上传的文件,将其保存到服务器下的特定位置。
文件下载
前端页面
<ol>
<%
String[] filelist = (String[])request.getSession().getAttribute("filelist");
if (filelist != null) {
for (int i = 0; i < filelist.length; i++) {
%>
<li><a href="download.action?filename=<%=filelist[i]%>"><%=filelist[i]%></a></li>
<%
}
} else {
%>
<li>无文件</li>
<% } %>
</ol>
home.jsp
struts.xml
<package name="download" extends="struts-default">
<!-- 下载文件action -->
<action name="download" class="com.wsy.action.DownloadAction">
<result name="success" type="stream">
<param name="contentType">image/jpeg,image/gif,text/plain</param>
<!-- 获取输入流,根据值调用相应的get方法 -->
<param name="inputName">targetFile</param>
<!--
contentDisposition是文件下载的处理方式,包括内联(inline)和附件(attachment),默认是inline。
使用附件时这样配置:attachment;filename="文件名" 。
-->
<param name="contentDisposition">attachment;filename="${filename}"</param>
<param name="bufferSizbe">1024*1024</param>
</result>
</action>
</package>
struts.xml
文件下载action
package com.wsy.action; import java.io.InputStream; import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport; public class DownloadAction extends ActionSupport {
private String filename; public String getFilename() {
return filename;
} public void setFilename(String filename) {
this.filename = filename;
} public InputStream getTargetFile() throws Exception {
InputStream in = ServletActionContext.getServletContext().getResourceAsStream("/WEB-INF/uploadFiles/" + this.getFilename());
return in;
} public String execute() throws Exception {
return SUCCESS;
}
}
DownloadAction.java
原理:同Servlet和HTTP协议时的文件下载。
出现的问题
1 上传文件时,
严重: Exception occurred during processing request: /Users/apple/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Union/WEB-INF/uploadFiles/acm.txt (No such file or directory)
java.io.FileNotFoundException: /Users/apple/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Union/WEB-INF/uploadFiles/acm.txt (No such file or directory)
原因:设置放在uploadFiles文件夹下,但uploadFiles文件夹不存在,所以抛出文件不存在异常。
解决方案:在上传文件的action创建文件输出流之前,先检测该文件夹是否存在,若不存在则创建。
2 下载文件时,
严重: Exception occurred during processing request: Can not find a java.io.InputStream with the name [targetFile] in the invocation stack. Check the <param name="inputName"> tag specified for this action.
java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [targetFile] in the invocation stack. Check the <param name="inputName"> tag specified for this action.
原因:
(1)struts.xml中返回中的inputName的值与action中的方法名不对应。
(2)文件为不允许类型或超出文件设定大小。
(3)action中创建文件输入流时传入的路径错误。
(4)文件名中含有中文字符,则导致无法创建文件输入流。
解决方案:
针对(1)~(3),仔细检查。
针对(4),在setFilename()方法返回时对文件名进行处理,
public void setFilename(String filename) throws UnsupportedEncodingException {
this.filename = new String(filename.getBytes("ISO8859-1"), "utf-8");
}
而做了如上处理后,虽然没有异常被抛出,但发现在下载含中文字符的文件时,下载的文件的文件名仍然时乱码。
所以就在Action中另添加一个方法。
public String getDownloadFilename() throws UnsupportedEncodingException {
return new String(filename.getBytes(), "ISO9959-1");
}
并将struts.xml中result中的contentDisposition的值改为对象的值。
<param name="contentDisposition">attachment;filename="${downloadFilename}"</param>
以上即为全部内容,欢迎提出问题和建议!
Struts2之文件上传下载的更多相关文章
- Struts2实现文件上传下载功能(批量上传)
今天来发布一个使用Struts2上传下载的项目, struts2为文件上传下载提供了好的实现机制, 首先,可以先看一下我的项目截图 关于需要使用的jar包,需要用到commons-fileupload ...
- Struts2 文件上传,下载,删除
本文介绍了: 1.基于表单的文件上传 2.Struts 2 的文件下载 3.Struts2.文件上传 4.使用FileInputStream FileOutputStream文件流来上传 5.使用Fi ...
- Struts2中文件上传下载实例
1.单文件上传 jsp页面: <!-- 单文件上传 --> <form action="Fileupload.action" method="post& ...
- Struts2 控制文件上传下载
之前介绍servlet3.0新特性的时候有提到过servlet API提供了一个part类来实现对文件的上传和保存,Struts其实是在其基础上做了进一步的封装,更加简单易用.至于文件下载,Strut ...
- plupload+struts2实现文件上传下载
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" ...
- struts2实现文件上传和下载
在做B/S系统时,通常会涉及到上传文件和下载文件,在没接struts2框架之前,我们都是使用apache下面的commons子项目的FileUpload组件来进行文件的上传,但是那样做的话,代码看起来 ...
- struts2的文件上传
在做B/S系统时,通常会涉及到上传文件和下载文件,在没接struts2框架之前,我们都是使用apache下面的commons子项目的FileUpload组件来进行文件的上传,但是那样做的话,代码看起来 ...
- java中的文件上传下载
java中文件上传下载原理 学习内容 文件上传下载原理 底层代码实现文件上传下载 SmartUpload组件 Struts2实现文件上传下载 富文本编辑器文件上传下载 扩展及延伸 学习本门课程需要掌握 ...
- Struts2文件上传下载
Struts2文件上传 Struts2提供 FileUpload拦截器,用于解析 multipart/form-data 编码格式请求,解析上传文件的内容,fileUpload拦截器 默认在defau ...
随机推荐
- VC++ MFC获取对话框上控件的位置
CRect rect; GetDlgItem(控件ID)->GetWindowRect(&rect);//获取控件的屏幕坐标 ScreenToClient(&rect);//转换 ...
- 用fxc.exe编译shader文件(*.fx, *.hlsl)的设置
原文出自:http://msdn.microsoft.com/en-us/library/windows/desktop/bb509709(v=vs.85).aspx#Profiles 拿DX11 S ...
- [原创.数据可视化系列之二]使用cesium三维地图展示美国全球军事基地分布
基于浏览器的三维地图还算是一个比较高冷的东西,最主要的技术难点是如何在浏览器上 多快好省 的显示三维数据,很遗憾,还真的没有太好的的方案,只能说还有可行的方案. 很久之前用过skyline,使用CS居 ...
- 介绍开源的.net通信框架NetworkComms框架 源码分析(二十二 )TCPConnectionStatic
原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是 ...
- 方法的覆盖(override)、重载(overload)和重写(overwrite)
body { background-color: white } .markdown-body { min-width: 200px; max-width: 760px; margin: 0 auto ...
- OpenLDAP双主
1:主A服务器 然后重新生成配置文件数据 主B服务器 注意:两个主服务器的rid必须得一样 在做主从的时候,必须得安装必要的软件包,comp ...
- [原创]迈出NIOS的第一步,HelloNIOS
Altera官方推出NIOS已经很久了,个人感觉C+V代码配合会是后面FPGA使用的一个主流,由C来完成一些对时序要求不高,对功能要求偏高的部分,比如运动控制等:由V来配合时序完成高时序要求的需求以及 ...
- Oracle数据访问组件ODAC的安装方法:
Oracle数据访问组件ODAC(Oracle Data Access Components)顾名思义就是用来访问Oracle数据库的小程序.我们可以编程调用这些组件来实现在没有安装Oracle数据库 ...
- otter双主同步安装与配置
otter是阿里的开源数据同步项目,资源地址就不用说了哈,网上找,阿里云论坛关于单方向同步的配置已经很清楚了,理论上说,双主同步也不复杂,但是毕竟 是数据库,比较重要,配置双主的时候,总觉得心里没底, ...
- Java 的replace和replaceAll的使用
(1)replace() 方法通过用 newChar 字符替换字符串中出现的所有 oldChar 字符,并返回替换后的新字符串. public String replace(char oldChar, ...