Struts2使用注解实现文件的下传与上载(一)

Struts2使用注解实现文件的上传与下载(一)

        在Struts2中借助Commons FileUpload组件很容易实现文件的上传与下载,Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中,从而我们能够以本地文件方式操作浏览器上传文件。但是这些例子大多需要在struts.xml中进行配置,比较麻烦,好在Struts2中提供了struts2-convention-plugin插件,可以在程序中使用注解对Action进行配置,使之更加灵活。

        下面介绍使用注解实现文件的上传:

         1. 添加依赖的jar包

Struts2使用注解实现文件的下传与上载(一)

           2. 配置struts.xml文件,这里的struts文件基本上不需要配置,如下即可:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />
	<constant name="struts.devMode" value="true" />
	<constant name="struts.convention.package.locators" value="action" />
	<!-- 指定允许上传的文件最大字节数,默认值是2097152(2M),使用struts常量扩大默认上传文件大小 -->
	<constant name="struts.multipart.maxSize" value="104857600"></constant>

</struts>
        3. 编写文件上传的Action:FileUploadAction.java

package com.figo.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ActionSupport;

@Action("fileUpload")
@InterceptorRefs(value = { @InterceptorRef("fileUploadStack") })
@Results({ @Result(name = "success", location = "/result.jsp") })
public class FileUploadAction extends ActionSupport {

	private static final long serialVersionUID = 572146812454l;
	private static final int BUFFER_SIZE = 16 * 1024;
	// 封装上传文件域的属性
	private File upload;
	// 封装上传文件类型的属性
	private String contentType;
	// 封装上传文件名的属性
	private String fileName;
	private String storageFileName;

	// private String storagePath;

	// since we are using <s:file name="upload" ... /> the File itself will be
	// obtained through getter/setter of <file-tag-name>
	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getFileName() {
		return fileName;
	}

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

	// since we are using <s:file name="upload" .../> the file name will be
	// obtained through getter/setter of <file-tag-name>FileName
	public String getUploadFileName() {
		return fileName;
	}

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

	public String getStorageFileName() {
		return storageFileName;
	}

	public void setStorageFileName(String storageFileName) {
		this.storageFileName = storageFileName;
	}

	// since we are using <s:file name="upload" ... /> the content type will be
	// obtained through getter/setter of <file-tag-name>ContentType
	public String getUploadContentType() {
		return contentType;
	}

	public void setUploadContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getContentType() {
		return contentType;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public void copy(File src, File dst) {
		try {
			InputStream in = null;
			OutputStream out = null;
			try {
				in = new BufferedInputStream(new FileInputStream(src),
						BUFFER_SIZE);
				out = new BufferedOutputStream(new FileOutputStream(dst),
						BUFFER_SIZE);
				byte[] buffer = new byte[BUFFER_SIZE];
				while (in.read(buffer) > 0) {
					out.write(buffer);
				}
			} finally {
				if (null != in) {
					in.close();
				}
				if (null != out) {
					out.close();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getExtention(String fileName) {
		int pos = fileName.lastIndexOf(".");
		return fileName.substring(pos);
	}

	@Override
	public String execute() throws Exception {
		// storageFileName = new Date().getTime() + getExtention(fileName);
		storageFileName = fileName;
		System.out.println("FileName: " + fileName);
		System.out.println("ContentType: " + contentType);
		System.out.println("File: " + upload);
		File storageFile = new File(ServletActionContext.getServletContext()
				.getRealPath("/upload") + "/" + storageFileName);
		copy(upload, storageFile);

		return SUCCESS;
	}

}
       FileUploadAction作用是将浏览器上传的文件拷贝到WEB应用程序的upload文件夹下。

       4. 编写文件上传的表单页面 upload.jsp:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>File Upload</title>
</head>
<body>
	<s:form action="fileUpload" method="post" enctype="multipart/form-data">
		<s:file name="upload" label="File" />
		<s:submit />
	</s:form>
</body>
</html>
       将表单的提交方式设为POST,然后将enctype设为multipart/form-data, <s:file/>标志将文件上传控件绑定到Action的upload属性。

        5. 结果返回页面 result.jsp:

<%@ page language="java" contentType="text/html;charset=utf-8"
	pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>File upload success</title>
</head>
<body>

	File
	<s:property value="fileName" />
	upload success.
	<br /> Saved as
	<s:property value="storageFileName" />
	<br /> File:
	<s:property value="upload" />
	<br /> ContentType:
	<s:property value="contentType" />

</body>
</html>

        6. 配置web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Upload</display-name>
  
  <filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.figo.action</param-value>
       	</init-param>  
	</filter>

	<filter> 
        <filter-name>struts-cleanup</filter-name> 
        <filter-class> 
            org.apache.struts2.dispatcher.ActionContextCleanUp
        </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.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

        重点是在filter里添加<init-param>,actionPackages为Action文件所在的包。

        7. 页面测试:

        文件上传页面:

Struts2使用注解实现文件的下传与上载(一)

        文件上传返回结果:

Struts2使用注解实现文件的下传与上载(一)

        因为是在eclipse工程里进行的测试,所以文件保存在了临时文件里,如果是真正发布的话,上传的文件就会保存到预先设置好的目录中。

        注:

        1. struts2默认最大只能上传2M的文件,可以在struts.xml中扩大默认文件上传的大小。

        2. 总结常用的注解如下:

        Namespace:指定命名空间。

        ParentPackage:指定父包。

        Result:提供了Action结果的映射(一个结果的映射)。

        Results:“Result”注解列表。

        ResultPath:指定结果页面的基路径。

        Action:指定Action的访问URL。

        Actions:“Action”注解列表。

        ExceptionMapping:指定异常映射(映射一个声明异常)。

        ExceptionMappings:一级声明异常的数组。

        InterceptorRef:拦截器引用。

        InterceptorRefs:拦截器引用组。

       这里只是给大家起个抛砖引玉的效果,程序本身很简单,主要是配置,下一篇介绍零配置文件下载。

       源代码下载链接:http://download.csdn.net/detail/sxwyf248/4462899