`

struts2 文件上传

阅读更多

实现原理

Struts 2是通过Commons FileUpload文件上传。Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。从而我们就能够以本地文件方式的操作浏览器上传的文件。

具体实现

以下是例子所依赖类包的列表:

 

 

 

首先,创建文件上传页面FileUpload.jsp,内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Insert title here</title>
 </head>
 <body>
  <s:form action="upload" method="post" enctype="multipart/form-data">
   <s:file name="myFile" />
   <s:submit />
  </s:form>
 </body>
</html>

在FileUpload.jsp中,先将表单的提交方式设为POST,然后将enctype设为multipart/form-data,这并没有什么特别之处。接下来,<s:file/>标志将文件上传控件绑定到Action的myFile属性。

 

其次是UploadAction.java代码:

package com.student.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Date;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;


public class UpLoadAction extends ActionSupport {
 private File myFile;
 private String myFileContentType;
 private String myFileFileName;
 private String AllowedType;

 public File getMyFile() {
  return myFile;
 }

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

 public String getMyFileContentType() {
  return myFileContentType;
 }

 public void setMyFileContentType(String myFileContentType) {
  this.myFileContentType = myFileContentType;
 }

 public String getMyFileFileName() {
  return myFileFileName;
 }

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

 public String getAllowedType() {
  return AllowedType;
 }

 public void setAllowedType(String allowedType) {
  AllowedType = allowedType;
 }
  
 public String execute() throws Exception {
  
  String imageFileName = new Date().getTime()  +  getExtention(getMyFileFileName());
  String path = ServletActionContext.getServletContext().getRealPath("/")+"/images";
  ServletActionContext.getRequest().setAttribute("imageFileName", imageFileName);
  
  FileInputStream fis = new FileInputStream(getMyFile());
  FileOutputStream fos = new FileOutputStream(path+"/"+ imageFileName);
  byte[] b = new byte[1024];
  int len = 0;
  while((len = fis.read(b))!=-1){
   fos.write(b, 0, len);
  }
  fis.close();
  fos.close();
  return SUCCESS;
 }
 
 //获得文件的后缀
  private static String getExtention(String fileName){
         int pos = fileName.lastIndexOf( "." );
         return fileName.substring(pos);
    }

 
}

 

在FileUploadAction中我分别写了setMyFileContentType、setMyFileFileName、setMyFile和 setCaption四个Setter方法,后两者很容易明白,分别对应FileUpload.jsp中的<s:file/> 和<s:textfield/>标志。但是前两者并没有显式地与任何的页面标志绑定,那么它们的值又是从何而来的呢?其实,<s:file/>标志不仅仅是绑定到myFile,还有myFileContentType(上传文件的MIME类型)和 myFileFileName(上传文件的文件名,该文件名不包括文件的路径)。因此,<s:file name="xxx" />对应Action类里面的xxx、xxxContentType和xxxFileName三个属性。

FileUploadAction作用是将浏览器上传的文件拷贝到WEB应用程序的UploadImages文件夹下,新文件的名称是由系统时间与上传文件的后缀组成,该名称将被赋给imageFileName属性,以便上传成功的跳转页面使用。

下面我们就来看看上传成功的页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Insert title here</title>
 </head>
 <body>
  <div style="padding: 3px; border: solid 1px #cccccc; text-align: center">
   <img src="images/${imageFileName}" />
   <br />
  </div>
 </body>
</html>

然后是Action的配置文件:

<action name="upload" class="com.student.action.UpLoadAction1">
   <interceptor-ref name="fileUpload">
    <param name="allowedTypes">
     image/bmp,image/png,image/gif,image/jpeg,image/pjpeg
    </param>
    <param name="maximumSize">1048576</param>
   </interceptor-ref>
   <interceptor-ref name="defaultStack" />
   <result name="success">/success.jsp</result>
   <result name="input">/upload.jsp</result>
  </action>

最后是web.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
   
    <filter>
        <filter-name> struts-cleanup </filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ActionContextCleanUp
        </filter-class>
    </filter> 
 
  <filter>
      <filter-name>struts2</filter-name>
      <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>
 
 <filter-mapping>
        <filter-name> struts-cleanup </filter-name>
        <url-pattern> /* </url-pattern>
    </filter-mapping>
 
 <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>

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



 
清单7 FileUpload页面

选择图片文件,填写Caption并按下Submit按钮提交,出现图示页面:


 

 

清单8 上传成功页面

更多配置

在运行上述例子,如果您留心一点的话,应该会发现服务器控制台有如下输出:


 

Mar 20 , 2007 4 : 08 : 43 PM org.apache.struts2.dispatcher.Dispatcher getSaveDir
INFO: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
Mar 20 , 2007 4 : 08 : 43 PM org.apache.struts2.interceptor.FileUploadInterceptor intercept
INFO: Removing file myFile C:\Program Files\Tomcat 5.5 \work\Catalina\localhost\Struts2_Fileupload\upload_251447c2_1116e355841__7ff7_00000006.tmp

 

清单9 服务器控制台输出

上述信息告诉我们,struts.multipart.saveDir没有配置。struts.multipart.saveDir用于指定存放临时文件的文件夹,该配置写在struts.properties文件中。例如,如果在struts.properties文件加入如下代码:

struts.multipart.saveDir = /tmp

 

清单10 struts配置

这样上传的文件就会临时保存到你根目录下的tmp文件夹中(一般为c:\tmp),如果此文件夹不存在,Struts 2会自动创建一个。

错误处理

上述例子实现的图片上传的功能,所以应该阻止用户上传非图片类型的文件。在Struts 2中如何实现这点呢?其实这也很简单,对上述例子作如下修改即可。

首先修改FileUpload.jsp,在<body>与<s:form>之间加入“<s:fielderror />”,用于在页面上输出错误信息。

然后修改struts.xml文件,将Action fileUpload的定义改为如下所示:

< action name ="fileUpload" class ="tutorial.FileUploadAction" > 
            < interceptor-ref name ="fileUpload" > 
                < param name ="allowedTypes" > 
                    image/bmp,image/png,image/gif,image/jpeg
                </ param > 
            </ interceptor-ref > 
            < interceptor-ref name ="defaultStack" />            
            < result name ="input" > /FileUpload.jsp </ result > 
            < result name ="success" > /ShowUpload.jsp </ result > 
        </ action >

 

清单11 修改后的配置文件

显而易见,起作用就是fileUpload拦截器的allowTypes参数。另外,配置还引入defaultStack它会帮我们添加验证等功能,所以在出错之后会跳转到名称为“input”的结果,也即是FileUpload.jsp。

发布运行应用程序,出错时,页面如下图所示:

 

 

 清单12 出错提示页面

上面的出错提示是Struts 2默认的,大多数情况下,我们都需要自定义和国际化这些信息。通过在全局的国际资源文件中加入“struts.messages.error.content.type.not.allowed=The file you uploaded is not a image”,可以实现以上提及的需求。

实现之后的出错页面如下图所示:



 清单13 自定义出错提示页面

同样的做法,你可以使用参数“maximumSize”来限制上传文件的大小,它对应的字符资源名为:“struts.messages.error.file.too.large”。

字符资源“struts.messages.error.uploading”用提示一般的上传出错信息。

 

 

其中UpLoadAction还可以写成如下形式:

package com.student.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;


public class UpLoadAction1 extends ActionSupport {
 private static final int BUFFER_SIZE = 2 * 1024;
 private File myFile;
 private String myFileContentType;
 private String myFileFileName;

 public File getMyFile() {
  return myFile;
 }

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

 public String getMyFileContentType() {
  return myFileContentType;
 }

 public void setMyFileContentType(String myFileContentType) {
  this.myFileContentType = myFileContentType;
 }

 public String getMyFileFileName() {
  return myFileFileName;
 }

 public void setMyFileFileName(String myFileFileName) {
  this.myFileFileName = myFileFileName;
 }
 
  
 public String execute() throws Exception {  
  File src = getMyFile();
  String dstPath = ServletActionContext.getServletContext().getRealPath("/")+"/images";
  String imageFileName = getImageFileName(getMyFileFileName());
  ServletActionContext.getRequest().setAttribute("imageFileName", imageFileName);
  File dst = new File(dstPath+"/"+imageFileName);
  copy(src, dst);
  return SUCCESS;
 }
 
 //将指定的文件拷贝到指定的目录
 public static void copy(File src,File dst){
  InputStream in = null;
  OutputStream out = null;
  try {
   in = new BufferedInputStream(new FileInputStream(src),BUFFER_SIZE);
   out = new BufferedOutputStream(new FileOutputStream(dst),BUFFER_SIZE);
   byte[] b = new byte[1024];
   int len = 0;
   while((len = in.read(b))!= -1){
    out.write(b, 0, len);
   }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }finally{
    try {
    if(null!=in){
         in.close();
     }
     if(null!=out) {
         out.close();
     }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 
 //根据当前时间给文件取指定的名字
 public static String getImageFileName(String fileName){
  return new Date().getTime() + getExtention(fileName);
 }
 
 //获取文件的后缀
 public static String getExtention(String fileName){
  int pos = fileName.lastIndexOf(".");
  return fileName.substring(pos);
 }

 
}

 

 

 

来自:http://blog.sina.com.cn/s/blog_6145ed810100eb82.html

  • 大小: 2.8 KB
  • 大小: 9.1 KB
  • 大小: 10.1 KB
  • 大小: 23.6 KB
  • 大小: 11.5 KB
分享到:
评论

相关推荐

    struts2文件上传下载源代码

    在Struts2中,文件上传和下载是常见的功能需求,特别是在处理用户交互和数据交换时。这篇博客文章提供的"struts2文件上传下载源代码"旨在帮助开发者理解和实现这些功能。 文件上传功能允许用户从他们的设备上传文件...

    struts2文件上传jar

    这个压缩包包含了实现Struts2文件上传所需的全部jar包,这些库文件对于理解和实现文件上传功能至关重要。 首先,我们要了解Struts2文件上传的基本流程。当用户通过表单提交包含文件输入字段的请求时,Struts2框架会...

    简单易懂的struts2文件上传

    在Struts2中,文件上传功能是一个常见的需求,例如用户可能需要上传图片、文档或其他类型的文件。本教程将深入浅出地讲解如何在Struts2中实现文件上传,并提供一个简单的实例来帮助理解。 1. **Struts2文件上传概述...

    struts2文件上传

    Struts2 文件上传是Web开发中的一个重要功能,它允许用户从他们的本地计算机向服务器传输文件。在Struts2框架中,文件上传是通过特定的拦截器实现的,这些拦截器处理了文件上传请求并提供了安全性和大小限制。下面将...

    Struts2文件上传

    Struts2文件上传是Web开发中常见的功能,用于允许用户在网页上选择并上传本地文件到服务器。在Java Web环境中,Struts2框架提供了一套完整的解决方案来处理文件上传请求。下面将详细介绍Struts2文件上传的核心概念、...

    struts 2文件上传

    在Struts 2中,文件上传功能是通过使用Struts 2的插件机制来实现的,这使得开发者能够方便地处理用户上传的文件。下面将详细讨论Struts 2文件上传的相关知识点。 ### 1. Struts 2文件上传原理 文件上传是基于HTTP...

    Struts2文件上传带进度条页面无刷新

    "Struts2文件上传带进度条页面无刷新"的实现涉及多个技术点,包括Struts2的文件上传插件、AJAX异步通信以及前端进度条展示。 首先,Struts2的文件上传依赖于`struts2-upload-plugin`。这个插件扩展了Struts2的核心...

    Struts2之struts2文件上传详解案例struts011

    在这个"Struts2之struts2文件上传详解案例struts011"中,我们将深入探讨如何实现这一功能。 首先,我们需要了解Struts2中的Action类,它是处理用户请求的核心组件。为了支持文件上传,我们需要创建一个继承自`org....

Global site tag (gtag.js) - Google Analytics