本章代码:
https://github.com/MarsOu1998/StrutsFile
1.传统文件上传需要考虑的问题:
1.文件编码问题
2.文件大小问题
3.文件分块问题
2.利用Struts解决上述问题
Struts的upload包是用于专门负责文件上传的工作。
3. 文件上传
1. 表单的属性:enctype=“multipart/form-data”
这个属性告诉Struts,表单提交的数据会被编码并且具备多个部分。
2. html:file property=“file”
同时在ActionForm里面定一个与file同名的属性,采用JavaBean风格,这个file的类型需要是org.apache.struts.upload.FormFile类的。
3. 得到文件信息:
getContentType:得到HTTP协议的文件类型
getFileName:得到文件名称
getFileSize:得到文件大小
4. 限制文件大小
在struts-config.xml的消息资源文件前加一个:controller maxFileSize=“大小”/来限制文件长度
初步实现文件上传:
upload.jsp:
<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<%--
Created by IntelliJ IDEA.
User: air
Date: 2019-08-16
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
</head>
<body>
<html:form action="/upload" method="post" enctype="multipart/form-data">
请您选择一个文件进行上传:<html:file property="myFile"></html:file>
<html:submit value="上传"/>
</html:form>
</body>
</html>
UploadForm.java:
package ActionForm;
import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;
public class UploadForm extends ActionForm {
private FormFile myFile;
public FormFile getMyFile() {
return myFile;
}
public void setMyFile(FormFile myFile) {
this.myFile = myFile;
}
}
UploadAction.java:
package Action;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ActionForm.UploadForm;
import org.apache.struts.upload.FormFile;
public class UploadAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
UploadForm uploadForm=(UploadForm)form;
FormFile myfile=uploadForm.getMyFile();
String type=myfile.getContentType();
String name=myfile.getFileName();
int size=myfile.getFileSize();
System.out.println(type);
System.out.println(name);
System.out.println(size);
return new ActionForward("/upload.jsp");
}
}
struts-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="uploadForm" type="ActionForm.UploadForm"></form-bean>
</form-beans>
<action-mappings>
<action name="uploadForm" path="/upload" type="Action.UploadAction"></action>
</action-mappings>
</struts-config>
####效果演示:
选择一个mp4文件进行上传,点击上传,控制台就会打印出该文件的类型、名字、大小
如果没有选择文件就直接点击上传,页面上是不会有报错的,在后台会显示文件名字为空,大小为0,这一点可以便于判断文件是否为空。
限制上传文件的大小
如果想要限制文件上传的大小,在struts-config.xml里面添加controller就行了,代码如下:
struts-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="uploadForm" type="ActionForm.UploadForm"></form-bean>
</form-beans>
<action-mappings>
<action name="uploadForm" path="/upload" type="Action.UploadAction"></action>
</action-mappings>
<controller maxFileSize="10M"></controller>
</struts-config>
这里限制了上传文件大小为10M,如果文件超出了10M,会引发空指针异常
4.写文件
将文件写入硬盘
byte[] FileForm.getFileData()可以得到文件数据
然后利用java.io.FileOutputStream类来进行写文件
获取上传的文件
upload.jsp和UploadForm还是老样子,UploadAction.java需要做出一些更新,新增一些内容
UploadAction.java:
package Action;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ActionForm.UploadForm;
import org.apache.struts.upload.FormFile;
import java.io.FileOutputStream;
public class UploadAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
UploadForm uploadForm=(UploadForm)form;
FormFile myfile=uploadForm.getMyFile();
String type=myfile.getContentType();
String name=myfile.getFileName();
int size=myfile.getFileSize();
System.out.println(type);
System.out.println(name);
System.out.println(size);
FileOutputStream fos=null;
try{
byte [] data=myfile.getFileData();
fos=new FileOutputStream(name);
fos.write(data);
}catch (Exception e){
e.printStackTrace();
}finally {
try{
fos.close();
}catch (Exception ex){
ex.printStackTrace();
}
}
return new ActionForward("/upload.jsp");
}
}
上传文件之后,路径默认放在Tomcat服务器的bin目录下:
5 文件路径
默认情况下文件是写在Tomcat的bin目录下,那么如何修改文件上传的路径呢?如何得到站点根目录下某个文件夹的绝对路径呢?
Action.getServlet().getServletContext.getRealPath(“站点路径”);
修改上传文件的路径
需要注意一点,Java如果想要访问硬盘或者服务器上面的路径,一定要提供逻辑路径(硬盘上的路径(c:…)
写上完整逻辑路径的名称也可以,但是名称可能会比较长,不利于修改。可以利用application的getRealPath获取。
其他的不变,UploadAction.java新增一些代码:
package Action;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ActionForm.UploadForm;
import org.apache.struts.upload.FormFile;
import java.io.FileOutputStream;
public class UploadAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
UploadForm uploadForm=(UploadForm)form;
FormFile myfile=uploadForm.getMyFile();
String type=myfile.getContentType();
String name=myfile.getFileName();
int size=myfile.getFileSize();
System.out.println(type);
System.out.println(name);
System.out.println(size);
FileOutputStream fos=null;
try{
ServletContext application=this.getServlet().getServletContext();
String realPath=application.getRealPath("/自定义路径/");
byte [] data=myfile.getFileData();
fos=new FileOutputStream(realPath+"/"+name);
fos.write(data);
}catch (Exception e){
e.printStackTrace();
}finally {
try{
fos.close();
}catch (Exception ex){
ex.printStackTrace();
}
}
return new ActionForward("/upload.jsp");
}
}
如果有报错的话,那是文件夹还没有建立,或者存储在的是当前项目的目录下,而不是Tomcat的目录。
6.读入上传的文件
我们可以无需把文件写入硬盘而对上传的文件进行读操作。
例如:再上传的文本文件之中,检查是否有不合法的词汇?
FormFile.getInputStream()可以做到这一点。如果支持中文的话,可以使用BufferedReader类
UploadAction.java:
package Action;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ActionForm.UploadForm;
import org.apache.struts.upload.FormFile;
import java.io.*;
public class UploadAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
UploadForm uploadForm=(UploadForm)form;
FormFile myfile=uploadForm.getMyFile();
String type=myfile.getContentType();
String name=myfile.getFileName();
int size=myfile.getFileSize();
System.out.println(type);
System.out.println(name);
System.out.println(size);
FileOutputStream fos=null;
try{
ServletContext application=this.getServlet().getServletContext();
String realPath=application.getRealPath("/自定义路径/");
byte [] data=myfile.getFileData();
fos=new FileOutputStream(realPath+"/"+name);
fos.write(data);
}catch (Exception e){
e.printStackTrace();
}finally {
try{
fos.close();
}catch (Exception ex){
ex.printStackTrace();
}
}
// InputStream is=myfile.getInputStream();
// BufferedReader br=new BufferedReader(new InputStreamReader(is));is
return new ActionForward("/upload.jsp");
}
}
用BufferedReader类就可以获取文件,对文件进行分析.
7.上传多个文件
上传多个文件,传统的数组属性方法已经无法满足需求,我们建议是:利用ArrayList来存储。因为数组属性不支持多个文件空间同名的情况,所以建议使用索引属性,当然了,不同名也可以做到。
方案:
1. 将控件定义为索引
2. 定义索引属性,可以使用数组,也可以使用ArrayList存储
8.小结
利用Struts进行文件上传的开发比传统的方式有许多的优点,重点是学习Struts框架的规范,在这种开发流程和编程思想的基础上,许多的工作都能够被简化,这也正是框架的魅力之处。