一.简述
我这里实现网页上的文件上传和下载是用struts2框架来实现的,具体是对java.io数据流的操作。过程是先在网页将文件上传到服务器里,并且这些文件在网页上可以显示出来,可以供别人下载。
二.上传下载演示
1.文件上传
2.点击浏览,选择文件上传
3.下载文件界面
4.选择坦克大战项目下载
三.文件上传
首先看文件上传,通过jsp文件上传文件到服务器,你可以保存在该项目的相对路径下的webContent下,也可以保存在绝对路径下。
具体操作:
1.首先创建一个上传文件的jsp
<body>
<form action="uploadAction" method="post"
enctype="multipart/form-data">
文件上传:<input type="file" name="myFile">
<input type="submit" style="margin-left: 0px" value="上传" />
</form>
</body>
这里要设置action要和struts.xml里的对应,HTML表单如何打包数据文件是由enctype这个属性决定的,所以要设置enctype,这里是以二进制形式传值。
2.创建uploadAction
package com.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private File myFile;// 上传的文件,对应表单的file的name属性
private String myFileContentType;// 文件类型,xxxContentType,xxx对应表单file的name属性
private String myFileFileName;
@Override
public String execute() throws Exception {
if (myFile == null) {
this.addFieldError("file", "文件不能为空,请选择");
return INPUT;
} else {
InputStream is = new FileInputStream(this.getMyFile());
OutputStream os = new FileOutputStream(new File("D:/文件上传下载/WebContent/upload", this.getMyFileFileName()));
/* String path = ServletActionContext.getRequest().getRealPath("/upload");
InputStream is = new FileInputStream(this.getMyFile());
OutputStream os = new FileOutputStream(new File(path,this.getMyFileFileName()));
InputStream is=new FileInputStream(this.getMyFile());
String directory="/upload";
String target=ServletActionContext.getServletContext().getRealPath(directory);//需要在webroot目录下创建一个upload目录
OutputStream os=new FileOutputStream(target+"\\"+this.getMyFileFileName());
System.out.println(target);*/
byte[] buf = new byte[1024];
int length = 0;
while ((length = is.read(buf)) > 0) {
os.write(buf, 0, length);
}
is.close();
os.close();
}
return SUCCESS;
}
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public String getMyFileContentType() {
return myFileContentType;
}
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}
public String getMyFileFileName() {
return myFileFileName;
}
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}
}
我用的是上传到绝对路径,上传到相对路径下的代码我也展示了,自己可以去调试下。
3.接下来配置struts.xml文件就行了
<action name="uploadAction" class="com.action.UploadAction">
<result name="input">management.jsp</result>
<result>/success.jsp</result>
<interceptor-ref name="fileUpload">
<!-- 不写下面两个参数为允许所有大小所有类型的文件的上传 -->
<!-- <param name="maximumSize">1024000</param>
<param name="allowedTypes">
application/msword,image/jpeg,image/zip,image/txt
</param> -->
</interceptor-ref>
<interceptor-ref name="defaultStack" />
</action>
在这里可以去用拦截器去限制上传文件大小和类型。
四.文件下载
也就是从你上传文件的相应路径下载。
1.先来看看struts.xml配置文件
<action name="download" class="com.action.DownloadAction" >
<result name="success" type="stream">
<!-- image/jpeg代表JPG图片 -->
<!-- <param name="contentType">image/jpeg</param> -->
<!-- 下载文件处理方法 -->
<param name="contentDisposition">
<!-- attachment表示附件方式,即下载时打开保存对话窗,filename表示下载时显示的保存时的文件名 -->
<!-- 如果不写attachment;或者是写的是inline; 则表示内联,即会在浏览器中尝试打开下载的文件,而不是下载-->
attachment;filename="${filename}"
</param>
<!-- 下载文件输出流定义 -->
<!-- 这里的inputName元素所对应的value值downloadFile,在action中一定要有对应的getDownloadFile()方法 -->
<param name="inputName">downloadFile</param>
<!-- 下载缓冲区的大小 -->
<!-- <param name="bufferSize">1024</param> -->
</result>
</action>
这里有个type属性设置为stream, 意思是把一般内容输出到流。
contentType:指定文件格式(内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片)。
contentDisposition :其中attachment 将会告诉浏览器下载该文件,filename 指定下载文件保有存时的文件名,el表达式${filename}表示去去filename的值,可以实现动态下载。
bufferSize:下载缓冲区的大小。
<param name="inputName">downloadFile</param
>这里是获取文件输出流,设置成downloadfile但acton里要有getdownloadfile方法。
2.创建downloadAction
package com.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import com.opensymphony.xwork2.ActionSupport;
public class DownloadAction extends ActionSupport {
private static final long serialVersionUID = 1L;
// 文件路径
private String filename;
public String getFilename() throws UnsupportedEncodingException {
this.filename = new String(filename.getBytes(), "ISO8859-1");
return filename;
}
public void setFilename(String filename) throws UnsupportedEncodingException {
this.filename = filename;
}
// 返回inputstream,文件下载关键方法
public InputStream getDownloadFile() throws Exception {
//InputStream in = ServletActionContext.getServletContext().getResourceAsStream("/upload/" + filename);
File file=new File("D:/JAVA WEB/JAVA WEB代码/工作室网站/WebContent/upload/"+filename);
InputStream in=new FileInputStream(file);
return in;
}
public String execute() throws Exception {
return SUCCESS;
}
}
在getDownloadFile你可以去用相对路径去找你要下载的文件,也可以绝对路径,我实现的是绝对路径,另一种我也展示了你可以自己去调试。
然后还有个中文问题,如果你的文件名是中文的话,取值会有问题没显示,就像下面图片一样。
解决方式:在getFilename里加上
this.filename = new String(filename.getBytes(), "ISO8859-1");
这行代码,因为网页上传值是以ISO8859-1格式传的,所以获得文件名字时要转换一下。
3.文件显示
我们想上传文件之后就有显示可以下载,我是去遍历文件夹的,然后在网页上显示。
<body>
<%
//取得服务器"/download/file"目录的物理路径
File file = new File("D:/JAVA WEB/JAVA WEB代码/工作室网站/WebContent/upload");
//取得file目录下所有文件
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++)
{
String fname = files[i].getName();
//对文件名进行url编码(UTF-8指明fname原来的编码,UTF-8一般由本地编码GBK代替)
fname = java.net.URLEncoder.encode(fname, "UTF-8");
out.println("<a href=download.action?Filename=" + fname + ">"
+ files[i].getName() + "</a><br>");
}
%>
</body>