写了一个用Struts实现文件上传的功能,拿出来晒晒。
首先导入如下的包到WEB-INF/lib目录下:
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
commons-logging-1.0.4.jar
freemarker-2.3.8.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xwork-2.0.4.jar
下面是各个文件的编写和配置:
web.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <filter>
- <filter-name>struts-clean</filter-name>
- <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
- </filter>
- <filter>
- <filter-name>struts</filter-name>
- <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>struts</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <welcome-file-list>
- <welcome-file>fileupload.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
struts2提供了ActionContextCleanUp类,在struts2的架构中,标准的过滤器一般以ActionContextCleanUp开始,后面跟着其他需要的过滤器,最后,由FilterDispatcher来处理请求,FilterDispatcher通常是将请求传递给ActionMapper,ActionContextCleanUp的一个重要作用是通知FilterDispatcher在正确的时间清除ActionContext中的请求数据,所以正确的排序如下:
(1)ActionContextCleanUp过滤器
(2)其他过滤器
(3)FilterDispatcher过滤器
FileUpLoadAction.java
- package com.bin.strust2.dome01;
- 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 java.util.Date;
- import com.opensymphony.xwork2.ActionSupport;
- import org.apache.struts2.ServletActionContext;
- public class FileUpLoadAction extends ActionSupport
- {
- // private static final long serialVersionUID = 572146812454l;
- private static final int BUFFER_SIZE = 16 * 1024;
- private File myFile;
- private String contentType;
- private String fileName;
- private String imageFileName;
- private String caption;
- public void setMyFileContentType(String contentType)
- {
- this.contentType = contentType;
- }
- public void setMyFileFileName(String fileName)
- {
- this.fileName = fileName;
- }
- public void setMyFile(File myFile)
- {
- this.myFile = myFile;
- }
- public String getImageFileName()
- {
- return imageFileName;
- }
- public String getCaption()
- {
- return caption;
- }
- public void setCaption(String caption)
- {
- this.caption = caption;
- }
- private static 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();
- }
- }
- private static String getExtention(String fileName)
- {
- int pos = fileName.lastIndexOf(".");
- return fileName.substring(pos);
- }
- @Override
- public String execute()
- {
- imageFileName = new Date().getTime() + getExtention(fileName);
- File imageFile = new File(ServletActionContext.getServletContext().getRealPath("/UploadImages") + "/" + imageFileName);
- copy(myFile, imageFile);
- return SUCCESS;
- }
- }
用上传时间来命名上传的文件名。
fileupload.jsp
- <%@page contentType="text/html" pageEncoding="gbk"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
- <%@taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>JSP Page</title>
- </head>
- <body>
- <s:form action="fileupload" method="post" enctype="multipart/form-data">
- <s:file name="myFile" label="上传文件"></s:file>
- <s:textfield name="caption" label="显示名字"></s:textfield>
- <s:submit value="上传"></s:submit>
- </s:form>
- </body>
- </html>
显示上传文件的页面,虽然可以上传的不只是图片一种,但如果上传的是图片我们就把他显示出来。
showfile.jsp
- <%@page contentType="text/html" pageEncoding="gbk"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
- <%@taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>JSP Page</title>
- </head>
- <body>
- <div style ="padding: 3px; border: solid 1px #cccccc; text-align: center" >
- <img src ='UploadImages/<s:property value ="imageFileName" /> ' />
- <br />
- <s:property value ="caption" />
- </div >
- </body>
- </html>
最后还要配置struts.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- <struts>
- <package name="fileupload" extends="struts-default">
- <action name="fileupload" class="com.bin.strust2.dome01.FileUpLoadAction">
- <interceptor-ref name="fileUploadStack"></interceptor-ref>
- <result name="success">/showfile.jsp</result>
- </action>
- </package>
- </struts>
到这里就可以实现文件的上传了,(*^__^*) 嘻嘻……。
但细心的朋友可以发现,在服务器打印出的信息中有这样一句话:
2008-11-30 14:20:45 org.apache.struts2.dispatcher.Dispatcher getSaveDir
信息: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to java.servlet.context.tempdir
这个是因为我们没有给程序指定缓存的地址,我们在src目录下加入文件struts.properties,内容如下
- struts.multipart.saveDir = /tmp
但现在又有一个问题,就是我们给上传文件设置显示的名字如果是中文的话会出现乱码,如果不是用Struts2框架,我们是要自己写一个转换编码的方法或类的,但Strust2为我们提供了乱码解决方案,我们只要调用他就好了,做法如下:
在struts.xml中的struts节点下加入<constant name="struts.i18n.encoding" value="GBK"></constant>,即可解决乱码问题。