首先,引入jar包。除了 Struts2.0的几个核心jar包外,还需要额外引入commons-fileupload.jar和commons-io.jar。

引入这两个包的时候,似乎版本也是一个比较重要的问题。我原先引入的是commons- fileupload-1.0.jar和commons-io.不知道那个版本.jar。代码全部写好之后却报 java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]。这个class是在Struts1.0-core.jar包里的,却死活找不到。直到我把两个包更新到了更高的版本,才算解决了这个 怪异的问题。

引入了jar包之后,写action的代码。主要的代码来自网络。可以忽略其中的log、 errorbean、baseaction等我自己写的东西。

package common.web.action;

import java.io.*;
import java.util.Date;

import org.apache.struts2.ServletActionContext;

/**
* 实现文件上传的action
*
*/
public class UploadAction extends BasicAction {
private static final long serialVersionUID = 572146812454l;

// 输入、输出流的缓冲区大小
private int BUFFER_SIZE;
// 上传文件存储路径
private String filePath;

// 上传文件
// 注意,文件上传时<s:file/>同时与myFile,myFileContentType,myFileFileName绑定
// 所以同时要提供myFileContentType,myFileFileName的set方法
private File myFile;
// 上传文件类型
private String contentType;
// 上传文件名
private String fileName;
private String p_w_picpathFileName;
// 文件说明,与页面属性绑定
private String caption;

/**
* 主要的方法,从请求中读取文件,复制到指定的路径下去
*/
@Override
public String execute() {
   log.info("上传的文件信息:");
   log.info("文件名: " + fileName+"; 文件类型: " + contentType+"; 文件大小: " + myFile.length() + " bytes");

// 利用当前时间的毫秒数,加上原文件的扩展名,构成新的文件名
   p_w_picpathFileName = new Date().getTime() + getExtention(fileName);

log.info("新的文件名为= " + p_w_picpathFileName);
   log.info("新的文件存储路径为= " + this.filePath);

File p_w_picpathFile;
   try {
    // 如果是绝对路径
    if (filePath.indexOf(":") > 0) {
     p_w_picpathFile = new File(this.filePath + "/" + p_w_picpathFileName);
    } else {
     // 在工程路径下的文件夹中,根据新的文件名,创建文件
     p_w_picpathFile = new File(ServletActionContext.getServletContext()
       .getRealPath(this.filePath)
       + "/" + p_w_picpathFileName);
    }
   } catch (NullPointerException e) {
    e.printStackTrace();
    errorbean.setErrorMessage("找不到上传文件的保存路径!");
    errorbean.setMyException(e);
    errorbean.setSuccess(false);
    log.error(errorbean.toString());
    return INPUT;
   }
   // 将请求中的文件复制到新的文件中
   save(myFile, p_w_picpathFile);
   errorbean.setSuccess(true);
   errorbean.setErrorMessage("文件上传成功!");

if (errorbean.isSuccess()) {
    return SUCCESS;
   } else {
    return INPUT;
   }
}

/**
* 将请求中的文件复制到指定路径下去的方法;
*
* @param File
*            src: 源文件
* @param File
*            det: 目标文件
*/
private void save(File src, File dst) {

// 输入输出流
   InputStream in = null;
   OutputStream out = null;

try {
    // 根据源文件和缓冲区大小,创建输入流
    in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
   } catch (Exception e) {
    e.printStackTrace();
    errorbean.setErrorMessage("无法创建输入流!");
    errorbean.setMyException(e);
    errorbean.setSuccess(false);
    log.error(errorbean.toString());
    return;
   }
   try {
    // 根据目标文件和缓冲区大小,创建输出流
    out = new BufferedOutputStream(new FileOutputStream(dst),
      BUFFER_SIZE);
   } catch (Exception e) {
    e.printStackTrace();
    errorbean.setErrorMessage("无法创建输出流!");
    errorbean.setMyException(e);
    errorbean.setSuccess(false);
    log.error(errorbean.toString());
    return;
   }
   // 从输入流中读取文件,写入输出流中
   byte[] buffer = new byte[BUFFER_SIZE];
   try {
    while (in.read(buffer) > 0) {
     out.write(buffer);
    }
   } catch (IOException e) {
    e.printStackTrace();
    errorbean.setErrorMessage("从输入流中读取/向输出流中写入数据时发生异常!");
    errorbean.setMyException(e);
    errorbean.setSuccess(false);
    log.error(errorbean.toString());
    return;
   } finally {
    try {
     // 关闭输入输出流
     if (null != in) {
      in.close();
     }
     if (null != out) {
      out.close();
     }
    } catch (IOException e) {
     e.printStackTrace();
    }
   }

}

/**
* 获取上传文件扩展名的方法
*
* @param String
*            fileName:上传文件的全名
* @return String: 上传文件的扩展名
*/
private String getExtention(String fileName) {
   int pos = fileName.lastIndexOf(".");
   return fileName.substring(pos);
}

/**
* getter & setter
*/
public void setMyFileContentType(String contentType) {
   this.contentType = contentType;
}

public void setMyFileFileName(String fileName) {
   this.fileName = fileName;
}

public void setMyFile(File myFile) {
   this.myFile = myFile;
}

public void setMyFile(String myFile) {
   System.out.println("String 类型的 myFile: "+myFile);
}

public String getImageFileName() {
   return p_w_picpathFileName;
}

public String getCaption() {
   return caption;
}

public void setCaption(String caption) {
   this.caption = caption;
}

public void setBUFFER_SIZE(int buffer_size) {
   BUFFER_SIZE = buffer_size;
}

public int getBUFFER_SIZE() {
   return BUFFER_SIZE;
}

public void setFilePath(String filePath) {
   this.filePath = filePath;
}

}

jsp页面的写法如下。 <body>
   This is my JSP page for upload file.
   <br>
   <s:property value="errorbean.errorMessage"/>
   <s:form action="fileupload" namespace="/" method="POST" enctype="multipart/form-data">
    <s:file name="myFile" label="MyFile"></s:file>
    <s:textfield name="caption" label="Caption"></s:textfield>
    <s:submit label="submit"></s:submit>
   </s:form>
</body>

其中,enctype="multipart/form-data"是上传文件的form的写法。如 果不这样写,action无法在Request里面找到对应的file。并且,写了这个东西最好配置上namespace。我最初只写 enctype="multipart/form-data"而没写namespace,结果又报 java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]。这个东西真是阴魂不散!不过加了namespace之后就没事了。

struts.xml:

<action name="fileupload" class="UPLOAD">
    <interceptor-ref name="fileUpload">
     <param name="maximumSize">4194304</param>
     <param name="allowedTypes">
      p_w_picpath/jpeg,p_w_picpath/gif,p_w_picpath/jpg
     </param>
    </interceptor-ref>
    <interceptor-ref name="defaultStack" />
    <result name="success">test/upload.jsp</result>
    <result name="input">test/upload.jsp</result>
   </action>

Struts.xml里面的<interceptor-ref name="fileUpload">是为了限制上传文件的大小和文件类型做的配置,配置的内容就是下面的两个<param>标签。在 这个过滤器之后一定要加上<interceptor-ref name="defaultStack" />,否则fileupload过滤到问题之后,不会转到input结果中去,而仍然会向action中跳转。这时读取到的file就是null 了。此外,配置了这俩过滤器,就必须配置input结果,否则发生问题的时候找不到跳转目标。

上面的例子是我测试通过了的。当然,文件上传还有一些尾巴工作可以改进,比如文件存储的临时路径、错 误提示信息的国际化等等。这些另外再说吧!

转载于:https://blog.51cto.com/winters1224/799053

struts2.0实现文件上传相关推荐

  1. struts2完美实现文件上传和下载

    ## struts2完美实现文件上传和下载 ## 第一步:在webx项目lib目录下加入struts.jar包 asm-3.3.jar asm-commons-3.3.jar asm-tree-3.3 ...

  2. data后缀文件解码_封装ThinkPHP6.0通用文件上传

    php中文网最新课程 每日17点准时技术干货分享 本文为php中文网认证作者:"wpj"投稿,欢迎加入php中文网有偿投稿计划! 本文实例讲述了封装ThinkPHP6通用文件上传方 ...

  3. Servlet3.0学习总结(三)——基于Servlet3.0的文件上传

    在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件,在Servlet3.0中提供了对文件上传的原生支持,我们不 ...

  4. Feng Office 3.7.0.5 - 文件上传

    Feng Office 3.7.0.5 - 文件上传 <?php$exp = explode("/", $_SERVER['REQUEST_URI']);$iname = $ ...

  5. struts2之单个文件上传

    通过2种方式模拟单个文件上传,效果如下所示 开发步骤如下: 1.新建一个web工程,导入struts2上传文件所需jar,如下图 目录结构 2.新建Action 第一种方式 package com.l ...

  6. struts2教程--实现文件上传下载

    Struts2文件上传下载 一.Struts2文件上传 提供 FileUpload 拦截器,用于解析 multipart/form-data 编码格式请求,解析上传文件的内容 fileUpload拦截 ...

  7. Struts2框架--学习笔记(下):OGNL表达式、值栈操作、拦截器、struts2标签、文件上传

    一.OGNL概述:OGNL是一种表达式 (1)在struts2中操作值栈数据. (2)一般把ognl在struts2中操作,和struts2标签一起使用操作值栈. (3)ognl不是strut2的一部 ...

  8. struts2之单个文件上传(特别推荐)

    通过2种方式模拟单个文件上传,效果如下所示 开发步骤如下: 1.新建一个web工程,导入struts2上传文件所需jar,如下图 目录结构 2.新建Action 第一种方式 package com.l ...

  9. 在Struts2中实现文件上传(二)

    发布运行应用程序,在浏览器地址栏中键入:http://localhost:8080/Struts2_Fileupload/FileUpload.jsp,出现图示页面:   清单7 FileUpload ...

最新文章

  1. 针对七牛含有特殊字符的文件名,对特殊字符编码处理
  2. 游戏杆编程心得二:如何判断按钮的有效按下
  3. 下载了python在哪里写代码-通过python下载FTP上的文件夹的实现代码
  4. 北斗导航 | 卫星导航基础知识(坐标系)
  5. MySQL主从复制主库宕机:1更新完relaylog2最大post设为主库 配置及删除之前从库信息3其他从库新建连接
  6. ORA-15096: lost disk write detected的解决与修复
  7. kafka从头消费信息
  8. PMP考试通过率怎么样?
  9. 腾讯云服务器安全吗?来说说
  10. 二维曲线 去噪点 c++_二维介孔聚吡咯-氧化石墨烯异质结用于制备无枝晶的锂金属负极...
  11. SSD(Single Shot MultiBox Detector)不得不说的那些事
  12. 怎么将照片尺寸调整成两寸?照片调整尺寸方法分享
  13. 艾滋hiv最新研究进展(2022年4月)
  14. 专利缴费后如何获取发票
  15. 原生js时间格式化方法封装
  16. 如何引流至企业微信社群
  17. 台式电脑开启休眠模式(win10)
  18. mybatis-plus 注解 通过中间表进行一对多、多对多查询(三表)
  19. 腹式呼吸胸部发麻是怎么回事?
  20. 【Excel 函数】Office 365 之Excel函数之Right

热门文章

  1. GitLab安装文档
  2. HTML5元素周期表
  3. ORM-Dapper:Dapper百科
  4. iOS_Spring自动生成Model,Service,Controller 之 介绍
  5. mysql数据库千万级别数据的查询优化和分页测试
  6. [转]VC获取各类指针
  7. Project interpreter not specified(eclipse+pydev) (转)
  8. Ubuntu中Apache修改DocumentRoot(修改网站根目录)
  9. [转]QT中QString与string的转化,解决中文乱码问题
  10. 著名ERP厂商的SSO单点登录解决方案介绍一