struts的基本jar包中已经提供了文件上传的相关jar包commons-fileupload.jar,用于将上传的文件封装为File类型的
下面简单的通过一个小例子来简单描述一下struts里面的文件上传步骤
1. 首先按照struts项目的创建步骤创建好struts项目
2. 写一个UploadAction.java
public class UploadAction extends ActionSupport {
private File photo;
public String upload(){
System.out.println(photo);
return NONE;
}
public File getPhoto() {
return photo;
}
public void setPhoto(File photo) {
this.photo = photo;
}
}
3. 写一个upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>file_upload</title>
</head>
<body>
<s:form enctype="multipart/form-data" action="upload" method="POST">
<s:file label="照片" name="photo"></s:file>
<s:submit label="上传"></s:submit>
</s:form>
</body>
</html>
4. 在struts.xml文件中设置action
<?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>
<constant name="struts.devMode" value="true" />
<package name="upload" extends="struts-default" namespace="/file">
<action name="upload" class="action.UploadAction" method="upload">
<result name="input">/upload.jsp</result>
</action>
</package>
</struts>
启动tomcat访问upload.jsp路径,选择文件,点击提交
控制台提示如下
ERROR ParametersInterceptor Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'photoContentType' on 'class action.UploadAction: Error setting expression 'photoContentType' with value ['image/png', ]
ERROR ParametersInterceptor Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'photoFileName' on 'class action.UploadAction: Error setting expression 'photoFileName' with value ['批注 2020-01-11 114441.png', ]
C:\Users\用户名\.IntelliJIdea2019.3\system\tomcat\Tomcat_8_5_31_upload_struts\work\Catalina\localhost\upload_struts_war_exploded\upload_51ef87c8_b4dd_4c14_80b3_63b2fe6d7a1a_00000000.tmp
这里面会自动将该文件封装成file类型,存在了一个临时文件夹,省去了之前的读取文件字节流。
但是这里面还存在两个错误,看上面控制台输出的信息,根据提示,发现在action中少了两个属性,一个是文件类型photoContentType,一个是photoFileName(注意这里面会根据表单里面<s:file></s:file>标签内部中name属性的值来改变前面的属性名字,如果name的属性值为xxx,则前面的属性名字为xxxContentType和xxxFileName)
5. 消除错误,在action中添加如下两个属性
public class UploadAction extends ActionSupport {
private String photoContentType;
private String photoFileName;
private File photo;
public String upload(){
System.out.println(photo);
System.out.println(photoContentType);
System.out.println(photoFileName);
return NONE;
}
public File getPhoto() {
return photo;
}
public void setPhoto(File photo) {
this.photo = photo;
}
public String getPhotoContentType() {
return photoContentType;
}
public void setPhotoContentType(String photoContentType) {
this.photoContentType = photoContentType;
}
public String getPhotoFileName() {
return photoFileName;
}
public void setPhotoFileName(String photoFileName) {
this.photoFileName = photoFileName;
}
}
再次提交文件,控制台输出信息如下
C:\Users\用户名\.IntelliJIdea2019.3\system\tomcat\Tomcat_8_5_31_upload_struts\work\Catalina\localhost\upload_struts_war_exploded\upload_8232872a_3647_4d48_9e2a_9888099d7a4e_00000000.tmp
image/png
批注 2020-01-11 114441.png
6. 下面介绍如何对自动封装的file文件转存到服务器端
public class UploadAction extends ActionSupport {
private String username;
private String photoContentType;
private String photoFileName;
private File photo;
public String upload(){
System.out.println(photo);
System.out.println(photoContentType);
System.out.println(photoFileName);
//1. 获取存储目录
String dictory = ServletActionContext.getServletContext().getRealPath("/WEB-INF/upload")+"/" +username;
System.out.println("保存路径"+dictory);
File f=new File(dictory);
if (f.exists()==false){
f.mkdirs();
}
//2. 文件保存路径
String fileSavePath=dictory+"/"+photoFileName;
//3. 剪切文件到另一个位置
//FileUtils.copyFile(photo,new File(fileSavePath));
photo.renameTo(new File(fileSavePath));
return NONE;
}
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 getPhotoContentType() {
return photoContentType;
}
public void setPhotoContentType(String photoContentType) {
this.photoContentType = photoContentType;
}
public String getPhotoFileName() {
return photoFileName;
}
public void setPhotoFileName(String photoFileName) {
this.photoFileName = photoFileName;
}
}
这里面在upload.jsp里面添加了一个name为username的文本域,用于区别不同用户的文件夹
<s:form enctype="multipart/form-data" action="/file/upload" method="POST">
<s:textfield label="用户名" name="username"></s:textfield>
<s:file label="照片" name="photo"></s:file>
<s:submit label="上传"></s:submit>
</s:form>
访问该页面,选择好文件,输入好用户名,点击提交后,文件已经存在了服务器该项目的WEB-INF中
注意事项:
struts提供了内置标签用于文件上传<s:file>,我们称之为文件选择域
设置一个form表单,其enctype类型设置为multipart/form-data,enctype为编码格式
multipart/form-data | 不对字符编码。 在使用包含文件上传控件的表单时,必须使用该值。 |
表单提交方式必须为post
必须在处理文件的action里面设置上photoContentType和photoFileName两个属性,并且为其添加set和get方法