java中struts2实现文件上传下载功能实例解析

本文实例讲述了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_*" class="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 style="width:355px; float: left;">${item.accessory}</div>
       <c:if test="${!empty item.accessory}">
           <div class="btn_img" style="float: left;"><a style="color: black; text-decoration: none;" 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" class="downloadAction">
    <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文件中,加如下配置:

代码如下:

<!-- 所允许上传文件的大小2M -->
    <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" class="com.buptisc.srpms.action.UploadFileAction">
            <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" class="com.buptisc.srpms.action.UploadFileAction">
            <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程序设计有所帮助。

(0)

相关推荐

  • 搭建EXTJS和STRUTS2框架(ext和struts2简单实例)

    新建一个工程struts2工程teaweb(因为现在所做的项目是一个关于茶叶,茶文化的),导入jar包(基本的几个jar包:commons-logging-1.0.4.jar,freemarker- 2.3.8.jar,ognl-2.6.11.jar,struts2-core-2.0.10.jar,xwork-2.0.4.jar),配置 struts.xml配置内容如下 <?xml version="1.0" encoding="UTF-8" ?> &l

  • struts2单个文件上传的两种实现方式

    通过2种方式模拟单个文件上传,效果如下所示 开发步骤如下: 1.新建一个web工程,导入struts2上传文件所需jar,如下图 目录结构 2.新建Action 第一种方式 复制代码 代码如下: package com.ljq.action; import java.io.File; import org.apache.commons.io.FileUtils;import org.apache.struts2.ServletActionContext; import com.opensymph

  • ajax+json+Struts2实现list传递实例讲解

    由于实习需要,需要通过ajax来获取后台的List集合里面的值.由于前面没有接触过,所以今天就来研究下了. 一.首先需要下载JSON依赖的jar包.它主要是依赖如下: json-lib-2.2.2-jdk15 ezmorph-1.0.4 commons-logging-1.0.4 commons-lang-2.4 commons-collections-3.2.1 commons-beanutils 二.实例. 1.身份证错误信息Bean类(ErrorCondition.java) 复制代码 代

  • 关于Struts2的类型转换详解

    一.类型转换的意义 对于一个智能的MVC框架而言,不可避免的需要实现类型转换.因为B/S(浏览器/服务器)结构应用的请求参数是通过浏览器发送到服务器的,这些参数不可能有丰富的数据类型,因此必须在服务器端完成数据类型的转换 MVC框架是一个表现层解决方案,理应提供类型转换的支持,Struts2提供了功能非常强大的类型转换支持. 二.表现层数据的处理 1.对于web应用而言,表现层主要用于与用户交互,包括收集用户输入数据,向用户呈现服务器的状态.因此表现层的数据的流向主要有两个方向:输入数据和输出数

  • Struts1和struts2的区别_动力节点Java学院整理

    Struts2其实并不是一个陌生的Web框架,Struts2是以Webwork的设计思想为核心,吸收了Struts1的优点,因此,可以认为Struts2是Struts1和Webwork结合的产物. 简单来说二者的区别是: 一个是Stuts1 ,一个是Stuts2,这是最大的区别,技术方面,Stuts1有个核心控制器,但是只提供了一个接口,也就是execute,还要配置actionform之类的,很麻烦,所以依赖性比较强:而Stuts2是针对拦截器开发的,也就是所谓的AOP思想,可以配置多个act

  • struts1登录示例代码_动力节点Java学院整理

    Struts1框架实例-登录实例: 1.实例开始工作-导入jar包,在官网上下载struts1框架包,解压之后导入工程的: 2.之后配置web.xml(这里的具体配置方法可以参见struts1框架包中的实例文件夹webapps中的实例代码中web.xml文件的配置方法): 具体如下: <span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?> &

  • jsp struts1 标签实例详解第1/2页

    1,TagForm.java 复制代码 代码如下: package com.tarena.struts.tag.form; import org.apache.struts.action.*; import javax.servlet.http.*; import java.util.*; public class TagForm extends ActionForm { private int id; private String userName; private String passwo

  • struts1实现简单的登录功能实例(附源码)

    环境:MyEclipse 14 1   struts1 框架搭建 在MyEclipse新建web project 取名为struts1_login,此时是一个空文档就不截图了然后在project上右键->选择myeclipse->add struts capabilities 单击上面Install Apache Struts(1.x)Facet 点击next 选择*.do ,改下包名改成与你项目相关的.如我的包名为com.lichang.struts1 点击next 点击完成,在我们的WEB

  • struts2+spring+hibernate分页代码[比较多]第1/7页

    dao层接口: Java代码 复制代码 代码如下: package com.last999.im.news.dao; import java.util.*; import com.last999.im.news.entity.KindEntity; import com.last999.im.news.web.PageTool; public interface KindEntityDao{ public KindEntity get(String uuid); public void save

  • 浅谈struts1 & jquery form 文件异步上传

    1.概述 还在用struts1?是的,在地球的没写地方,落后的生产方式还在运转(老项目). 从 继承org.apache.struts.action.Action, 继承org.apache.struts.action.ActionForm开始吧 2. 代码 2.1 html页面 <html> <head> <title>网页上传</title> </head> <body> <center> <h1>本地文件

随机推荐