FileUpload——在Struts2中上传文件

来源:互联网 发布:天天pk10计划软件 编辑:程序博客网 时间:2024/05/01 13:46

FileUpload——在Struts2中上传文件

 

大家可能注意一个问题很久了,在现在我们使用的Struts2版本中有一个commons-fileupload.jar,之前我们就提到,这个jar包主要是对文件上传的支持,看来Struts2认为在一个应用中文件的上传是个必要。本章节我们就一起来看看怎样在Struts2中实现文件上传,配置及基本做法。

 

配置

       在我们现在使用的版本中我们不需要什么配置,除非你想做点特别的事情。这里我们不讨论Struts2其他版本的文件上传问题。

 

基本做法

       OK,我们看到要实现文件上传基本上不需要额外的配置,比如说什么上传插件啦,相信我们的Struts2在这方面的使用时非常方便的。

       现在我们抛去Struts2,来想一想我们平时或以前在编写应用时怎样来实现文件上传的呢。要关心文件流的读写问题,存放位置,文件的打开与关闭,请求方式等等。带着我们平时编码的这些问题来看看Struts2中的解决方式。

       Step1: new一个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>FileUpload Page</title>

</head>

<body>

 

      <h2>Please select a file </h2>

      <s:form action="doUpload" enctype="multipart/form-data" method="post">

           <s:file name="upload"  label="Upload File"/>

           <s:textfield name="caption" label="Caption" />

           <s:submit></s:submit>

      </s:form>

</body>

</html>

这里你或许注意到了,我使用了<X:file>标签,作用就是在客户端产生一个文件域用来上传文件,然后我们为文件添加了一个标题(catpion)。还要注意这里我们更改了form提交的数据类型(enctype=”multipart/form-data”),这个不难理解,因为我们平时就是这么做的。

       Step2:new 一个 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>Upload Successfully</title>

</head>

<body>

 

      <h2>Here are some message about uploaded file</h2>

     

      <p>

           <b>File:</b>&nbsp;&nbsp;&nbsp;&nbsp;<s:property value="upload" /><br />

           <b>Caption:</b>&nbsp;&nbsp;&nbsp;&nbsp;<s:property value="caption" /><br />

           <b>ContentType:</b>&nbsp;&nbsp;&nbsp;&nbsp;<s:property value="uploadContentType" /><br />

           <b>FileName:</b>&nbsp;&nbsp;&nbsp;&nbsp;<s:property value="uploadFileName"/><br />

      </p>

</body>

</html>

       Step3: new 一个Action类,在Action里我们期望得到文件本身和文件的名称还有contentType。

 

Java代码  收藏代码
  1. package com.lele.struts2.fileuploadTest;  
  2.    
  3. import java.io.File;  
  4.    
  5. public class FileUploadAction {  
  6.    
  7.       private File upload;  
  8.       private String caption;  
  9.       private String uploadContentType;  
  10.       private String uploadFileName;  
  11.        
  12.       public String execute() {  
  13.            return "success";  
  14.       }  
  15.    
  16.       public File getUpload() {  
  17.            return upload;  
  18.       }  
  19.    
  20.       public void setUpload(File upload) {  
  21.            this.upload = upload;  
  22.       }  
  23.    
  24.       public String getCaption() {  
  25.            return caption;  
  26.       }  
  27.    
  28.       public void setCaption(String caption) {  
  29.            this.caption = caption;  
  30.       }  
  31.    
  32.       public String getUploadContentType() {  
  33.            return uploadContentType;  
  34.       }  
  35.    
  36.       public void setUploadContentType(String uploadContentType) {  
  37.            this.uploadContentType = uploadContentType;  
  38.       }  
  39.    
  40.       public String getUploadFileName() {  
  41.            return uploadFileName;  
  42.       }  
  43.    
  44.       public void setUploadFileName(String uploadFileName) {  
  45.            this.uploadFileName = uploadFileName;  
  46.       }  
  47. }  

这个Action就是解决问题的关键了,在这里我们的做法和之前的Action没有什么差别,就是这么简单。

       Step4: 在Action的配置文件里进行配置:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"

    "http://struts.apache.org/dtds/struts-2.1.7.dtd">

<struts>

      <package name="fileupload" extends="struts-default">

     

           <action name="index">

                 <result>fileUpload.jsp</result>

           </action>

 

           <action name="doUpload" class="com.lele.struts2.fileuploadTest.FileUploadAction">

                 <result>success.jsp</result>

           </action>

      </package>

</struts>

这里就不贴web.xml中的配置信息了,大家自己来吧。

现在我们就一起来看一下最终结果:



 

下面我们上传一个文件,然后填写文件标题提交一下:



 

大家或许看到的信息和我差不多,File就是上传成功后最终文件的位置及文件本身。ContentType就是消息类型(MIME类型),FileName就是文件的真实名称。

大家或许注意到了一些东西,在上传文件的页面中只有<x:file>和<x:textfield>,怎么在Action里有4个?这明显不对应。这一切都是<x:file>的缘故,一个标签对应了三个属性(upload uploadContentType uploadFileName)。

 

引发的问题

       在上面我们看到了在Struts2中的文件上传,相信你会感觉到在Struts2中文件上传的简单。不过上传文件的过程中发生了一些比较微妙的事情,您或许注意到在eclipse的控制台下产生的日志中看到了一些信息:

信息: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir

信息: Removing file upload

E:\MyJavaWorkplace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\struts2FileUploadTest\upload__419b20ce_12c9676ac91__8000_00000002.tmp

       这里我们并不能把这些信息看作为错误,第一条说的是struts.multipart.saveDir属性没有配置,struts.multipart.saveDir用于指定存放临时文件的文件夹。既然是属性没有配置,那么就配置一下好了。我们可以在

       Struts.property中添加上面的信息:

       struts.multipart.saveDir=路径

这样上传的文件就会临时保存到你指定的目录里了。

       第二条说的是移除了一个文件,因为我们上传文件并没有关心文件究竟到什么地方,也没有进行处理,在Struts2看来这些文件就是临时文件应当被清理,合理。现在看来我们要保留住上传的文件还要自己动手来做,你可以自己写一个IO操作类,也可以用common-fileupload.jar中的util,都可以的,看你怎么玩了。当然我们也可以在Action中直接处理文件。

       现在还要提一个问题,假设选择没有文件,没有填写文件标题能不能提交?问题很明显,要做一个严谨的Web程序我们是不允许这样做的,可怎么来处理呢?我们就要用到校验器了(我之前的文章可能未提及到),我们使用简单的方式:

首先要求被校验的Action类继承自ActionSupport

然后在Action类的目录下new一个Action类名-validation.xml,在其中填写以下内容:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC

          "-//OpenSymphony Group//XWork Validator 1.0.2//EN"

          "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

 

<validators>

      <field name="upload">

           <field-validator type="fieldexpression">

                 <param name="expression"><![CDATA[upload.length() > 0]]></param>

                 <message>File cannot be empty</message>

           </field-validator>

      </field>

      <field name="caption">

           <field-validator type="requiredstring">

                 <message>Caption cannot be empty</message>

           </field-validator>

      </field>

</validators>

       最后我们要修改Action配置文件,在<result>元素位置进行修改:

<result name="input">fileUpload.jsp</result>

<result>success.jsp</result>

这样就Ok了。

       能不能校验文件类型,文件大小?能,不过做法有点不太一样。我们需要从“根”入手,先来看做法:

       修改Action配置文件:

<action name="doUpload" class="com.lele.struts2.fileuploadTest.FileUploadAction">

                 <interceptor-ref name="fileUpload">

                      <param name="allowedTypes">

                            image/bmp,image/x-png,image/pjpeg,image/gif

                      </param>

                 </interceptor-ref>

                 <interceptor-ref name="defaultStack"></interceptor-ref>

                 <result name="input">fileUpload.jsp</result>

                 <result>success.jsp</result>

           </action>

没错我们使用了拦截器,当然这个拦截器不是我们自己写的而是Struts2本身的东东,在这里我们要求上传类型必须是图片类型,而后我们还需要之前的默认拦截器,因为我们要校验。(对拦截器不明白的朋友可以去看我之前的文章:Struts2的核心——拦截器)。

       这时我们再来上传文件,就会发现我们只能上传指定的文件类型了,同样可以使用maximumSize参数来设定上传文件大小。

       不过新的问题又来了,校验是没问题了,校验失败时输出的信息可有点烦人,能不能换成自定义的信息。当然这种信息是Struts2默认信息,不要以为是什么错误。这种情况下我们就要在全局国际资源文件中做点事情了。在资源文件中加入“struts.messages.error.content.type.not.allowed=The file you uploaded required image。现在可以了吧。

 

       OK,本章节内容就到这里了,下面的章节会介绍到多文件上传,有兴趣的朋友继续向下读。下个章节再见。

0 0
原创粉丝点击