- 浏览: 308908 次
最新评论
-
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
hunanjun000:
《研磨struts2》第四章 Action 之 4.5 Action的其它重要知识
13.1 文件上传
13.1.1 概述
在开发基于Web的应用的时候,经常会碰到需要实现文件上传、下载的功能,比如编辑某个商品,需要给它上传一个图片等等。
不使用Struts2的话,可以有很多种方式来实现文件上传,比如使用Apache的Common-FileUpload等。但是这些传统的方式,实现起来非常麻烦,需要写很多代码来进行控制。
现在使用Struts2来实现文件上传的功能,会更加简单和方便,事实上,Struts2的文件上传功能,默认就是基于Common-FileUpload来实现的,只不过比直接使用Common-FileUpload来得更简单。
13.1.2使用Struts2实现文件上传
1:fileUpload拦截器
使用Struts2来实现文件上传,需要使用Struts2预定义的fileUpload拦截器。简要的看看在struts-default.xml中的配置,示例如下:
- <package name="struts-default" abstract="true">
- …
- <interceptors>
- …
- <interceptor name="fileUpload"
- ss="org.apache.struts2.interceptor.FileUploadInterceptor"/>
- …
- <interceptor-stack name="defaultStack">
- …
- <interceptor-ref name="fileUpload"/>
- …
- </interceptor-stack>
- </interceptors>
- <default-interceptor-ref name="defaultStack"/>
- </package>
上面列出了struts-default.xml中跟fileUpload拦截器有关的部分。首先,Struts2有一个预定义拦截器叫fileUpload;然后,defaultStack拦截器栈引用了fileUpload拦截器;最后,struts-default包又将defaultStack拦截器声明为自己的默认拦截器引用。
因此,如果我们的包继承了struts-default包,而我们的Action类又没有声明自己的拦截器引用的话,使用的就是defaultStack拦截器栈,从而引用了fileUpload拦截器。
2:实现上传页面
如果一个表单中,包含了文件上传的表单域,则一定要把整个表单enctype属性设置为multipart/form-data。形如:
- <%@ page language="java" contentType="text/html; charset=gb2312"
- pageEncoding="gb2312"%>
- <!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=gb2312">
- <title>Insert title here</title>
- </head>
- <body>
- <form action="/helloworld/uploadAction.action" method="post"
- enctype="multipart/form-data">
- 文件名称:<input type="text" name="fileName"><br>
- 文件:<input type="file" name="myFile"><br>
- <input type="submit" value="提交">
- </form>
- </body>
- </html>
在这个文件里,指定了<form>元素的enctype属性为multipart/form-data,还用了一个type为file的输入域,它会在页面上生成一个文件选择框。整个页面运行如下:
图13.1 文件上传页面
在这个页面上文件域里面,在输入框后面多了一个“浏览”按钮,点击这个浏览按钮,就会弹出文件选择框。
3:实现文件上传Action
这个Action和其他的Action没有太多特殊之处,使用一个String属性fileName来准备接收前一个页面的fileName文本框的值,然后使用一个File属性myFile来准备接收前一个页面的myFile文件框传过来的文件的值。
在execute方法中,我们可以随意存储上传的文件,本例只是把它放到了e盘的temp目录下,并以传入的fileName作为保存的文件名。
示例代码如下:
- public class UploadAction extends ActionSupport{
- private String fileName;
- private File myFile;
- public String getFileName() {
- return fileName;
- }
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
- public File getMyFile() {
- return myFile;
- }
- public void setMyFile(File myFile) {
- this.myFile = myFile;
- }
- public String execute()throws Exception{
- //先把上传过来的文件存放到e盘temp目录下,以传入的fileName为名字
- OutputStream output = null;
- InputStream input = null;
- try{
- output = new FileOutputStream("e:/temp/"+fileName);
- //建立一个1k大小的缓冲区
- byte[] bs = new byte[1024];
- //将上传过来的文件输出到output中
- input = new FileInputStream(myFile);
- int length = 0;
- //length=input.read(bs)这句话中,length=-1代表了读到文件结尾
- while ((length=input.read(bs))>0){
- output.write(bs, 0, length);
- }
- }finally{
- input.close();
- output.close();
- }
- return SUCCESS;
- }
- }
注意:如何操作上传的文件,完全是I/O的知识,为了保持实例的简单,只是采用了最简单的方式,把内容存放在一个绝对路径表示的文件里面,当然还可以将上传的文件存储在web服务器上,甚至数据库中。
4:映射这个Action
在struts.xml中对这个Action进行配置,可以看到没有任何特异之处,只是指出了Action名称和对应的实现类,以及上传之后要跳转到的页面。
5:上传之后的页面
由于上传的文件在Action中已经被正确处理了,所以这个上传之后的页面没有任何特殊的作用,只是显示一下,表示上传成功了,示例代码如下:
- <%@ page language="java" contentType="text/html; charset=gb2312"
- pageEncoding="gb2312"%>
- <%@taglib prefix="s" uri="/struts-tags" %>
- <!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=gb2312">
- <title>Insert title here</title>
- </head>
- <body>
- 成功上传文件<s:property value="fileName"/>
- </body>
- </html>
运行测试一下,在文件上传页面选择要上传的文件,然后点击提交按钮,会发现文件会上传,并以我们指定的文件名称保存到我们指定的文件夹下去了。
13.1.3获取文件的更多信息
Struts2支持用更多的属性来获取有关上传文件的真实文件名和文件类型。
比如:表单中包含了一个叫xyz的文件域,也就是类似于<input type=”file” name=”xyz”,那么可以用三个属性来获取上传文件的信息:
- File类型的属性xyz用来获取文件内容。
- String类型的属性xyzFileName用来获取文件的真实文件名。
- String类型的属性xyzContentType属性用来获取文件的类型。
将处理上传文件的Action类修改一下,添加两个属性:myFileFileName和myFileContentType,以及他们对应的getter/setter方法,来尝试获得文件的真实文件名和文件类型。
另外,保存文件的时候,也使用文件的真实名称,示例代码如下:
- public class UploadAction extends ActionSupport{
- private String fileName;
- private File myFile;
- private String myFileFileName;
- private String myFileContentType;
- public String getMyFileFileName() {
- return myFileFileName;
- }
- public void setMyFileFileName(String myFileFileName) {
- this.myFileFileName = myFileFileName;
- }
- public String getMyFileContentType() {
- return myFileContentType;
- }
- public void setMyFileContentType(String myFileContentType) {
- this.myFileContentType = myFileContentType;
- }
- public String getFileName() {
- return fileName;
- }
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
- public File getMyFile() {
- return myFile;
- }
- public void setMyFile(File myFile) {
- this.myFile = myFile;
- }
- public String execute()throws Exception{
- System.out.println("用户传入的文件名:"+fileName);
- System.out.println("上传文件的真实文件名:"+myFileFileName);
- System.out.println("上传文件的类型:"+myFileContentType);
- System.out.println("这个文件的文件名是什么?"+myFile.getName());
- //把上传过来的文件存放到e盘temp目录下,以真实的文件名作为名字
- OutputStream output = null;
- InputStream input = null;
- try{
- output = new FileOutputStream("e:/temp/"+myFileFileName);
- //建立一个1k大小的缓冲区
- byte[] bs = new byte[1024];
- //将上传过来的文件输出到output中
- input = new FileInputStream(myFile);
- int length = 0;
- //length=input.read(bs)这句话中,length=-1代表了读到文件结尾
- while ((length=input.read(bs))>0){
- output.write(bs, 0, length);
- }
- }finally{
- input.close();
- output.close();
- }
- return SUCCESS;
- }
- }
运行测试一下,后台输出为:
注意其中“这个文件的文件名是什么?”,代码写的是输出myFile这个File对象的名字,由于myFile对象封装了上传文件的内容,因而某些朋友就认为这个文件就是我们上传的文件,从而认为它的getName方法就是返回的上传的这个文件的名字。
这是错误的,这个myFile文件是Struts2在上传过程中生成的临时文件,它的内容与上传文件相同,但是名字并不相同,它的名字是由Struts2临时生成的,形如“upload__5ab75acc_12c5f17ac7a__8000_00000001.tmp”这样的。
13.1.4限制文件的大小及类型
在文件上传的时候,有可能需要对文件的大小和类型做出限制。Struts2支持直接在fileUpload拦截器上设置参数来进行限制。
在引用fileUpload拦截器的时候,可以指定三个参数(指定<param>子元素):
- allowedTypes:指定允许上传的文件的类型,如果存在多种类型,以逗号隔开。注意:这里添的不是文件的扩展名,而是对应的ContentType,如果不知道某种文件的ContentType可以先上传一下试试,在后台输出ContentType来。
- maximumSize:指定允许上传的文件的最大字节数。
- allowedExtensions:指定允许上传的文件的扩展名。
如果上传的文件不满足以上的参数指定的条件,则会跳转到一个叫input的<result>上,一般input都会指回到提交之前的页面,也就是文件上传页面。
参数非常简单,但是配置比较怪异,fileUpload拦截器虽然在defaultStack拦截器栈上已经引用了,但是还可以在defaultStack拦截器栈之前再引用一次,然后在这次引用上指定参数,示例代码如下:
- <package name="helloworld" extends="struts-default">
- <action name="uploadAction" class="cn.javass.fileupload.UploadAction">
- <interceptor-ref name="fileUpload">
- <param name="allowedTypes">text/plain</param>
- <param name="maximumSize">1000</param>
- </interceptor-ref>
- <interceptor-ref name="defaultStack"/>
- <result name="input">/fileupload/fileupload.jsp</result>
- <result>/fileupload/success.jsp</result>
- </action>
- </package>
观察以上的<action>元素,要额外注意两点:
- 这个Action应该先引用fileUpload拦截器,然后引用defaultStack拦截器栈。
- 这个Action中还要有一个叫input的<result>,以备上传不成功时,Struts2跳转到提交前的页面。
还要稍微修改一下login.jsp,来显示不满足限制条件时的错误信息。只需要在合适的地方加上<s:fielderror/>来显示错误信息即可。形如:
- <%@ page language="java" contentType="text/html; charset=gb2312"
- pageEncoding="gb2312"%>
- <!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=gb2312">
- <title>Insert title here</title>
- </head>
- <body>
- <%@taglib prefix="s" uri="/struts-tags" %>
- <s:fielderror/>
- <form action="/helloworld/uploadAction.action" method="post"
- enctype="multipart/form-data">
- 文件名称:<input type="text" name="fileName"><br>
- 文件:<input type="file" name="myFile"><br>
- <input type="submit" value="提交">
- </form>
- </body>
- </html>
运行修改之后的文件上传功能,如果上传非txt文件,运行结果如下:
图13.2 fileUpload拦截器限制文件上传类型
如果上传大于1000字节的txt文件,运行结果如下:
图13.3 fileUpload拦截器限制文件上传大小
13.1.5上传超大的文件
Struts2在实现文件上传的时候,还有一个小问题,那就是默认上传文件的大小是不能超过2097152字节的。这个配置在struts2-core-2.1.8.1.jar文件里面,“\org\apache\struts2”文件夹下的default.properties文件里面,配置如下:
先来测试一下,看看是不是有这个问题。到文件上传页面,选择一个超过上述字节数的文件来上传看看,点击提交按钮,后台输出错误,示例如下:
注意上面加粗的那句话,明确告诉我们,上传的文件大小为3402567,大于配置的最大值2097152字节。
那么该怎么办呢?
方法很简单,只要覆盖这个默认设置就可以了,有两种方式,一种是在Struts.properties里面配置,另外一种就是在struts.xml里面配置。这里就以在struts.xml来配置为例,只要在struts.xml中加入如下的常量定义,示例代码如下:
设置上传文件的最大值为大约10M。再次测试运行看看,应该就可以正常上传了。
13.1.6在一个表单中上传多个文件
在实际开发中,经常会碰到需要在一个表单中上传多个文件的情况,比如为某文档添加附件,就可能要求在一个表单上添加多个附件。
对于在一个表单中上传多个文件的功能,使用Struts2也能轻松实现。只需要在提交页面上添加同名的多个文件输入域,然后在Action中对应使用File类型的数组去接收这些参数即可。
比如上面的示例,可以把上传文件页面改为:
- <%@ page language="java" contentType="text/html; charset=gb2312"
- pageEncoding="gb2312"%>
- <!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=gb2312">
- <title>Insert title here</title>
- </head>
- <body>
- <%@taglib prefix="s" uri="/struts-tags" %>
- <s:fielderror/>
- <form action="/helloworld/uploadAction.action" method="post"
- enctype="multipart/form-data">
- 文件:<input type="file" name="myFile"><br>
- 文件:<input type="file" name="myFile"><br>
- 文件:<input type="file" name="myFile"><br>
- 文件:<input type="file" name="myFile"><br>
- <input type="submit" value="提交">
- </form>
- </body>
- </html>
上例中,<form>表单中有多个同名的file输入域myFile。
在Action中,只要使用数组或List来操作就可以了,这里以数组为例来修改Action,示例代码如下:
- public class UploadAction extends ActionSupport{
- private File[] myFile;
- private String[] myFileFileName;
- public File[] getMyFile() {
- return myFile;
- }
- public void setMyFile(File[] myFile) {
- this.myFile = myFile;
- }
- public String[] getMyFileFileName() {
- return myFileFileName;
- }
- public void setMyFileFileName(String[] myFileFileName) {
- this.myFileFileName = myFileFileName;
- }
- public String execute()throws Exception{
- //把上传过来的文件存放到e盘temp目录下,以真实的文件名作为名字
- OutputStream output = null;
- InputStream input = null;
- try{
- for(int i=0;i<myFileFileName.length;i++){
- output = new FileOutputStream("e:/temp/"+myFileFileName[i]);
- //建立一个1k大小的缓冲区
- byte[] bs = new byte[1024];
- //将上传过来的文件输出到output中
- input = new FileInputStream(myFile[i]);
- int length = 0;
- //length=input.read(bs)这句话中,length=-1代表了读到文件结尾
- while ((length=input.read(bs))>0){
- output.write(bs, 0, length);
- }
- }
- }finally{
- input.close();
- output.close();
- }
- return SUCCESS;
- }
- }
然后就可以去运行测试了,看看上面的实现是不是真的能同时上传多个文件。但是要提醒一点,如果想要上传不同类型的文件,记得把前面示例的时候,在struts.xml中所作的限制设定去掉。
私塾在线网站原创《研磨struts2》系列
转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4121.html】
欢迎访问http://sishuok.com获取更多内容
发表评论
-
研磨struts2 目录贴
2012-08-24 12:12 163331.1 《研磨struts2》 第一章 Struts2 ... -
跟着cc学设计 之 研磨设计模式 视频教程 出炉了
2012-08-15 07:16 2研磨设计模式——跟着CC学设计系列精品课程,上线了! ... -
研磨struts2 目录
2012-07-30 21:15 2471.1 《研磨struts2》 第一章 Strut ... -
研磨struts2 目录
2012-07-30 16:54 361.1 《研磨struts2》 第一章 Stru ... -
《研磨struts2》A.2 struts.properties的配置 之 A.2.1 概述
2012-07-09 12:10 3055A.2.1 概述 如果我们希望覆盖在 ... -
《研磨struts2》附录A Struts2的配置 之 A.1 struts.xml的配置
2012-07-09 12:10 2710A.1 struts.xml的配置 A.1.1 ... -
《研磨struts2》第二十一章 零配置 之 21.3 通过注解来实现零配置
2012-07-06 08:07 291121.3 通过注解来实现零配置 21.3.1 ... -
《研磨struts2》第二十一章 零配置 之 21.2 约定大于配置
2012-07-05 10:44 245821.2 约定大于配置 21.2.1 约定 ... -
《研磨struts2》第二十一章 零配置 之 21.1 概述
2012-07-05 10:44 231321.1 概述 21.1.1 零配置概述 在 ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.3 整合Struts2与SiteMesh
2012-07-04 08:15 2072在Struts2中使用SiteMesh ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.2 单独使用SiteMesh
2012-07-03 08:00 209120.2 单独使用SiteMesh 20. ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.1 调整应用的风格
2012-07-03 07:59 185520.1 调整应用的风 ... -
《研磨struts2》19.2 使用execAndWait拦截器模拟进度条 之 19.2.1 模拟长时间运行的Action
2012-07-02 12:24 213719.2.1模拟长时间运行的Action ... -
《研磨struts2》第十九章 进度条 之 19.1 使用“进度条”告知用户进度
2012-07-02 12:23 214119.1 使用“进度条”告知用户进度 ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.3 Struts2结合JFreeChart
2012-06-28 12:12 199918.3 Struts2结合JFreeChart ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.2 Struts2插件概述
2012-06-28 12:11 2022Struts2并没有求大求全,企图把所有 ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.1 JFreeChart使用
2012-06-20 15:48 227818.1 JFreeChart使用 18.1.1概 ... -
研磨struts2(1-10章)电子书下载
2012-06-19 07:30 6058研磨struts2的博客文章 私塾在线学习网 《研 ... -
《研磨struts2》第十七章 防止重复提交 之 17.3 更强大的tokenSession拦截器
2012-06-18 13:46 206917.3 更强大的tokenSession拦截器 ... -
《研磨struts2》第十七章 防止重复提交 之 17.2 使用标签
2012-06-18 13:45 233317.2 使用<s:token/>标签 ...
相关推荐
4. **结果类型(Result Types)**:Struts2支持多种结果类型,如dispatcher(用于转发到JSP页面)、stream(用于下载文件)等。源代码可能展示了如何根据不同情况选择合适的结果类型。 5. **动态方法访问(Dynamic ...
### 知识点一:Struts2入门(MVC HelloWorld) #### 1.1 Struts2简介 ...以上就是关于“研磨Struts2”的主要知识点梳理,通过深入学习这些内容,开发者可以更好地掌握Struts2框架的核心技术和实践技巧。
由于文件较大,我把这个文档切割为2部分,这是第一部分,请下载完第一部分后一定要下载第二部分,否则不能阅读。
根据提供的文件信息,我们可以推断出这是一份关于《研磨Struts 2》书籍PDF版本的下载资源。为了更好地理解和概括这份资料所涉及的知识点,我们先来了解一下Struts 2框架及其重要性,然后深入探讨《研磨Struts 2》这...
《研磨Struts2》这本书是专门针对Struts2框架的学习指南,通过深入浅出的方式讲解了Struts2的核心概念和技术。其配套的PPT和视频旨在帮助读者更直观地理解书中的理论知识,并将其付诸实践。 在研读《研磨Struts2》...
研磨Struts2 高清完整版,请和第一部分一起下载啊
研磨Struts2_12859679_高清完整版
《研磨Struts2》这本书主要介绍了Struts2的基础知识、实践应用以及其核心概念。 1. **MVC模式**:MVC是一种设计模式,用于分离应用程序的业务逻辑、数据和用户界面。在Struts2中,Action类代表Controller,负责处理...
研磨Struts2-高清-完整目录-2011年10月,分享给所有需要的人
本电子书一共两个压缩文档,本文件为part2. 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,...
Java工程师三大框架面试题.pdf
研磨设计模式(完整版pdf)相信我不用介绍,很多人都在找这本书吧,今天我特意从另外的地方下载到了这本书,发了几十积分。才弄到。为了让大家同时分享这本书的精华。我今天特意上传。注:此电子书较大,我分了3个...
研磨设计模式.part2 一定要下载5部分
研磨设计模式(完整版pdf)相信我不用介绍,很多人都在找这本书吧,今天我特意从另外的地方下载到了这本书,发了几十积分。才弄到。为了让大家同时分享这本书的精华。我今天特意上传。注:此电子书较大,我分了3个...