Struts2文件上传(全)

一、单文件上传

上传表单页面:select.jsp

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>上传表单页面</title>
</head>
<body>
	<h3>Struts2基于表单的文件上传</h3>
	<s:form action="upload" method="post" theme="simple" enctype="multipart/form-data">
		输入账号:<s:textfield name="uid"/><br/><br/><!-- 文本 -->
		选择头像:<s:file name="headImage" label="选择上传的文件"/><!-- 要上传的文件 -->
		<s:submit value="提交"/>
		<s:fielderror/>
	</s:form>
</body>
</html>

如下所示的上传显示界面:

当文件上传页面提交请求时,请求发送到wq.action,这是一个Struts2的Action,该Action处理上传请求,具体的UploadAction类代码如下:

package cn.tedu.action;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.tedu.web.BaseAction;

@Controller
@Scope("prototype")
public class UploadAction extends BaseAction{
	private String uid;		//账号
	private File headImage; //上传的文件
	private String headImageContentType;//文件类型
	private String headImageFileName;//文件名
	public String getUid() {
		return uid;
	}
	public void setUid(String uid) {
		this.uid = uid;
	}
	public File getHeadImage() {
		return headImage;
	}
	public void setHeadImage(File headImage) {
		this.headImage = headImage;
	}
	public String getHeadImageContentType() {
		return headImageContentType;
	}
	public void setHeadImageContentType(String headImageContentType) {
		this.headImageContentType = headImageContentType;
	}
	public String getHeadImageFileName() {
		return headImageFileName;
	}
	public void setHeadImageFileName(String headImageFileName) {
		this.headImageFileName = headImageFileName;
	}
	
	//上传的时候调用
	public String up(){
		// 上传文件的保存位置在“/image”,该位置在tomcat服务器的“webapps”之中
        String  realpath= ServletActionContext.getServletContext().getRealPath("/image");
        // 声明文件目录image,如果文件名不存在就建一个
        File file = new File(realpath);
        if(!file.exists()){
        	file.mkdirs();
        }
        //实现文件上传
        try {
			FileUtils.copyFile(headImage, new File(file, headImageFileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
        return SUCCESS;
	}
	
}

需要注意的是,上面的Action除了包含两个表单域的name属性外,还包含headImageContentType和headImageFileName两个属性,这两个属性分别能用于封装上传文件的文件类型、上传文件的文件名。可以这样认为:如果表单中包含一个name属性为xxx的文件域,则对应的Action需要使用3个属性来封装文件域信息:

  1. 类型为java.io.File的xxx属性来封装文件;
  2. 类型为String的xxxFileName属性封装了该文件域对应的文件名;
  3. 类型为String的xxxContentType属性封装了该文件域对应的文件类型

所以,在Action的up方法中,可以直接通过这3个属性获取上传文件的文件、文件名、文件类型。

(3) 接下来进行UploadAction的配置(struts.xml文件配置),具体代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!--指定国际化资源文件(下一章会讲到)-->
	<constant name="struts.custom.i18n.resources" value="messageResource"/>
	<!--设置Struts应用的解码集-->
    <constant name="struts.i18n.encoding" value="utf-8"/>
    
	<package namespace="/" name="default" extends="struts-default">
		<!-- 文件上传主页面 -->
		<action name="wq">
			<result>/select.jsp</result>
		</action>
		
		<action name="upload" class="uploadAction" method="up">
			<result name="success">/uploadSuccess.jsp</result>
		</action>
	</package>
	
</struts>

由于是整合了spring,所以spring-web.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
	
	<!-- spring的组件扫描 -->
	<context:component-scan base-package="cn.tedu"/>
	
</beans>

导包:

最后写一个上传成功页面(uploadSuccess.jsp)

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>上传成功页面</title>
</head>
<body>
	<h3>上传成功</h3>
	用户账号:<s:property value="uid"/><br/>
	您的头像:<img src="<s:property value="'image/' + headImageFileName"/>" alt="图像无法显示"/>
</body>
</html>

上传成功后会显示上传的图片和用户账号

上传过程图:

1.选择图片

2.确认选择

3.提交之后,显示上传成功

上传的图片保存位置如下:

--------------------------------------------------------------------------------------------------------------

二、拦截器实现文件的过滤

Struts2提供了一个名为fileUpload拦截器,通过配置该拦截器可以轻松地实现文件过滤。为了让fileUpload拦截器起作用,只需要在处理文件上传的Action中配置该拦截器引用即可。
配置fileUpload拦截器时可以指定如下两个参数:

  1. allowTypes:该参数指定允许上传文件的类型,多个文件类型之间以英文逗号隔开;
  2. maximumSize:该参数指定允许上传文件的大小,单位是字节。

  当文件过滤失败后,系统自动转入input逻辑视图,因此必须为Action配置名为input的逻辑视图。

(1) 通过拦截器来实现文件过滤的struts.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!--指定国际化资源文件(下一章会讲到)-->
	<constant name="struts.custom.i18n.resources" value="messageResource"/>
	<!--设置Struts应用的解码集  指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
    <constant name="struts.i18n.encoding" value="utf-8"/>
    <!-- 上传文件的总大小(可能上传多个)该属性指定Struts 2文件上传中整个请求内容允许的最大字节数 
    	而拦截器中配置的是限制单个上传文件的大小-->
    <constant name="struts.multipart.maxSize" value="1000000000"/>
    
    
    <!--package中加入拦截器-->
	<package namespace="/" name="default" extends="struts-default">
		<interceptors>
			<!--配置拦截器栈-->
			<interceptor-stack name="myStack">
				 <!--配置fileUpload拦截器-->
				 <interceptor-ref name="fileUpload">
				  	<!--配置允许上传文件的类型(此处要注意的是png图片在ie浏览器中是image/x-png类型)-->
				 	<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg,image/jpg,image/x-png,image/pjpeg</param>
					<!--配置允许上传文件大小拦截器,单位是字节(2的16次幂=65536(64k))-->
				 	<param name="maximumSize">65536</param>
				 </interceptor-ref>
				 <interceptor-ref name="defaultStack"/>
			</interceptor-stack>
		</interceptors>
		<!-- 拦截器配置完毕 -->
		
		
		<!-- 文件上传主页面 -->
		<action name="wq">
			<result>/select.jsp</result>
		</action>
		
		<action name="upload" class="uploadAction" method="up">
			<!-- 使用拦截器 -->
			<interceptor-ref name="myStack"/>
			<result name="success">/uploadSuccess.jsp</result>
			
			<!--过滤失败,系统会转入input逻辑视图,这里配置其返回选择界面-->
			 <result name="input">/select.jsp</result>
		</action>
	</package>
	
</struts>

格式不对和容量大于64kb会上传失败,直接返回重新选择的界面。如果上传失败,系统需要回应上传失败信息。因此,需要在文件上传页select.jsp页面中加上“<s:filederror/>”------->(我直接加到了select.jsp代码中,你可以回看上面)
(a) 例如:文件格式不对

提交之后页面显示如下:

(b)文件大小超过了限额(本案例文件大小限制64KB)

提交之后页面显示如下:

-------------------------------------------------------------------------------------------------

三、文件上传的常量配置
上传文件时,系统默认使用web服务器的工作路径作为临时路径。为了避免文件上传时候使用Web服务器的工作路径作为临时路径,则应该设置struts.multipart.saveDir常量。该常量指定上传文件的临时保存路径。该常量配置示例如下:

 <constant name="struts.multipart.saveDir" value="HOME/....(写上路径)..."/>

Struts2配置文件中的struts.multipart.saveDir起什么作用? 
原来初步感觉这个文件夹就服务端保存上传文件的文件夹,不过根本不是这么回事! 
这个文件夹只是用来保存上传文件的“临时路径”,文件上传完毕后就会从此路径移除。 
如果不配置将使用默认的 javax.servlet.context.tempdir 来保存临时文件。 
所以这个目录设不设无所谓

此外,还有一个文件上传的常量struts.multipart.maxSize。该常量指定struts.mutipart.maxSize。该常量指定在struts2文件上传中整个请求内容所允许的最大字节数,默认为2097152(即2MB)。该常量配置示例如下:

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

该属性是上传文件的总大小(可能上传多个),该属性指定Struts 2文件上传中整个请求内容允许的最大字节数,而拦截器中配置的是限制单个上传文件的大小

四、Struts2多文件上传

在Struts2应用中,如果一个页面有多个文件域需要实现上传,则可以为每个文件域提供三个属性,分别封装该文件域对应的文件名、文件类型和文件内容。多文件上传与单文件上传没有什么区别,仅仅是利用数组同时上传多个文件的方式。在处理多文件上传时,要注意改变的是,在Action类中,需要使用三个数组分别封装文件名、文件类型和文件内容

struts.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!--指定国际化资源文件(下一章会讲到)-->
	<constant name="struts.custom.i18n.resources" value="messageResource"/>
	<!--设置Struts应用的解码集  指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
    <constant name="struts.i18n.encoding" value="utf-8"/>
    <!-- 上传文件的总大小(可能上传多个)该属性指定Struts 2文件上传中整个请求内容允许的最大字节数 
    	而拦截器中配置的是限制单个上传文件的大小-->
    <constant name="struts.multipart.maxSize" value="1000000000"/>
    
    
    <!--package中加入拦截器-->
	<package namespace="/" name="default" extends="struts-default">
		<interceptors>
			<!--配置拦截器栈-->
			<interceptor-stack name="myStack">
				 <!--配置fileUpload拦截器-->
				 <interceptor-ref name="fileUpload">
				  	<!--配置允许上传文件的类型(此处要注意的是png图片在ie浏览器中是image/x-png类型)-->
				 	<param name="allowedTypes">image/x-png,image/bmp,image/gif,image/jpeg,image/jpg</param>
					<!--配置允许上传文件大小拦截器,单位是字节(2的16次幂=65536(64k))-->
				 	<param name="maximumSize">65536</param>
				 </interceptor-ref>
				 <interceptor-ref name="defaultStack"/>
			</interceptor-stack>
		</interceptors>
		<!-- 拦截器配置完毕 -->
		
		<!-- 多文件上传 -->
		<!-- 文件上传主页面 -->
		<action name="wq1">
			<result>/select1.jsp</result>
		</action>
		<action name="upload1" class="uploadAction1" method="up">
			<!-- 使用拦截器 -->
			<interceptor-ref name="myStack"/>
			<result name="success">/uploadSuccess1.jsp</result>
			
			<!--过滤失败,系统会转入input逻辑视图,这里配置其返回选择界面-->
			 <result name="input">/select1.jsp</result>
		</action>
	</package>
	
</struts>

多文件上传显示页面:

代码如下:

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>上传表单页面</title>
</head>
<body>
	<h3>Struts2基于表单的多文件上传</h3>
	<s:form action="upload1" method="post" theme="simple" enctype="multipart/form-data">
		输入账号:<s:textfield name="uid"/><br/><br/><!-- 文本 -->
		多个头像1:<s:file name="headImage" label="选择上传的文件"/><br/><br/><!-- 要上传的文件 -->
		多个头像2:<s:file name="headImage" label="选择上传的文件"/><br/><br/><!-- 要上传的文件 -->
		<s:submit value="提交"/>
		<s:fielderror/>
	</s:form>
</body>
</html>

控制器UploadAction:

package cn.tedu.action;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.tedu.web.BaseAction;

@Controller
@Scope("prototype")
public class UploadAction1 extends BaseAction{
	private String uid;		//账号
	private List<File> headImage; //上传的文件
	private List<String> headImageContentType;//文件类型
	private List<String> headImageFileName;//文件名
	private String savePath;//保存路径
	public String getUid() {
		return uid;
	}
	public void setUid(String uid) {
		this.uid = uid;
	}
	public List<File> getHeadImage() {
		return headImage;
	}
	public void setHeadImage(List<File> headImage) {
		this.headImage = headImage;
	}
	public List<String> getHeadImageContentType() {
		return headImageContentType;
	}
	public void setHeadImageContentType(List<String> headImageContentType) {
		this.headImageContentType = headImageContentType;
	}
	public List<String> getHeadImageFileName() {
		return headImageFileName;
	}
	public void setHeadImageFileName(List<String> headImageFileName) {
		this.headImageFileName = headImageFileName;
	}
	public String getSavePath() {
		return savePath;
	}
	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}
	//上传的时候调用
	public String up(){
		savePath = "moreImage";
		String realPath = ServletActionContext.getServletContext().getRealPath("/" + savePath);
		// 上传文件的保存位置在“/moreImage”,该位置在tomcat服务器的“webapps”之中
        // 声明文件目录moreImage,如果文件名不存在就建一个
        File file = new File(realPath);
        if(!file.exists()){
        	file.mkdirs();
        }
        //实现文件上传
        try {
        	 for(int i = 0; i< headImage.size(); i++){
        		 FileUtils.copyFile(headImage.get(i), new File(file, headImageFileName.get(i)));
             }
		} catch (IOException e) {
			e.printStackTrace();
		}
        return SUCCESS;
	}
	
}

上传成功页面:

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>上传成功页面</title>
</head>
<body>
	<h3>上传成功</h3>
	用户账号:<s:property value="uid"/><br/>
	
	文件路径:<s:property value="savePath"/><br>
	
	<!-- 
	根据上传文件的文件名,在页面上显示上传的图片 采用相对路径,不要使用绝对路径
	在Action中得到了上传文件的目录savePath,若没有目录
	ServletActionContext.getServletContext().getRealPath("");
	则在该页面中直接使用<s:property />作为img的相对路径
	img中采用了EL表达式 并结合struts标签完成路径的拼接,
	<s:property />表示headImageFileName集合中的每一个文件名,即每一个元素
	-->  
         文件为:<s:property value="headImageFileName"/><br> 
   ----------遍历文件:----------<br> 
	<s:iterator value="headImageFileName">
		<img src="${savePath}/<s:property /> "/>
	</s:iterator>

</body>
</html>

选择上传文件:

上传成功:

注意:文件图片在显示的时候,img标签建议采用相对路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒--

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值