struts1(3)----文件上传

来源:互联网 发布:esop 知乎 编辑:程序博客网 时间:2024/06/05 17:31

            Struts封装了很多javaweb常见的操作,提供给开发者是更简单的操作和更少的代码量就能够完成相关功能。传统javaweb实现文件上传需要对提交的表单数据进行校验及封装,而利用Struts框架来实现文件上传工作,这些操作都不需要。jsp页面负责提交上传的文件数据,struts内部将这些文件表单数据都封装到一个FormFile对象中,通过这个对象可以获取到上传文件的所有数据。操作也简化了很多,而且还会自动将表单数据封装到FormBean中。

       下面是一个上传文件的例子:

              FormBean

public class UploadFormBean extends ActionForm {private String name;private FormFile file;   //使用struts实现上传文件,需要使用org.apache.struts.upload.FormFile封装文件字段public String getName() {return name;}public void setName(String name) {this.name = name;}public FormFile getFile() {return file;}public void setFile(FormFile file) {this.file = file;}}

         
        action

public class UploadFileAction2 extends Action {@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {// TODO Auto-generated method stubUploadFormBean ufb = (UploadFormBean) form;FormFile file = ufb.getFile();if (file == null) {request.setAttribute("message", "文件为空");return mapping.findForward("message");}InputStream in = file.getInputStream();String fileName = file.getFileName();String savePath = request.getSession().getServletContext().getRealPath("/upload");FileOutputStream out = new FileOutputStream(savePath + "/" + fileName);byte[] buf = new byte[1024];int len = 0;while ((len = in.read(buf)) > 0) {out.write(buf, 0, len);}out.close();in.close();request.setAttribute("message", "上传成功");return mapping.findForward("message");}}

        FormFile是struts实现文件上传用来封装文件的对象。其getInputStream方法可以获取到对应文件的字节流,通过此方法可以读取到文件的内容。其getFileName方法可以获取到此上传的文件名,不过要是上传的文件名是中文,此方法获取到的文件名将会是乱码,可以使用过滤器解决。下面是这个对象的一些方法

 voiddestroy() 
           Destroys all content for the uploaded file, including any underlying data files. StringgetContentType() 
           Returns the content type for this file. byte[]getFileData() 
           Returns the data for the entire file as byte array. StringgetFileName() 
           Returns the file name of this file. intgetFileSize() 
           Returns the size of this file. InputStreamgetInputStream() 
           Returns an input stream for this file. voidsetContentType(String contentType) 
           Sets the content type for this file. voidsetFileName(String fileName) 
           Sets the file name of this file. voidsetFileSize(int fileSize) 
           Sets the file size.          

          提交文件上传数据时,同传统javaweb实现上传表单一样,需要将enctype类型设置为multpart/form-data类型。同时还需导入如下两个包:

              struts-1.3.8\lib\commons-fileupload-1.1.1.jarcommons-io-1.1.jar

      当然这两个包在导入struts相关库时已经导入了。在使用struts上传文件时,对于上传多个文件不像上传单个文件那么简单,上传多个文件相对复杂些。对上传多个文件,bean属性应该有个list或者map集合来保存提交的文件,当然这些文件也都是封装在FormFile对象中,也就是说list集合中,存入的是FormFile类型的元素。正是由于这个属性是list或map,这里以list为例。其set和get方法,不能是setList(List list)或getList(), 其setList应该能将每个FormFile对象加入到list中,getList应该能获取到整个list,当然也可以获取指定的File. 使用commons-beanutils, 封装数据时,set和get方法有如下几种设置方法:

if (bean instanceof Map) {            setPropertyOfMapBean((Map) bean, name, value);        } else if (resolver.isMapped(name)) {            setMappedProperty(bean, name, value);        } else if (resolver.isIndexed(name)) {            setIndexedProperty(bean, name, value); //对应set(int index,,,)方法        } else {            setSimpleProperty(bean, name, value);//对应set()方法        }

         因此对多文件上传时,FormBean可以写成如下形式:

public class UploadMultFile extends ActionForm {private String name;private List<FormFile> list = new ArrayList();public String getName() {return name;}public void setName(String name) {this.name = name;}public FormFile getList(int index) {return list.get(index);}public void setList(int index, FormFile file) {list.add(index, file);}public List<FormFile> getAll(){return list;}}


        对应action代码:

public class UploadFileAction extends Action {@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {// TODO Auto-generated method stubUploadMultFile ufb = (UploadMultFile)form;List<FormFile> files = ufb.getAll();if(files==null || files.size()==0){request.setAttribute("message", "文件为空");return mapping.findForward("message");}for(FormFile file : files){InputStream in = file.getInputStream();String fileName = file.getFileName();String savePath = request.getSession().getServletContext().getRealPath("/upload");FileOutputStream out = new FileOutputStream(savePath+"/"+fileName);byte[] buf = new byte[1024];int len = 0;while((len=in.read(buf)) >0){out.write(buf, 0, len);}out.close();in.close();}request.setAttribute("message", "上传成功");return mapping.findForward("message");}}

       上传多个文件时,对应的jsp页面也有也比较特殊,每个file类型的input项,其name名字为list[0],list[1]。如下所示:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>        <title>文件上传页面</title>  </head>    <body>   <form action="${pageContext.request.contextPath }/UploadFile.do"    method="post"   enctype="multipart/form-data">   用户名: <input type="text" name="username" /><br />   上传文件1:<input type="file" name="list[0]" /><br />   上传文件2:<input type="file" name="list[1]" /><br />   <input type="submit" value="submit" />   </form>  </body></html>

      其name名称list[0], list[1]在使用commons-beanutils封装属性时,将会对其进行解析,list将作为bean的属性名,即通过list来找到setList方法和getList方法,而[0],[1]将作为setList和getList的参数。这种操作比较特殊。

     这是使用struts上传多个文件时特殊之处。当然使用Struts上传文件,也可以对上传文件大小或一个上传表单最大能上传多少字节,当上传的文件大于这个值时,struts将不会把上传的文件封装到FormFile对象中,即取到其对应的FormFile对象为NULL。不过在struts中,这些设置都市在struts-config.xml文件中进行设置,相对来说方便灵活了很多。这些配置值是在struts-config.xml配置文件中的controller标签里进行配置的。具体可以参考如下说明:

5.2.1 Controller Configuration

The <controller> element allows you to configure the ActionServlet. Many of the controller parameters were previously defined by servlet initialization parameters in your web.xml file but have been moved to this section of struts-config.xml in order to allow different modules in the same web application to be configured differently. For full details on available parameters see the struts-config DTDDoc or the list below.

  • bufferSize - The size (in bytes) of the input buffer used when processing file uploads. [4096] (optional)
  • catalog - Name of the catalog to use when processing requests for this module. [struts]
  • className - Classname of configuration bean. [org.apache.struts.config.ControllerConfig] (optional)
  • command - Name of the command to execute to process a request. [servlet-standard]
  • contentType - Default content type (and optional character encoding) to be set on each response. May be overridden by the Action, JSP, or other resource to which the request is forwarded. [text/html] (optional)
  • forwardPattern - Replacement pattern defining how the "path" attribute of a <forward> element is mapped to a context-relative URL when it starts with a slash. This value may consist of any combination of the following:
    • $M - Replaced by the module prefix of this module.
    • $P - Replaced by the "path" attribute of the selected <forward> element.
    • $$ - Causes a literal dollar sign to be rendered.
    • $x - (Where "x" is any character not defined above) Silently swallowed, reserved for future use.
    If not specified, the default forwardPattern is consistent with the previous behavior of forwards. [$M$P] (optional)
  • inputForward - Set to true if you want the input attribute of <action> elements to be the name of a local or global ActionForward , which will then be used to calculate the ultimate URL. Set to false to treat the input parameter of <action> elements as a module-relative path to the resource to be used as the input form. [false] (optional)
  • locale - Set to true if you want a Locale object stored in the user's session if not already present. [true] (optional)
  • maxFileSize - The maximum size (in bytes) of a file to be accepted as a file upload. Can be expressed as a number followed by a "K", "M", or "G", which are interpreted to mean kilobytes, megabytes, or gigabytes, respectively. [250M] (optional)
  • memFileSize - The maximum size (in bytes) of a file whose contents will be retained in memory after uploading. Files larger than this threshold will be written to some alternative storage medium, typically a hard disk. Can be expressed as a number followed by a "K", "M", or "G", which are interpreted to mean kilobytes, megabytes, or gigabytes, respectively. ["256K"]
  • multipartClass - The fully qualified Java class name of the multipart request handler class to be used with this module. [org.apache.struts.upload.CommonsMultipartRequestHandler] (optional)
  • nocache - Set to true if you want the controller to add HTTP headers for defeating caching to every response from this module. [false] (optional)
  • pagePattern - Replacement pattern defining how the page attribute of custom tags using it is mapped to a context-relative URL of the corresponding resource. This value may consist of any combination of the following:
    • $M - Replaced by the module prefix of this module.
    • $P - Replaced by the "path" attribute of the selected <forward> element.
    • $$ - Causes a literal dollar sign to be rendered.
    • $x - (Where "x" is any character not defined above) Silently swallowed, reserved for future use.
    If not specified, the default pagePattern is consistent with the previous behavior of URL calculation. [$M$P] (optional)
  • processorClass - The fully qualified Java class name of the RequestProcessor subclass to be used with this module. [org.apache.struts.chain.ComposableRequestProcessor] (optional)
  • tempDir - Temporary working directory to use when processing file uploads. [{the directory provided by the servlet container}]

This example uses the default values for several controller parameters. If you only want default behavior you can omit the controller section altogether.

<controller    processorClass="org.apache.struts.action.RequestProcessor"       contentType="text/html"/>;

         下面是设置了单个文件上传大小的限制的例子,具体处理如下所示:

配置文件中controller标签的设置,上传的文件不能超过20k

<controller     processorClass="org.apache.struts.action.RequestProcessor"    maxFileSize="20K"></controller>

              由于struts在文件上传时,若其文件大小超过了指定的大小限制时,不会报错,但FormFile对象没有封装上传文件,其值为NULL,若上传的文件没有指定,而是为空,对应的FormFile对象不为空,但其得到的文件名为空,文件大小为0,因此只能通过判断封装了文件的FormFile对象是否为空来判断该文件是否超过来了大小限制,因此如果为空,说明上传过来的文件超过了设置的大小限制。若不为空,可以通过其文件名和大小来判断上传文件表单是否有指定了上传文件。下面是action的处理逻辑。

public class UploadFileAction2 extends Action {@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {// TODO Auto-generated method stubUploadFormBean ufb = (UploadFormBean) form;FormFile file = ufb.getFile();if (file == null) {request.setAttribute("message", "文件大小过大");return mapping.findForward("message");}else if(file.getFileName().equals("")){request.setAttribute("message", "请选择上传文件");return mapping.findForward("message");}InputStream in = file.getInputStream();String fileName = file.getFileName();String savePath = request.getSession().getServletContext().getRealPath("/upload");FileOutputStream out = new FileOutputStream(savePath + "/" + fileName);byte[] buf = new byte[1024];int len = 0;while ((len = in.read(buf)) > 0) {out.write(buf, 0, len);}out.close();in.close();request.setAttribute("message", "上传成功");return mapping.findForward("message");}}




 



 

0 0
原创粉丝点击