一,文件的上传
文件的上传涉及到几个步骤:
1.在jsp页面中选择文件
一般来说,我们会在form中提交,但是这里我们使用ajax进行提交,所以直接用div就行,在div中放一个<input type="file"..>标签用于选择文件,再放一个button用于上传,这里要注意你得记住这个file标签的id和name属性,之后会用到!
<div class="modal-footer">
<input id="file" name="fileup" type="file" value="选择文件">
<button id="upload" type="button" class="btn btn-primary">点击上传</button>
</div>
2.在js中获取选中的文件对象和相关信息并提交到指定action
这里需要用到jquery的一个叫ajaxFileUpload的方法,这里需要引入一个ajaxfileupload.js的文件,这是我在 github上找到的,亲测能用(https://github.com/carlcarl/AjaxFileUpload),在项目中jquery.js引入之后引入这个js文件即可,然后我们在js中的upload.click中写上传的代码
$("#upload").click(function () {
var iffile=$("#file").val();
var file=document.getElementById("file");
var docname = $("#upname").val();
var docuper = $("#uper").html().substring(4);
var doctime = $("#uptime").html().substring(5);
var doctype = $("#upsection").html().substring(5);
if(iffile==""){
alert("请选择文件!");
return false;
}
filesize=file.files[0].size;
if(filesize>31457280){
alert("文件大小不能超过30MB!");
return false;
}
var fileextindex=iffile.lastIndexOf(".");
var fileext=iffile.substring(fileextindex+1);
if(fileext!="txt"&&fileext!="jpg"&&fileext!="gif"&&fileext!="png"&&fileext!="doc"&&fileext!="docx"&&fileext!="rar"&&fileext!="zip"&&fileext!="pdf"&&fileext!="pptx"&&fileext!="xlsx"){
alert("暂时不支持该文件格式!");
return false;
}
if(docname==""){
alert("请给文件取个名!");
return false;
}
if (doctype == "课内资料一点通")
doctype = "class";
else if (doctype == "外语学习小助手")
doctype = "english";
else if (doctype == "出国保研有话说")
doctype = "overseas";
var doccontent = $("#upcontent").val();
$.ajaxFileUpload({
url: 'fileupaction.action',//用于文件上传的请求地址
fileElementId: 'file',//文件上传空间的id属性,通过这个id,相当于非异步中的myFile
dataType: 'json',
data: {
docname: docname,
docuper: docuper,
doctime: doctime,
doctype: doctype,
doccontent: doccontent
},
success: function (data) {
if (data.result == "success") {
alert("上传成功!");
window.location.href = "studycool.jsp?pagefrom=document";
} else {
alert("上传失败!");
}
},
error: function (data) {
alert("上传失败!");
}
});
})
这行代码主要做了两件事,先判断上传的文件是否符合要求,符合要求则上传,判断文件有以下几个核心
- 判断文件是否存在:通过id将文件对象赋给iffile,然后通过iffile==""来判断是否选择了文件
- 判断文件大小:这里要注意,通过jquery获取的文件对象无法使用后面的语句,因此我们用原生js
document.getElementById("file")来获取文件对象,然后通过filesize=file.files[0].size获得文件大小,单位是B
- 判断文件后缀名:通过lastindexof方法找到“.”的位置,然后用substring获取后缀名
上传文件有以下几个参数:
- url:你处理上传文件的action的名字
- fileElementId:你file标签的id,这里也就是file
- datatype:返回的是什么类型的数据,这里当然是json格式
- data:这里面可以放随着文件一起要被处理的其他参数
- success和error:提交成功或失败的处理方式
至此,文件上传的前端部分就写好了!
3.在action中接受文件,将该文件放到写入流中,再用输出流输出到指定位置
public class FileUpload extends ActionSupport{
private File fileup;//文件对象
private String fileupFileName;//文件名
private String fileupContentType;//文件类型
private String docname;
private String docuper;
private String doctime;
private String doctype;
private String docimg;
private String doccontent;
private String result;
@Override
public String execute() throws Exception {
InputStream is = new FileInputStream(fileup);//创建写入流对象
HttpServletRequest request=ServletActionContext.getRequest();
ServletContext servletContext=request.getSession().getServletContext();
String wholepath=servletContext.getRealPath("/");
// int outindex=wholepath.indexOf("out");
// String path=wholepath.substring(0,outindex)+"web\\document";
String path=wholepath+"document";
String ext = fileupFileName.substring(fileupFileName.lastIndexOf(".")+1);//获取文件扩展名
//这里先获取资料的数量
GetDocNum gdn=new GetDocNum();
int docid=gdn.get()+1;
String filePath = path+"/doc"+docid+"."+ext;
OutputStream os = new FileOutputStream(filePath);//创建输出流对象
System.out.println("文件全路径:"+filePath);//输出文件全路径
IOUtils.copy(is, os);//输出
os.close();
is.close();
//写入数据库
//创建连接
Dbconnection dbconn=new Dbconnection();
Connection conn=dbconn.connect();
if(conn==null) {
System.out.println("连接失败");
}else {
System.out.println("连接成功");
}
DocUpload du=new DocUpload();
if(du.upload(conn,docname,docuper,doctime,doctype,docimg,doccontent,"."+ext)==true){
result="success";
}else{
result="error";
}
return SUCCESS;
}
public void setFileup(File fileup) {
this.fileup = fileup;
}
public void setFileupFileName(String fileupFileName) {
this.fileupFileName = fileupFileName;
}
public void setFileupContentType(String fileupContentType) {
this.fileupContentType = fileupContentType;
}
public File getFileup() {
return fileup;
}
public String getFileupFileName() {
return fileupFileName;
}
public String getFileupContentType() {
return fileupContentType;
}
此处省略其他成员变量的set和get方法
}
我们在处理文件的action中对文件进行处理,上面的一团我将会分解出来看:
首先我们要让action接受到这个文件和其相关参数,因此我们添加一些成员变量,主要有三个文件对象、文件名、文件类型,文件对象的变量名必须和file标签中的name属性(也就是fileup)一致,文件名是文件对象名+FileName,文件类型是文件对象名+ContentType!!!
然后为他们添加set和get方法,struts2会自动调用这些方法进行赋值,这样我们就接受到文件了
private File fileup;//文件对象
private String fileupFileName;//文件名
private String fileupContentType;//文件类型
有了文件之后,我们要把他放到写入流中
InputStream is = new FileInputStream(fileup);//创建写入流对象
然后我们要输出,输出之前我们要处理一下输出路径以及输出的文件名
通过getrealpath方法获得当前项目的根路径
HttpServletRequest request=ServletActionContext.getRequest();
ServletContext servletContext=request.getSession().getServletContext();
String wholepath=servletContext.getRealPath("/");
这里需要注意的是,由于我们的项目是运行在tomcat上的,所以idea会定位到out/artifacts文件夹中对应项目的根目录而不是我们真正本地的项目根目录,因此调试的时候需要改变该目录的路径,我们将out后的路径替换成我们本地的目录对应的文件夹即可
int outindex=wholepath.indexOf("out");
String path=wholepath.substring(0,outindex)+"web\\document";
然而在真正发布的时候,由于使用的是linux系统,因此路径又要改了,他会直接定位到webroot根目录下,因此只要加上文件夹名就可以了
String path=wholepath+"document";
我们对filepath进行一些处理之后即可输出
String filePath = path+"/doc"+docid+"."+ext;
OutputStream os = new FileOutputStream(filePath);//创建输出流对象
System.out.println("文件全路径:"+filePath);//输出文件全路径
IOUtils.copy(is, os);//输出
os.close();
is.close();
4.配置web.xml文件
这里我只使用了最简单的配置,更详细的配置可以看看其他博客的介绍
<package name="filepack" extends="json-default" namespace="/">
<!-- 上传action -->
<action name="fileupaction" class="com.mis.file.FileUpload">
<result name="success" type="json"></result>
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedExtensions">txt,jpg,gif,png,doc,docx,rar,zip,pdf,pptx,xlsx</param>
</interceptor-ref>
</action>
</package>
这样一来,我们就能把文件传到指定的文件夹啦!
二,文件的下载
文件的下载就更简单了,主要有以下几个步骤:
1.发起下载请求
我们可以直接在a标签的href中写上下载需要的action即相关参数
<a href="/resumedownloadaction.action?fileName=resume.docx&downfileName=工作安排" >点击下载工作安排</a>
也可以通过ajax对action发出请求,这里我就不写啦!
2.处理下载请求
首先我们引入两个成员变量,一个是要下载的文件名称,一个是下载时浏览器弹出的下载名称,并为他们生成get和set方法
private String fileName;
private String downfileName;
我们在execute方法中不写业务逻辑,直接返回success
public String execute() throws Exception {
return SUCCESS;
}
然后我们在web.xml中进行如下配置,我们让处理success时返回的是一个流,并且配置他的流名称叫DownloadFile,设置他在浏览器中下载时的文件名是action中的成员变量downfileName
<action name="resumedownloadaction" class="com.mis.myclass.ResumeDownload">
<result name="success" type="stream">
<param name="inputName">DownloadFile</param>
<param name="contentDisposition"> attachment;filename=${downfileName}</param>
<param name="bufferSize">10240</param>
</result>
</action>
3.返回输出流
我们回到action中,编写getDownloadFile方法,这里DownloadFile要和web.xml中流的名称相同,首先还是定位到要下载的文件的文件夹即文件,idea和eclipse以及windows和linux的区别上面已经说了,然后我们对浏览器的下载名要进行中文处理,否则会出现类似“____**”或者action的名称这种文件名,我们将编码集换成ISO8859-1即可,然后我们建立输入流,返回该流
public InputStream getDownloadFile() throws Exception{
HttpServletRequest request=ServletActionContext.getRequest();
ServletContext servletContext=request.getSession().getServletContext();
String wholepath=servletContext.getRealPath("/");
//windows下
// int outindex=wholepath.indexOf("out");
// String filePath=wholepath.substring(0,outindex)+"web\\resume\\"+fileName;
//linux下
String filePath=wholepath+"resume/"+fileName;
System.out.println(filePath);
int dotindex=fileName.indexOf(".");
String ext= fileName.substring(dotindex);
downfileName=downfileName+ext;
downfileName=new String(downfileName.getBytes(),"ISO8859-1");
InputStream is = new FileInputStream(new File(filePath));
return is;
}
这样,我们的下载请求就能得到处理,浏览器会弹出下载提示。
小结:struts对文件的上传和下载的一些资料网上还是有一些的,但是经过我的尝试,基本都是有问题的,这些是我综合其他资料试验成功的版本,可能对一些用法还不是很熟悉和详尽,但是基本能完成大部分的需求了。