文件上传
文件上传几近是每一个web利用实现的1个必须模块。文件上传的实现需要将表单元素属性enctype的值设置为multipart/form-data,使表单数据以2进制编码的方式提交。在接收此要求的Servlet中使用2进制流来获得内容,就能够获得上传文件的内容,从而实现文件的上传。
上传原理
在struts2中进行文件上传时,先需要将Form表单的enctype属性进行重新设置,该属性的取值就是决定表单数据的编码方式,有以下3个可选值:
1)application/x-www-form-urlencoded.这是默许的编码方式。只处理表单域里的value属性值,采取这类编码方式的表单会将表单域的值处理成URL编码方式。
2)multipart/form-data.这类编码方式的表单会以2进制流的方式来处理表单数据,将文件域指定文件的内容也封装到要求参数中。
3)text/plain.当表单的action属性值为mailto:URL的情势时,这类编码方式比较方便,它主要适用于直接通过表单发送邮件。
文件上传实例
实体类:
public class User {
private String name;//姓名
private String photo;//照片
private int age;//年龄
private int sex;//性别
private String icard;//身份证号
private String phone;//联系电话
private String address;//联系地址
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getIcard() {
return icard;
}
public void setIcard(String icard) {
this.icard = icard;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Action类:
public class UserAction extends ActionSupport {
private static final int BUFFER_SIZE = 40 * 40;
private File upload;// 封装上传文件域的
private String uploadContentType;// 封装上传文件的类型
private String uploadFileName;// 封装上传文件名
private String savePath;// 封装上传文件的保存路径
private User user;// 创建User类对象user
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
private static void copy(File source, File target) {
InputStream inputStream = null;// 声明1个输入流
OutputStream outputStream = null;// 声明1个输出流
try {
// 实例化输入流
inputStream = new BufferedInputStream(new FileInputStream(source),
BUFFER_SIZE);
outputStream = new BufferedOutputStream(
new FileOutputStream(target), BUFFER_SIZE);// 实例化输出流
byte[] buffer = new byte[BUFFER_SIZE];// 定义字节数组buffer
int length = 0;// 定义临时参数对象
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);// 如果上传的文件字节数大于0,将内容以字节情势写入
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (null != inputStream) {
try {
inputStream.close();// 关闭输入流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (null != outputStream) {
try {
outputStream.close();// 关闭输出流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
public String execute() throws Exception {
// 根据
服务器的文件保存地址和源文件名创建目录文件全路径
System.out.println("1" + this.getSavePath());
System.out.println("2" + this.getUploadFileName());
System.out.println("3" + this.getUpload());
System.out.println("4" + this.getTexts());
System.out.println("5" +this.getUploadContentType());
System.out.println("6" +ServletActionContext.getServletContext().getContextPath());
String path = ServletActionContext.getServletContext().getRealPath(
this.getSavePath())
+ "//" + this.getUploadFileName();
System.out.println(path);
System.out.println("uploadFilename: " + uploadFileName);
System.out.println("file: " + upload.getName());
System.out.println("file: " + upload.getPath());
user.setPhoto(this.uploadFileName);// 将上传的文件名称赋值给User类中的photo属性
File target = new File(path);// 定义目标文件对象
copy(this.upload, target);// 调用copy方法,实现文件的写入
return SUCCESS;
}
}
struts.xml中的配置,
<action name="user" class="com.mxl.action.UserAction">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">
image/pjpeg,image/x-png,image/gif,image/bmp
</param>
<param name="maximumSize">5000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<param name="savePath">/upload</param>
<result>/show_file.jsp</result>
<result name="input">/index.jsp</result>
</action>
上传界面:
<s:form action="user" namespace="/" method="post" enctype="multipart/form-data">
<s:textfield name="user.name" label="姓名" size="20"/>
<s:file name="upload" label="形象" size="20"/>
<s:textfield name="user.age" label="年龄" size="20"/>
<s:radio list="#{1:'男',2:'女'}" name="user.sex" listKey="key" listValue="value" value="1" label="性别" cssStype="border:0px;"/>
<s:textfield name="user.icard" label="身份证号" size="20"/>
<s:textfield name="user.phone" label="联系电话" size="20"/>
<s:textfield name="user.address" label="家庭住址" size="20"/>
<s:submit value="肯定录入" align="center"/>
</s:form>
显示界面:
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td width="300px" align="right">姓名:</td>
<td width="100px" align="left"><s:property value="user.name" />
</td>
<td rowspan="5" align="center"><img
src="upload/<s:property value="uploadFileName"/>"/><br />您的形象</td>
</tr>
<tr>
<td width="300px" align="right">年龄:</td>
<td><s:property value="user.age"/></td><td></td>
</tr>
<tr>
<td width="300px" align="right">性别:</td>
<td>
<s:if test="user.sex==1">
男
</s:if>
<s:else>
女
</s:else>
</td><td></td>
</tr>
<tr>
<td width="300px" align="right">身份证号:</td>
<td><s:property value="user.icard"/></td><td></td>
</tr>
<tr>
<td width="300px" align="right">联系电话:</td>
<td><s:property value="user.phone"/></td><td></td>
</tr>
<tr>
<td width="300px" align="right">家庭住址:</td>
<td><s:property value="user.address"/></td><td></td>
</tr>
</table>
多文件上传实例:
数组实现多文件上传,
Action类,
public class DocArrayAction extends ActionSupport{
private String name;//上传者
private File[] upload;//封装上传文件的属性
private String[] uploadContentType;//封装上传文件的类型
private String[] uploadFileName;//封装上传文件名
private String savePath;//封装上传文件保存路径
private Date createTime;//上传时间
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public File[] getUpload() {
return upload;
}
public void setUpload(File[] upload) {
this.upload = upload;
}
public String[] getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String[] uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String[] getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String[] uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public Date getCreateTime(){//实例化日期
createTime = new Date();
return createTime;
}
private static void copy(File source, File target) {
InputStream inputStream = null;// 声明1个输入流
OutputStream outputStream = null;// 声明1个输出流
try {
// 实例化输入流
inputStream = new BufferedInputStream(new FileInputStream(source));
outputStream = new BufferedOutputStream(
new FileOutputStream(target));// 实例化输出流
byte[] buffer = new byte[1024];// 定义字节数组buffer
int length = 0;// 定义临时参数对象
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);// 如果上传的文件字节数大于0,将内容以字节情势写入
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (null != inputStream) {
try {
inputStream.close();// 关闭输入流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (null != outputStream) {
try {
outputStream.close();// 关闭输出流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
public String execute() throws Exception {
for(int i = 0; i < upload.length; i++){
String path = ServletActionContext.getServletContext().getRealPath(
this.getSavePath())
+ "//" + this.uploadFileName[i];
File target = new File(path);// 定义目标文件对象
copy(this.upload[i], target);// 调用copy方法,实现文件的写入
}
return SUCCESS;
}
}
配置:
<action name="doc" class="com.mxl.action.DocArrayAction">
<interceptor-ref name="fileUpload">
<param name="maximumSize">50000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<param name="savePath">/upload</param>
<result>/show_doc.jsp</result>
<result name="input">/input_doc.jsp</result>
</action>
上传界面:
<s:form action="doc" namespace="/" method="post" enctype="multipart/form-data">
<s:textfield name="name" label="姓名" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:submit value="肯定上传" align="center"/>
</s:form>
上传成功界面:
<font style="font-size:12px; color:red">上传者<s:property value="name"/></font>
<table cellpadding="0" cellspacing="0">
<tr>
<th>文件名称</th>
<th>上传时间</th>
</tr>
<s:iterator value="uploadFileName" status="st">
<tr>
<td><s:property value="uploadFileName[#st.getIndex()]"/></td>
<td><s:date name="createTime" format="yyyy-MM-dd HH:mm:ss"/></td>
</tr>
</s:iterator>
</table>
List实现多文件上传:
Action类:
public class DocListAction extends ActionSupport{
private String name;
private List<File> upload;
private List<String> uploadContentType;
private List<String> uploadFileName;
private String savePath;
private Date createTime;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<File> getUpload() {
return upload;
}
public void setUpload(List<File> upload) {
this.upload = upload;
}
public List<String> getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(List<String> uploadContentType) {
this.uploadContentType = uploadContentType;
}
public List<String> getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(List<String> uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public Date getCreateTime(){
createTime = new Date();
return createTime;
}
public void setCreateTime(Date createTime){
this.createTime = createTime;
}
private static void copy(File source, File target) {
InputStream inputStream = null;// 声明1个输入流
OutputStream outputStream = null;// 声明1个输出流
try {
// 实例化输入流
inputStream = new BufferedInputStream(new FileInputStream(source));
outputStream = new BufferedOutputStream(
new FileOutputStream(target));// 实例化输出流
byte[] buffer = new byte[1024];// 定义字节数组buffer
int length = 0;// 定义临时参数对象
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);// 如果上传的文件字节数大于0,将内容以字节情势写入
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (null != inputStream) {
try {
inputStream.close();// 关闭输入流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (null != outputStream) {
try {
outputStream.close();// 关闭输出流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
public String execute() throws Exception {
for(int i = 0; i < upload.size(); i++){
String path = ServletActionContext.getServletContext().getRealPath(
this.getSavePath())
+ "//" + this.uploadFileName.get(i);
File target = new File(path);// 定义目标文件对象
copy(this.upload.get(i), target);// 调用copy方法,实现文件的写入
}
return SUCCESS;
}
}
配置:
<action name="docList" class="com.mxl.action.DocListAction">
<interceptor-ref name="fileUpload">
<param name="maximumSize">50000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<param name="savePath">/upload</param>
<result>/show_docList.jsp</result>
<result name="input">/input_docList.jsp</result>
</action>
上传界面:
<s:form action="docList" namespace="/" method="post" enctype="multipart/form-data">
<s:textfield name="name" label="姓名" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:file name="upload" label="选择文档" size="20"/>
<s:submit value="肯定上传" align="center"/>
</s:form>
成功界面:
<font style="font-size:12px; color:red">上传者<s:property value="name"/></font>
<table cellpadding="0" cellspacing="0">
<tr>
<th>文件名称</th>
<th>上传时间</th>
</tr>
<s:iterator value="uploadFileName" status="st" var="doc">
<tr>
<td><a href="downLoad.action?downPath=upload/<s:property value="#doc"/>"><s:property value="#doc"/></a></td>
<td><s:date name="createTime" format="yyyy-MM-dd HH:mm:ss"/></td>
</tr>
</s:iterator>
</table>