a.在jsp中简单利用Commons-fileupload组件实现
b.在struts1.2中实现
c.在sturts2中实现
注:此为三个简单Demo,仅供练习用,并没有做太多上传限制 如有兴趣可以自行查看相关文档说明 。
一.在JSP环境中利用Commons-fileupload组件实现文件上传
1.页面upload.jsp清单如下:
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>The FileUpload Demo</title>
- </head>
-
- <body>
- <form action="UploadFile" method="post" enctype="multipart/form-data">
- <p><input type="text" name="fileinfo" value="">文件介绍</p>
- <p><input type="file" name="myfile" value="浏览文件"></p>
- <p><input type="submit" value="上 传"></p>
- </form>
- </body>
- </html>
注意:在上传表单中,既有普通文本域也有文件上传域
2.FileUplaodServlet.java清单如下:
- import java.io.File;
- import java.io.IOException;
- import java.util.Iterator;
- import java.util.List;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.*;
-
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileItemFactory;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
-
- public class FileUplaodServlet extends HttpServlet {
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doPost(request, response);
- }
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- request.setCharacterEncoding("UTF-8");
-
-
- boolean isMultipart = ServletFileUpload.isMultipartContent(request);
-
- if(isMultipart)
- {
- try {
- FileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload fileload = new ServletFileUpload(factory);
-
- fileload.setSizeMax(4194304);
- List<FileItem> files = fileload.parseRequest(request);
- Iterator<FileItem> iterator = files.iterator();
- while(iterator.hasNext())
- {
- FileItem item = iterator.next();
- if(item.isFormField())
- {
- String name = item.getFieldName();
- String value = item.getString();
- System.out.println("表单域名为: " + name + "值为: " + value);
- }else
- {
-
- String filename = item.getName();
- if(filename != null)
- {
- File file = new File(filename);
-
- if(file.exists()){
- File filetoserver = new File("d://upload//",file.getName());
- item.write(filetoserver);
- System.out.println("文件 " + filetoserver.getName() + " 上传成功!!");
- }
- }
- }
- }
- } catch (Exception e) {
- System.out.println(e.getStackTrace());
- }
- }
- }
- }
3.web.xml清单如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.4"
- xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
-
- <servlet>
- <servlet-name>UploadFileServlet</servlet-name>
- <servlet-class>
- org.chris.fileupload.FileUplaodServlet
- </servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>UploadFileServlet</servlet-name>
- <url-pattern>/UploadFile</url-pattern>
- </servlet-mapping>
-
- <welcome-file-list>
- <welcome-file>/Index.jsp</welcome-file>
- </welcome-file-list>
-
- </web-app>
二.在strut1.2中实现
1.上传页面file.jsp 清单如下:
- <%@ page language="java" pageEncoding="ISO-8859-1"%>
- <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
- <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
-
- <html>
- <head>
- <title>JSP for FileForm form</title>
- </head>
- <body>
- <html:form action="/file" enctype="multipart/form-data">
- <html:file property="file1"></html:file>
- <html:submit/><html:cancel/>
- </html:form>
- </body>
- </html>
2.FileAtion.java的清单如下:
- import java.io.*;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.struts.action.Action;
- import org.apache.struts.action.ActionForm;
- import org.apache.struts.action.ActionForward;
- import org.apache.struts.action.ActionMapping;
- import org.apache.struts.upload.<SPAN class=hilite2>FormFile</SPAN>;
-
- import form.FileForm;
-
-
- public class FileAction extends Action {
-
-
-
-
-
- public ActionForward execute(ActionMapping mapping, ActionForm form,
- HttpServletRequest request, HttpServletResponse response) {
- FileForm fileForm = (FileForm) form;
- <SPAN class=hilite2>FormFile</SPAN> file1=fileForm.getFile1();
- if(file1!=null){
-
- String dir=request.getSession(true).getServletContext().getRealPath("/upload");
- OutputStream fos=null;
- try {
- fos=new FileOutputStream(dir+"/"+file1.getFileName());
- fos.write(file1.getFileData(),0,file1.getFileSize());
- fos.flush();
- } catch (Exception e) {
-
- e.printStackTrace();
- }finally{
- try{
- fos.close();
- }catch(Exception e){}
- }
- }
-
- return mapping.findForward("success");
- }
- }
3.FileForm.java的清单如下:
- import javax.servlet.http.HttpServletRequest;
- import org.apache.struts.action.ActionErrors;
- import org.apache.struts.action.ActionForm;
- import org.apache.struts.action.ActionMapping;
- import org.apache.struts.upload.<SPAN class=hilite2>FormFile</SPAN>;
-
-
- public class FileForm extends ActionForm {
-
-
- private <SPAN class=hilite2>FormFile</SPAN> file1;
-
-
- public ActionErrors validate(ActionMapping mapping,
- HttpServletRequest request) {
-
- return null;
- }
-
-
-
- public void reset(ActionMapping mapping, HttpServletRequest request) {
-
- }
-
- public <SPAN class=hilite2>FormFile</SPAN> getFile1() {
- return file1;
- }
-
- public void setFile1(<SPAN class=hilite2>FormFile</SPAN> file1) {
- this.file1 = file1;
- }
- }
4.struts-config.xml的清单如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
-
- <struts-config>
- <data-sources />
- <form-beans >
- <form-bean name="fileForm" type="form.FileForm" />
-
- </form-beans>
-
- <global-exceptions />
- <global-forwards />
- <action-mappings >
- <action
- attribute="fileForm"
- input="/file.jsp"
- name="fileForm"
- path="/file"
- type="action.FileAction"
- validate="false">
- <forward name="success" path="/file.jsp"></forward>
- </action>
-
- </action-mappings>
-
- <message-resources parameter="ApplicationResources" />
- </struts-config>
5.web.xml代码清单如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <servlet>
- <servlet-name>action</servlet-name>
- <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
- <init-param>
- <param-name>config</param-name>
- <param-value>/WEB-INF/struts-config.xml</param-value>
- </init-param>
- <init-param>
- <param-name>debug</param-name>
- <param-value>3</param-value>
- </init-param>
- <init-param>
- <param-name>detail</param-name>
- <param-value>3</param-value>
- </init-param>
- <load-on-startup>0</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>action</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
- </web-app>
三.在struts2中实现(以图片上传为例)
1.FileUpload.jsp代码清单如下:
- <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <title>The FileUplaodDemo In <SPAN class=hilite1>Struts2</SPAN></title>
- </head>
-
- <body>
- <s:form action="fileUpload.action" method="POST" enctype="multipart/form-data">
- <s:file name="myFile" label="MyFile" ></s:file>
- <s:textfield name="caption" label="Caption"></s:textfield>
- <s:submit label="提交"></s:submit>
- </s:form>
- </body>
- </html>
2.ShowUpload.jsp的功能清单如下:
- <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <title>ShowUpload</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>
3.FileUploadAction.java的代码清单如下 :
- import java.io.*;
- import java.util.Date;
-
- import org.apache.<SPAN class=hilite1>struts2</SPAN>.ServletActionContext;
-
-
- import com.opensymphony.xwork2.ActionSupport;
-
- 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) {
- System.out.println("contentType : " + contentType);
- this .contentType = contentType;
- }
-
- public void setMyFileFileName(String fileName) {
- System.out.println("FileName : " + 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;
- }
- }
注:此时仅为方便实现Action所以继承ActionSupport,并Overrider execute()方法
在struts2中任何一个POJO都可以作为Action
4.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="example" namespace="/" extends="struts-default">
- <action name="fileUpload" class="com.chris.FileUploadAction">
- <interceptor-ref name="fileUploadStack"/>
- <result>/ShowUpload.jsp</result>
- </action>
- </package>
- </struts>
5.web.xml清单如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.4"
- xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http:
- http:
- <filter >
- <filter-name> struts-cleanup </filter-name >
- <filter-class>
- org.apache.struts2.dispatcher.ActionContextCleanUp
- </filter-class >
- </filter >
- <filter-mapping >
- <filter-name > struts-cleanup </filter-name >
- <url-pattern > /* </url-pattern >
- </filter-mapping >
-
- <filter>
- <filter-name>struts2</filter-name>
- <filter-class>org.apachestruts2.dispatcher.FilterDispatcher</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <welcome-file-list>
- <welcome-file>Index.jsp</welcome-file>
- </welcome-file-list>
-
- </web-app>
发布运行应用程序,在浏览器地址栏中键入:http://localhost:8080/Struts2_Fileupload/FileUpload.jsp,出现图示页面:
清单7 FileUpload页面
选择图片文件,填写Caption并按下Submit按钮提交,出现图示页面:
清单8 上传成功页面
更多配置
在运行上述例子,如果您留心一点的话,应该会发现服务器控制台有如下输出:
Mar
20
,
2007
4
:
08
:
43
PM org.apache.struts2.dispatcher.Dispatcher getSaveDir
INFO: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
Mar
20
,
2007
4
:
08
:
43
PM org.apache.struts2.interceptor.FileUploadInterceptor intercept
INFO: Removing file myFile C:/Program Files/Tomcat
5.5
/work/Catalina/localhost/Struts2_Fileupload/upload_251447c2_1116e355841__7ff7_00000006.tmp
清单9 服务器控制台输出
上述信息告诉我们,struts.multipart.saveDir没有配置。struts.multipart.saveDir用于指定存放临时文件的文件夹,该配置写在struts.properties文件中。例如,如果在struts.properties文件加入如下代码:
struts.multipart.saveDir
=
/tmp
清单10 struts配置
这样上传的文件就会临时保存到你根目录下的tmp文件夹中(一般为c:/tmp),如果此文件夹不存在,Struts 2会自动创建一个。
错误处理
上述例子实现的图片上传的功能,所以应该阻止用户上传非图片类型的文件。在Struts 2中如何实现这点呢?其实这也很简单,对上述例子作如下修改即可。
首先修改FileUpload.jsp,在<body>与<s:form>之间加入“<s:fielderror />”,用于在页面上输出错误信息。
然后修改struts.xml文件,将Action fileUpload的定义改为如下所示:
<
action
name
="fileUpload"
class
="tutorial.FileUploadAction"
>
<
interceptor-ref
name
="fileUpload"
>
<
param
name
="allowedTypes"
>
image/bmp,image/png,image/gif,image/jpeg
</
param
>
</
interceptor-ref
>
<
interceptor-ref
name
="defaultStack"
/>
<
result
name
="input"
>
/FileUpload.jsp
</
result
>
<
result
name
="success"
>
/ShowUpload.jsp
</
result
>
</
action
>
清单11 修改后的配置文件
显而易见,起作用就是fileUpload拦截器的allowTypes参数。另外,配置还引入defaultStack它会帮我们添加验证等功能,所以在出错之后会跳转到名称为“input”的结果,也即是FileUpload.jsp。
发布运行应用程序,出错时,页面如下图所示:
清单12 出错提示页面
上面的出错提示是Struts 2默认的,大多数情况下,我们都需要自定义和国际化这些信息。通过在全局的国际资源文件中加入“struts.messages.error.content.type.not.allowed=The file you uploaded is not a image”,可以实现以上提及的需求。对此有疑问的朋友可以参考我之前的文章《在Struts 2.0中国际化(i18n)您的应用程序》。
实现之后的出错页面如下图所示:
清单13 自定义出错提示页面
同样的做法,你可以使用参数“maximumSize”来限制上传文件的大小,它对应的字符资源名为:“struts.messages.error.file.too.large”。
字符资源“struts.messages.error.uploading”用提示一般的上传出错信息。
多文件上传
与单文件上传相似,Struts 2实现多文件上传也很简单。你可以将多个<s:file />绑定Action的数组或列表。如下例所示。
<
s:form
action
="doMultipleUploadUsingList"
method
="POST"
enctype
="multipart/form-data"
>
<
s:file
label
="File (1)"
name
="upload"
/>
<
s:file
label
="File (2)"
name
="upload"
/>
<
s:file
label
="FIle (3)"
name
="upload"
/>
<
s:submit
/>
</
s:form
>
清单14 多文件上传JSP代码片段
如果你希望绑定到数组,Action的代码应类似:
private
File[] uploads;
private
String[] uploadFileNames;
private
String[] uploadContentTypes;
![](http://img.e-com-net.com/image/info5/bdecc7a8941d4a0480b17667d118af43.gif)
![](http://img.e-com-net.com/image/info5/3c08b10177914a9694ff09c622a33633.gif)
public
File[] getUpload()
{ return this .uploads; }
public
void
setUpload(File[] upload)
{ this .uploads = upload; }
public
String[] getUploadFileName()
{ return this .uploadFileNames; }
public
void
setUploadFileName(String[] uploadFileName)
{ this .uploadFileNames = uploadFileName; }
public
String[] getUploadContentType()
{ return this .uploadContentTypes; }
public
void
setUploadContentType(String[] uploadContentType)
{ this .uploadContentTypes = uploadContentType; }
清单15 多文件上传数组绑定Action代码片段
如果你想绑定到列表,则应类似:
private
List
<
File
>
uploads
=
new
ArrayList
<
File
>
();
private
List
<
String
>
uploadFileNames
=
new
ArrayList
<
String
>
();
private
List
<
String
>
uploadContentTypes
=
new
ArrayList
<
String
>
();
![](http://img.e-com-net.com/image/info5/bdecc7a8941d4a0480b17667d118af43.gif)
![](http://img.e-com-net.com/image/info5/3c08b10177914a9694ff09c622a33633.gif)
public
List
<
File
>
getUpload()
{
return this .uploads;
}
public
void
setUpload(List
<
File
>
uploads)
{
this .uploads = uploads;
}
public
List
<
String
>
getUploadFileName()
{
return this .uploadFileNames;
}
public
void
setUploadFileName(List
<
String
>
uploadFileNames)
{
this .uploadFileNames = uploadFileNames;
}
public
List
<
String
>
getUploadContentType()
{
return this .uploadContentTypes;
}
public
void
setUploadContentType(List
<
String
>
contentTypes)
{
this .uploadContentTypes = contentTypes;
}
清单16 多文件上传列表绑定Action代码片段
总结
在Struts 2中实现文件上传的确是轻而易举,您要做的只是使用<s:file />与Action的属性绑定。这又一次有力地证明了Struts 2的简单易用。