java中struts2实现文件上传下载功能实例解析
java中struts2实现文件上传下载功能实例解析
发布时间:2016-12-28 来源:查字典编辑
摘要:本文实例讲述了java中struts2实现文件上传下载功能实现方法。分享给大家供大家参考。具体分析如下:1.文件上传首先是jsp页面的代码在...

本文实例讲述了java中struts2实现文件上传下载功能实现方法。分享给大家供大家参考。具体分析如下:

1.文件上传

首先是jsp页面的代码

在jsp页面中定义一个上传标签

复制代码 代码如下:<tr>

<td align="right" bgcolor="#F5F8F9"><b>附件:</b></td>

<td bgcolor="#FFFFFF">

<input type="file" name="upload" />

</td>

<td bgcolor="#FFFFFF"></td>

</tr>

然后是BaseAction中定义的相关属性其它的就省略了(也可定义在自己的Action,换下访问修饰符即可)

复制代码 代码如下:/**

*Action基类

**/

public class BaseAction extends ActionSupport {

protected List<File> upload;

protected List<String> uploadContentType; //文件类型

protected List<String> uploadFileName; //文件名

protected String savePath; //保存路径

}

然后是Action中的一个上传方法,代码如下:

复制代码 代码如下:/**

* 8.上传附件

* @param upload

*/

public void uploadAccess(List<File> upload){

try {

if (null != upload) {

for (int i = 0; i < upload.size(); i++) {

String path = getSavePath() + ""+ getUploadFileName().get(i);

System.out.println(path);

item.setAccessory(getUploadFileName().get(i));

FileOutputStream fos = new FileOutputStream(path);

FileInputStream fis = new FileInputStream(getUpload().get(i));

byte[] buffer = new byte[1024];

int len = 0;

while ((len = fis.read(buffer)) > 0) {

fos.write(buffer, 0, len);

}

fis.close();

fos.close();

}

}

} catch (Exception e) {

logger.error("上传附件错误。", e);

}

}

接着是我的struts2.xml文件

复制代码 代码如下:<action name="itemRDAction_*" method="{1}">

<param name="savePath">e:upload</param>

<interceptor-ref name="defaultStack">

<param name="fileUpload.allowedTypes">

application/octet-stream,image/pjpeg,image/bmp,image/jpg,image/png,image/gif,image/jpeg,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel

</param>

<param name="fileUpload.maximumSize">8000000</param>

</interceptor-ref>

<result name="show_item_rd_upd"> /WEB-INF/jsp/page_item/updItem_rd.jsp</result>

<result name="show_item_rd_list"> /WEB-INF/jsp/page_item/listItem_rd.jsp</result>

<result name="show_item_rd_push"> /WEB-INF/jsp/page_item/pushItem_rd.jsp</result>

</action>

savePath为保存路径,fileUpload.allowedTypes 用来限制上传文件类型 fileUpload.maximumSize 文件大小限制

2.文件下载

首先是页面中的下载链接

复制代码 代码如下:<tr>

<td width="20%" align="right" bgcolor="#F5F8F9"><b>附件:</b></td>

<td width="40%" bgcolor="#FFFFFF">

<div>${item.accessory}</div>

<c:if test="${!empty item.accessory}">

<div><a href="download.action?filename=${item.accessory}">下载</a></div>

</c:if>

</td>

<td width="40%" bgcolor="#FFFFFF"></td>

</tr>

接着是DownloadAction的代码:

复制代码 代码如下:/**

* DownloadAction

*

* @author zhaoxz

*

*/

@Controller("downloadAction")

@Scope("prototype")

public class DownloadAction extends BaseAction {

/**

*

*/

private static final long serialVersionUID = -4278687717124480968L;

private static Logger logger = Logger.getLogger(DownloadAction.class);

private String filename;

private InputStream inputStream;

private String savePath;

private String mimeType;

public InputStream getInputStream() {

try {

String path = getSavePath() + "//"+ new String(filename.getBytes("ISO8859-1"), "utf-8");

System.out.println(path);

mimeType = ServletActionContext.getServletContext().getMimeType(path)+ ";charset=UTF-8";

inputStream = new FileInputStream(path);

String agent = request.getHeader("USER-AGENT");

System.out.println(agent);

if (null != agent) {

if (-1 != agent.indexOf("Firefox")) {// Firefox

mimeType = mimeType.replace("UTF-8", "ISO8859-1");

} else {// IE7+ Chrome

System.out.println("IE,Chrome");

filename = new String(filename.getBytes("ISO8859-1"),"utf-8");

filename = java.net.URLEncoder.encode(filename, "UTF-8");

}

}

} catch (Exception e) {

logger.error("下载文件信息出错。", e);

}

if (null == inputStream) {

System.out.println("getResource error");

}

return inputStream;

}

public void setInputStream(InputStream inputStream) {

this.inputStream = inputStream;

}

@Override

public String execute() throws Exception {

return SUCCESS;

}

/*************************** get set ******************************/

public String getSavePath() {

return this.savePath;

}

public void setSavePath(String savePath) {

this.savePath = savePath;

}

public String getFilename() {

return filename;

}

public void setFilename(String filename) {

this.filename = filename;

}

}

然后是它的struts2.xml文件:

复制代码 代码如下:<action name="download">

<param name="savePath">E:/upload</param>

<result type="stream">

<param name="contentType">${mimeType}</param>

<param name="contentDisposition">attachment;filename="${filename}"</param>

<param name="inputName">inputStream</param>

</result>

</action>

下载的话注意下编码格式基本应该就没什么问题了.

上传过程碰到的问题

1.上传大文件就出错解决方法1

出现的错误有如下:

1、2012-02-24 11:06:31,937 ERROR (org.apache.struts2.dispatcher.Dispatcher:512) - Could not find action or result

No result defined for action com.iman.portal.action.QuestionActionImpl and result problemPage - action - file:/E:/myeclipse/workspaces/portal/WebRoot/WEB-INF/classes/struts2/struts-question.xml:51:55

2、the request was rejected because its size (2973652) exceeds the configured maximum (2097152)

中文意思: 要求被拒绝,因为它的大小(2973652)超过配置的最大值(2097152)、

考虑到用户体验,所以必须在上传附件时,拦截这样的异常,解决方法如下:

1、所上传的文件,在上传过程中都是先存放在缓存中的,安全起见,还是在项目的struts.properties文件中,加一个临时存放路径,虽然项目中己经设置好服务器的物理路径。

复制代码 代码如下: struts.multipart.saveDir=/temp

2、考虑到后期可能会修改文件上传的大小,所以不管是否默认,还是在项目的struts.properties文件中,加如下配置:

复制代码 代码如下: <>

<constant name="struts.multipart.maxSize" value="2097152"/>

3、struts.xml配置

复制代码 代码如下: <>

<action name="updateProblem" method="updateProblem">

<interceptor-ref name="fileUpload"/>

<interceptor-ref name="defaultStack" />

<result name="input">/page/question/page/problemPage.jsp</result>

</action>

4、最重要也是最关键的一步

fileUpload拦截器只是当文件上传到服务器上之后,才进行的文件类型和大小判断。在Action中如果我们什么操作都不做的话,异常就会展现在用户的面前,因此想了一个方法,把该异常信息设置为Action级别的错误信息。即重写addActionError方法。

复制代码 代码如下:@Override

public void addActionError(String anErrorMessage) {

// 这里要先判断一下,是我们要替换的错误,才处理

if (anErrorMessage.startsWith("the request was rejected because its size")) {

Pattern pattern = Pattern.compile("d+");

Matcher m = pattern.matcher(anErrorMessage);

// 匹配一次

m.find();

String s1 =m.group();//上传的文件大小

// 再匹配一次

m.find();

String s2 =m.group();//所限制的大小

if(!s1.equals("") && !s2.equals("")){

fileUploadErrorMessage="你上传的文件大小(" + Long.valueOf(s1)/1024 +"字节)超过允许的大小(" + Long.valueOf(s2)/1024/1024 + "M)";

getRequest().setAttribute("fileUploadErrorMessage","文件太大,超过了允许的大小("+Long.valueOf(s2)/1024/1024+"M),上传失败!");

// 将信息替换掉

super.addActionError(fileUploadErrorMessage);

}

} else {// 否则按原来的方法处理

super.addActionError(anErrorMessage);

}

}

可以,在返回页面用<s:fielderror/> <s:fielderror/>,得到addActionError中的错误内容。

因为我不打算,在页面上显示出来错误原因,想弹出一个提示框,所以将信息放入了request对象中。

而页面加载时,加了如下js验证:

复制代码 代码如下://判断 文件是否上传成功

var message="${request.fileUploadErrorMessage}";

if(message!=null && ""!=trim(message) && message!="null"){

self.parent.diag.close();

alert(message);

return;

}

下面是一些参考了解东东:

struts.multipart.maxSize掌控整个项目所上传文件的最大的Size

struts.multipart.maxSize和fileUpload拦截器的maximumSize属性分工不同,总结如下:

1.struts.multipart.maxSize掌控整个项目所上传文件的最大的Size。

超过了这个size,后台报错,程序处理不了如此大的文件。fielderror里面会有如下的提示:

the request was rejected because its size (16272982) exceeds the configured maximum (9000000)

2.fileUpload拦截器的maximumSize属性必须小于struts.multipart.maxSize的值。

struts.multipart.maxSize默认2M,当maximumSize大于2M时,必须设置struts.multipart.maxSize的值大于maximumSize。

3.当上传的文件大于struts.multipart.maxSize时,系统报错

当上传的文件在struts.multipart.maxSize和maximumSize之间时,系统提示:

File too large: file "MSF的概念.ppt" "upload__5133e516_129ce85285f__7ffa_00000005.tmp" 6007104

当上传的文件小于maximumSize,上传成功。

复制代码 代码如下:<action name="UploadFile">

<result name="UploadFileResult">/pages/ShowOtherFiles.jsp</result>

<result name="JGBsuccess">/pages/JGBdetail.jsp</result>

<interceptor-ref name="fileUpload">

<param name="savePath">/data</param>

<param name="maximumSize">52428800</param>

</interceptor-ref>

<interceptor-ref name="defaultStack"></interceptor-ref>

</action>

上传大文件就出错解决办法2:

问题:上传大文件报错……

解决:修改struts.xml文件中的参数如下

复制代码 代码如下:<constant name="struts.multipart.maxSize" value="55000000"/>

<action name="UploadFile">

<result name="UploadFileResult">/www.jb51.net/ ShowOtherFiles.jsp</result>

<result name="JGBsuccess">/pages/JGBdetail.jsp</result>

<interceptor-ref name="fileUpload">

<param name="savePath">/data</param>

<param name="maximumSize">52428800</param>

</interceptor-ref>

<interceptor-ref name="defaultStack"></interceptor-ref>

</action>

struts.xml文件中的大小与实际文件大小的关系:1048576(Bytes) = 1024*1024 = 1M实际文件大小.

struts.multipart.maxSize掌控整个项目所上传文件的最大的Size

struts.multipart.maxSize和fileUpload拦截器的maximumSize属性分工不同,总结如下:

1.struts.multipart.maxSize掌控整个项目所上传文件的最大的Size。超过了这个size,后台报错,程序处理不了如此大的文件。fielderror里面会有如下的提示:

the request was rejected because its size (16272982) exceeds the configured maximum (9000000)

2.fileUpload拦截器的maximumSize属性必须小于struts.multipart.maxSize的值。

struts.multipart.maxSize默认2M,当maximumSize大于2M时,必须设置struts.multipart.maxSize的值大于maximumSize。

3.当上传的文件大于struts.multipart.maxSize时,系统报错

当上传的文件在struts.multipart.maxSize和maximumSize之间时,系统提示:

File too large: file "MSF的概念.ppt" "upload__5133e516_129ce85285f__7ffa_00000005.tmp" 6007104

当上传的文件小于maximumSize,上传成功。

上传文件的类型限制

配置fileupload拦截器

struts2的defaultStack中已经含有fileupload拦截器,如果想加入allowedTypes参数,需要从新写一个defaultstack ,拷贝过来修改一下即可:

复制代码 代码如下:<interceptors>

<interceptor-stack name="myDefaultStack">

<interceptor-ref name="exception"/>

<interceptor-ref name="alias"/>

<interceptor-ref name="servletConfig"/>

<interceptor-ref name="i18n"/>

<interceptor-ref name=www.jb51.net/>

<interceptor-ref name="chain"/>

<interceptor-ref name="debugging"/>

<interceptor-ref name="profiling"/>

<interceptor-ref name="scopedModelDriven"/>

<interceptor-ref name="modelDriven"/>

<interceptor-ref name="fileUpload">

<param name="allowedTypes">

image/png,image/gif,image/jpeg

</param>

</interceptor-ref>

<interceptor-ref name="checkbox"/>

<interceptor-ref name="staticParams"/>

<interceptor-ref name="actionMappingParams"/>

<interceptor-ref name="params">

<param name="excludeParams">dojo..*,^struts..*</param>

</interceptor-ref>

<interceptor-ref name="conversionError"/>

<interceptor-ref name="validation">

<param name="excludeMethods">input,back,cancel,browse</param>

</interceptor-ref>

<interceptor-ref name="workflow">

<param name="excludeMethods">input,back,cancel,browse</param>

</interceptor-ref>

</interceptor-stack>

</interceptors>

<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>

仅修改代码中的

复制代码 代码如下:<interceptor-ref name="fileUpload">

<param name="allowedTypes">

image/png,image/gif,image/jpeg

</param>

</interceptor-ref>

拦截器栈在<package>标签内 <action>标签外配置 如上我们如果把它定义成默认拦截器的话就不需要在

<action>标签中引入,没有的话需要引入拦截器

复制代码 代码如下:<action>

<result name="input">/error/dbError.jsp</result>

<interceptor-ref name="myDefaultStack"></interceptor-ref>

</action>

文件上传类型错误action会直接返回input,所以不需要在action中return "input" ;

还可以在<package>标签外定义上传问价你的路径跟大小:

复制代码 代码如下:<constant name="struts.multipart.saveDir" value="/upload/detailed"></constant>

<constant name="struts.multipart.maxSize" value="1024"></constant>

最最最重要的一点:上传文件的表单 必须加上:enctype="multipart/form-data" 不加必然报input错误。

希望本文所述对大家的Java程序设计有所帮助。

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Java学习
热门Java学习
编程开发子分类