文件上传
前提:
1.method提交表单方式必须是post
2enctype必须是multipart/form-data
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%--导入struts2的标签库 --%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用户注册,使用的是struts2的标签</title>
<s:head></s:head>
</head>
<body>
<!--struts2的文件底层是使用的commons-fileupload和commons-io -->
<s:form action="upload.action" enctype="multipart/form-data">
<s:textfield name="name" label="用户名" requiredLabel="true" requiredPosition="left"/>
<s:file name="photo" label ="上传文件"></s:file>
<s:submit value="上传"/>
</s:form>
</body>
</html>
上传文件,传到服务器后,我们有两种方式来来处理它放置到我们要存储的位置
a.拷贝 即把上传服务器的临时文件拷贝到我们要存储的位置上去,这种方式操作后,临时文件还存在。
b.剪切 直接把临时文件剪切到我们要存储的位置,这种方式操作后,临时文件不存在。
文件上传的配置
在default.properties文件中有下面的配置
# uses javax.servlet.context.tempdir by default
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
从上面可以看出,其默认配置的最大文件大小为2MB,如果超过2MB,upload拦截器就会自动转到input的结果视图
配置上传文件的大小
a. 从upload拦截器中看出,它有个maximumSize属性,那我们可以通过参数注入的方式设置上传文件的大小了?
<action name="upload" class="com.yu.web.action.HelloAction" method="upLoadFile">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">10485760</param>
</interceptor-ref>
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="input">/uploadfile.jsp</result>
</action>
但是这种方式不起作用
b.通过配置变量替换default.properties中的struts.multipart.maxSize变量
<?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>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="com.yu.web.resources.message"></constant>
<constant name="struts.multipart.maxSize" value="10485760"></constant>
<!--注意:现在继承mydefault -->
<package name="p1" extends="struts-default" >
<action name="upload" class="com.yu.web.action.HelloAction" method="upLoadFile">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">10485760</param>
</interceptor-ref>
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="input">/uploadfile.jsp</result>
</action>
</package>
</struts>
文件上传的类型配置
a.通过配置文件的扩展名来限制文件的类型
<?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>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="com.yu.web.resources.message"></constant>
<constant name="struts.multipart.maxSize" value="10485760"></constant>
<!--注意:现在继承mydefault -->
<package name="p1" extends="struts-default" >
<action name="upload" class="com.yu.web.action.HelloAction" method="upLoadFile">
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedExtensions">.jpg,.png,.bmp</param>
</interceptor-ref>
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="input">/uploadfile.jsp</result>
</action>
</package>
</struts>
b.通过限制文件的MIME类型
<?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>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="com.yu.web.resources.message"></constant>
<constant name="struts.multipart.maxSize" value="10485760"></constant>
<!--注意:现在继承mydefault -->
<package name="p1" extends="struts-default" >
<action name="upload" class="com.yu.web.action.HelloAction" method="upLoadFile">
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">image/jpg,image/jpeg,image/bmp</param>
</interceptor-ref>
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="input">/uploadfile.jsp</result>
</action>
</package>
</struts>
如果不对应的文件类型上传时,就会提示错误,但是提示是英文的,那么怎么提示中文了
出错后的错误信息中文提示(Struts2中的所有文本提示都是基于国际化的)
struts2的默认消息提示位置
: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}
主要的文件错误文件上传提示为以上的四个部分
{0}:<input type="file" name="filename"></input> 中name属性的值
{1}:文件的真实名称
{2}:上传文件保存目录的名称
{3}:上传文件的类型(对struts.messages.error.file.too.large是文件的大小)
因为struts2的这些消息都是国际化的,所以我们可以更改成中文提示
首先:在src resource包下配置properties文件
在struts2中引用国际化资源包
<constant name="struts.custom.i18n.resources" value="com.yu.web.resource.fileuploadmessage"></constant>
多文件上传
多个文件上传的时候,它把其多个文件组成一个list集合,更改模型类
public class User {
private String name;
private File[] photo; //多个文件上传,用数组或者list集合
private String[] photoFileName; //多个文件上传,用数组或者list,文件名 ,固定写法,上传字段名称+FileName
private String[] photoContentType; //多个文件上传,用数组或者list,上传文件的MIME类型,上传字段名称+ContentType
jsp文件更改
<s:actionerror/>
<s:form action="upload.action" enctype="multipart/form-data">
<s:textfield name="name" label="用户名" requiredLabel="true" requiredPosition="left"/>
<s:file name="photo" label ="上传文件1"></s:file>
<s:file name="photo" label ="上传文件2"></s:file>
<s:submit value="上传"/>
</s:form>
action更改
public String upLoadFile(){
//拿到servletContext
ServletContext servletContext = ServletActionContext.getServletContext();
//得到其一个我们存储文件的真实目录,通过servletContext的realPath得到其一个虚拟目录的真实目录
String pathName= servletContext.getRealPath("/WEB-INF/files");
//
File file = new File(pathName);
//判断其目录是否存在,不存在则创建
if(!file.exists()){
file.mkdirs();
}
//拷贝该文件
//FileUtils.copyFile(user.getPhoto(),new File(file, user.getPhotoFileName()) );
//剪切文件
if(user.getPhoto()!=null&&user.getPhoto().length>0){
for(int i=0;i<user.getPhoto().length;i++){
user.getPhoto()[i].renameTo(new File(file, user.getPhotoFileName()[i]));
}
}
return SUCCESS;
}
文件下载
本质是提供一种输入流
stryts2.xml文档配置:
<action name="download" class="com.yu.web.action.DownLoadAction" method="downLoadFile">
<!--执行成功后,配置stream的框架处理其下载功能 -->
<result name="success" type="stream">
<!--配置输入流,就是配置其下载动作类中的字段 ,注意:这种注入参数的方式都是通过set方式注入的-->
<param name="inputName">fileInputStream</param>
<!--contentDisposition:设置 响应消息头告知浏览器已下载的方式打开-->
<param name="contentDisposition">attachment;filename=image.png</param>
<!--contentType:设置响应消息头,告知浏览器MIME类型 -->
<param name="contentType">application/octet-stream</param>
</result>
</action>
动作类:
public class DownLoadAction extends ActionSupport {
//提供一个inputStream的输入流框架
private InputStream fileInputStream;
public String downLoadFile() throws FileNotFoundException{
//通过虚拟路径得到真实的路径
String path=ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/盒子模型.png");
fileInputStream = new FileInputStream(path);
//写到这里就可以了,剩下的stream的框架会自动处理
return SUCCESS;
}
public InputStream getFileInputStream() {
return fileInputStream;
}
public void setFileInputStream(InputStream fileInputStream) {
this.fileInputStream = fileInputStream;
}
}
现在有个问题,文件名我们可以更改吗,当然可以,是ONGL表达式更改文件名
动作类中加一个更改文件名的字段,注意文件名有中文,要设置编码
public class DownLoadAction extends ActionSupport {
//提供一个inputStream的输入流框架
private InputStream fileInputStream;
private String fileName; //更改文件名
public String downLoadFile() throws Exception{
//通过虚拟路径得到真实的路径
String path=ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/盒子模型.png");
fileInputStream = new FileInputStream(path);
//设置文件名
fileName="照片.png";
//如果有中文,要给其名字编码,负责会出现乱码
fileName=URLEncoder.encode(fileName, "UTF-8");
//写到这里就可以了,剩下的stream的框架会自动处理
return SUCCESS;
}
public InputStream getFileInputStream() {
return fileInputStream;
}
public void setFileInputStream(InputStream fileInputStream) {
this.fileInputStream = fileInputStream;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
struts.xml中配置'
<action name="download" class="com.yu.web.action.DownLoadAction" method="downLoadFile">
<!--执行成功后,配置stream的框架处理其下载功能 -->
<result name="success" type="stream">
<!--配置输入流,就是配置其下载动作类中的字段 ,注意:这种注入参数的方式都是通过set方式注入的-->
<param name="inputName">fileInputStream</param>
<!--contentDisposition:设置 响应消息头告知浏览器已下载的方式打开-->
<param name="contentDisposition">attachment;filename=${filename}</param>
<!--contentType:设置响应消息头,告知浏览器MIME类型 -->
<param name="contentType">application/octet-stream</param>
</result>
</action>