一:上传
必要前提:
1.表单method必须是post;
2.enctype取值必须是multipart/form-data;
3.提供文件选择域。
upload.jsp页面
<s:actionerror/>
<s:form action="upload" enctype="multipart/form-data">
<s:textfield name="username" label="姓名"></s:textfield>
<s:file name="photo" label="图片"></s:file>
<s:submit value="上传"></s:submit>
</s:form>
Struts.xml配置文件
<package name="p1" extends="struts-default">
<action name="upload" class="com.action.uploadAction" method="upload">
<result name="input">/upload.jsp</result>
</action>
</package>
uploadAction动作类
public class Uplode extends ActionSupport {
//表单上提供的字段
private String username;
private File photo;
//struts2在文件上传时提供的属性
private String photoFileName;//上传的文件名。上传字段名称+FileName 注意大小写
private String photoContentType;//上传文件的MIME类型。上传字段名称+ContentType 注意大小写
public String uplode(){
//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存过去
//拷贝: 。注意:临时文件还在
//FileUtils.copyFile(photo, new File(file,photoFileName));
//剪切:把临时文件剪切指定的位置,并且给他重命名。 注意:临时文件没有了
photo.renameTo(new File(file,photoFileName));
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;
}
}
运行截图
上传成功后页面跳转到空白页面,表示运行成功,没有出错
查找已上传成功的图片路径:
Tomcat目录下——webapps——项目工程名——WEB-INF——files
文件上传的配置:
1、修改上传文件的默认大小
在default.properties文件中,上传的文件默认大小为2MB
struts.multipart.maxSize=2097152
在struts.xml中改变default.properties文件中的常量
计算:2MB=1024*1024*2
10MB=1024*1024*10
把上传文件的限制大小改为10MB
<constant name="struts.multipart.maxSize" value="10485760"></constant>
2、限制上传文件的类型
1)通过限制上传文件的扩展名,给fileUpload拦截器注入参数
在struts-default.xml找到fileUpload拦截器
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
复制文件路径FileUploadInterceptor,Ctrl+shift+T粘贴查找
点击第一个进去,加载外部文件
FileUploadInterceptor文件打开,查看源码
protected Set<String> allowedTypesSet = Collections.emptySet();
protected Set<String> allowedExtensionsSet = Collections.emptySet();
/**
* Sets the allowed extensions
*
* @param allowedExtensions A comma-delimited list of extensions
*/
public void setAllowedExtensions(String allowedExtensions) {
allowedExtensionsSet = TextParseUtil.commaDelimitedStringToSet(allowedExtensions);
}
/**
* Sets the allowed mimetypes
*
* @param allowedTypes A comma-delimited list of types
*/
public void setAllowedTypes(String allowedTypes) {
allowedTypesSet = TextParseUtil.commaDelimitedStringToSet(allowedTypes);
}
Struts.xml
<action name="upload" class="com.action.uploadAction" method="upload">
<!-- 给Struts2定义好的拦截器注入参数,设置上传文件的扩展名,多个文件用逗号分隔 -->
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedExtensions">.jpg,.png,.bmp</param>
</interceptor-ref>
<result name="input">/upload.jsp</result>
</action>
2)通过限制上传文件的MIME类型
Struts.xml
<action name="upload" class="com.action.uploadAction" method="upload">
<!-- 给Struts2定义好的拦截器注入参数,设置上传文件的MIME类型,多个文件用逗号分隔 -->
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">image/jpg,image//png,image//bmp</param>
</interceptor-ref>
<result name="input">/upload.jsp</result>
</action>
3、把默认的错误提示改成中文
1)创建新的资源文件fileupload.properties,放在src下
默认的错误信息在:
在项目工程下——libraries——web App libraries——struts2-core.jar——org.apache.struts2——struts-message.properties
struts.messages.error.uploading=Error uploading: {0}
struts.messages.error.file.too.large=The file is to large to be uploaded: {0} "{1}" "{2}" {3}
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3}
struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
2)复制默认的错误信息到新建的fileupload.properties文件,并把其中的英文信息改成中文,输入中文同时文件会自动把中文编译为Unicode编码写入到文件中
struts.messages.error.uploading=\u4E0A\u4F20\u9519\u8BEF: {0}
struts.messages.error.file.too.large=\u6587\u4EF6\u592A\u5927: {0} "{1}" "{2}" {3}
struts.messages.error.content.type.not.allowed=\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301: {0} "{1}" "{2}" {3}
struts.messages.error.file.extension.not.allowed=\u4E0A\u4F20\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF0C\u5141\u8BB8\u7684\u6587\u4EF6\u540E\u7F00\u540D\u4E3A.jpg\uFF0C.png\uFF0C.bmp:{0} "{1}" "{2}" {3}
3)配置Struts.xml文件
<constant name="struts.custom.i18n.resources" value="com.action.uploadmessage"></constant>
运行结果截图
二:下载
在struts-default.xml文件下找到
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
查看StreamResult.class源码的属性和方法
protected String contentType = "text/plain";
protected String contentDisposition = "inline";
protected String inputName = "inputStream";
/**
* @return Returns the contentType.
*/
public String getContentType() {
return (contentType);
}
/**
* @param contentType The contentType to set.
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* @return Returns the Content-disposition header value.
*/
public String getContentDisposition() {
return contentDisposition;
}
/**
* @param contentDisposition the Content-disposition header value to use.
*/
public void setContentDisposition(String contentDisposition) {
this.contentDisposition = contentDisposition;
}
/**
* @return Returns the inputName.
*/
public String getInputName() {
return (inputName);
}
/**
* @param inputName The inputName to set.
*/
public void setInputName(String inputName) {
this.inputName = inputName;
}
Struts.xml配置文件
<action name="download" class="com.controller.DownloadTest" method="download">
<result name="success" type="stream">
<!-- 给stream的结果类型注入参数:Content-Type -->
<param name="contentType">application/octet-stream</param>
<!-- 告知客户浏览器以下载的方式打开 -->
<param name="contentDisposition">attachment;filename=暴风截图20181226640992.jpg</param>
<!-- <param name="contentDisposition">attachment;filename=${@java.net.URLEncoder@encode(filename,"UTF-8")}</param>
注入字节输入流 :取值要写动作类中set方法的名称,首字母改成小写 -->
<param name="inputName">inputStream</param>
</result>
</action>
downloadAction动作类
public class downloadAction extends ActionSupport{
//1.提供一个InputStream类型的输入流
private InputStream inputStream;
public String download() throws Exception{
//2.给输入流赋值
String filePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/444.jpg");
inputStream = new FileInputStream(filePath);
//3.返回成功
return SUCCESS;
//4.剩下的交给stream类型的结果去完成
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
}
运行结果截图
问题:文件名不能在配置文件中写死,需要根据实际情况获取。
解决办法:
Struts.xml
<action name="download" class="com.controller.DownloadTest" method="download">
<result name="success" type="stream">
<!-- 给stream的结果类型注入参数:Content-Type -->
<param name="contentType">application/octet-stream</param>
<!-- 文件名问题:使用的是OGNL表达式,${filename}-->
<param name="contentDisposition">attachment;filename=filename=${filename}</param>
<!-- <param name="contentDisposition">attachment;filename=${@java.net.URLEncoder@encode(filename,"UTF-8")}</param>
注入字节输入流 :取值要写动作类中set方法的名称,首字母改成小写 -->
<param name="inputName">inputStream</param>
</result>
</action>
downloadAction动作类
public class downloadAction extends ActionSupport{
//1.提供一个InputStream类型的输入流,框架有个小bug,字段名不能用in
private InputStream inputStream;
private String fileName;
public String download() throws Exception{
//2.给输入流赋值
String filePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/444.jpg");
inputStream = new FileInputStream(filePath);
//获取文件名
fileName = FilenameUtils.getName(filePath);
//如果有中文需要用URLEncoder进行编码
fileName = URLEncoder.encode(fileName,"utf-8");
//3.返回成功
return SUCCESS;
//4.剩下的交给stream类型的结果去完成
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
}