1、首先要有以下jar包。不是全部都是必要的。
2、在WEB-INF目录下写一个web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>fileupload</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3、在WebContent下写一个页面upload.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>struts2 中的文件上传</title>
</head>
<body>
<!-- 文件上传的必要前提:
(1)、请求方式必须是post
(2)、enctype属性的取值必须是multipart/form-data
(3)、提供一个文件选择域 -->
<s:actionerror/>
<s:form action="upload" enctype="multipart/form-data">
<s:textfield name="username" lable="用户名"/>
<s:file name="photo" lable="图片"/>
<s:submit value="上传"/>
</s:form>
</body>
</html>
4、写一个文件上传的方法类
package com.controller;
import java.io.File;
import javax.servlet.ServletContext;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class Upload extends ActionSupport {
//表单上提供的字段
private String username;
private File photo;
//struts2在文件上传时提供的属性
//如果不记住文件名,会发生上传一张覆盖一张的情况,因为重名会覆盖
private String photoFileName;//上传的文件名。上传字段名称+FileName 注意大小写
private String photoContentType;//上传文件的MIME类型。上传字段名称+ContentType 注意大小写
public String upload(){
//1.拿到ServletContext
ServletContext application = ServletActionContext.getServletContext();
//2.调用realPath方法,获取根据一个虚拟目录得到的真实目录
String filePath = application.getRealPath("/WEB-INF/files");
//3.如果这个真实的目录不存在,需要创建
File file = new File(filePath);
if(!file.exists()){
file.mkdirs();
}
//4.把photo存过去
//拷贝: 把photo的临时文件复制到指定的位置 。注意:临时文件还在;所以为了节省内存空间,一般不采用拷贝方式
//FileUtils.copyFile(photo, new File(file,photoFileName));
//剪切:把临时文件剪切指定的位置,并且给他重命名。 注意:临时文件没有了
photo.renameTo(new File(file,photoFileName));
//这里new File的File与上面File file的file都是虚地址, 引用对象不一样,
//但是引用的实际的地址是一样的,即/WEB-INF/files
//文件上传和下载都不用管结果视图,所以不用return success
return null;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public File getPhoto() {
return photo;
}
public void setPhoto(File photo) {
this.photo = photo;
}
public String getPhotoFileName() {
return photoFileName;
}
public void setPhotoFileName(String photoFileName) {
this.photoFileName = photoFileName;
}
public String getPhotoContentType() {
return photoContentType;
}
public void setPhotoContentType(String photoContentType) {
this.photoContentType = photoContentType;
}
}
5、在src下写一个struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="p1" extends="struts-default">
<action name="upload" class="com.controller.Upload" method="upload">
<result name="input">/upload.jsp</result>
</action>
</package>
</struts>
6、确定项目是部署在tomcat下后,运行,可以在tomcat->webapps目录下找到该项目,在WEB-INF下的files文件夹下找到上传的文件。如果在webapps路径下找不到该项目,可能是因为该项目还没有部署在tomcat下,可以参考我的上一篇博客更改一下部署位置即可解决。这里上传的文件默认不能大于2M,否则上传不了,报错如下:
- Request exceeded allowed size limit! Max size allowed is: 2,097,152 but request was: 3,502,710!
在default-properties文件中,有个默认值2097152 =1024*1024*2,这个2代表文件大小不能超过2M。在第5步中,写struts.xml时候默认加载struts-default,加上没有重新设置这个常量,所以上传文件最大只能是2M。可以通过在struts.xml文件中修改这个常量来改变文件大小的限制值。做法为:在包标签前面加上 <constant name="struts.multipart.maxSize" value="5242880"></constant> 这里设置为5M。注意:这个常量是这么算的:1024*1024*(?M)
扩展1:如果想限制上传文件的类型,做法如下:
法1:在struts.xml文件里面的action标签里加入
<interceptor-ref name="defaultStack">
<!-- 限制上传文件的扩展名。如果有多个,使用逗号分隔 -->
<param name="fileUpload.allowedExtensions">jpg,png,bmp</param>
</interceptor-ref>
那么测试上传word文档时候就会失败,报错如下:
File extension not allowed: photo "汇总表.docx" "upload_ec5962c6_c07b_41bc_82ce_a5b047d24aea_00000001.tmp" application/vnd.openxmlformats-officedocument.wordprocessingml.document |
法2:在struts.xml文件里面的action标签里加入
<interceptor-ref name="defaultStack">
<!-- 限制上传文件的MIME类型。 如果有多个,使用逗号分隔 -->
<param name="fileUpload.allowedTypes">image/jpg,image/pjpeg,image/png</param>
</interceptor-ref>
测试时如果上传word文档,会失败,报错如下:
Content-Type not allowed: photo "汇总表.docx" "upload_813f909d_cd47_4a48_8668_461f85a13219_00000001.tmp" application/vnd.openxmlformats-officedocument.wordprocessingml.document |
扩展2:设置报错信息以更加人性化
报错信息默认加载struts-messages-properties 里面的相应常量值,如下:
解决办法:用国际化消息资源包,把对应的key值改为中文即可。
常用的key值:
比如现在我创建的是fileupload_message.properties1这个资源文件,注意:在方框处的 ascii码是打中文时候自动转换出来的。
写的中文是:上传文件的类型不是被支持的
struts.messages.error.content.type.not.allowed=\u4E0A\u4F20\u6587\u4EF6\u7684\u7C7B\u578B\u4E0D\u662F\u88AB\u652F\u6301\u7684: {0} "{1}" "{2}" {3}
设置完成后,报错信息如下:
上传文件的类型不是被支持的: photo "课堂记录.docx" "upload_01234ebd_290b_48af_888c_4adfecabf764_00000001.tmp" application/vnd.openxmlformats-officedocument.wordprocessingml.document |