Java中实现文件上传下载的三种解决方案(推荐)
java文件上传与文件下载是程序开发中比较常见的功能,下面通过本文给大家介绍java中实现文件上传下载的三种解决方案,具体详情如下所示;
第一点:java代码实现文件上传
formfile file=manform.getfile(); string newfilename = null; string newpathname=null; string fileaddre="/numup"; try { inputstream stream = file.getinputstream();// 把文件读入 string filepath = request.getrealpath(fileaddre);//取系统当前路径 file file1 = new file(filepath);//添加了自动创建目录的功能 ((file) file1).mkdir(); newfilename = system.currenttimemillis() + file.getfilename().substring( file.getfilename().lastindexof('.')); bytearrayoutputstream baos = new bytearrayoutputstream(); outputstream bos = new fileoutputstream(filepath + "/" + newfilename); newpathname=filepath+"/"+newfilename; system.out.println(newpathname); // 建立一个上传文件的输出流 system.out.println(filepath+"/"+file.getfilename()); int bytesread = 0; byte[] buffer = new byte[8192]; while ((bytesread = stream.read(buffer, 0, 8192)) != -1) { bos.write(buffer, 0, bytesread);// 将文件写入服务器 } bos.close(); stream.close(); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); }
第二点:jsp页面上实现文件上传
package com.vogoal.util; import java.io.bufferedoutputstream; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.text.simpledateformat; import java.util.arraylist; import java.util.date; import java.util.hashtable; import javax.servlet.servletinputstream; import javax.servlet.http.httpservletrequest; public class jspfileupload { /** request对象 */ private httpservletrequest request = null; /** 上传文件的路径 */ private string uploadpath = null; /** 每次读取得字节的大小 */ private static int bufsize = 1024 * 8; /** 存储参数的hashtable */ private hashtable paramht = new hasptable(); /** 存储上传的文件的文件名的arraylist */ private arraylist updfilearr = new arraylist(); /** * 设定request对象。 * * @param request * httpservletrequest request对象 */ public void setrequest(httpservletrequest request) { this.request = request; } /** * 设定文件上传路径。 * * @param path * 用户指定的文件的上传路径。 */ public void setuploadpath(string path) { this.uploadpath = path; } /** * 文件上传处理主程序。�������b * * @return int 操作结果 0 文件操作成功;1 request对象不存在。 2 没有设定文件保存路径或者文件保存路径不正确;3 * 没有设定正确的enctype;4 文件操作异常。 */ public int process() { int status = 0; // 文件上传前,对request对象,上传路径以及enctype进行check。 status = precheck(); // 出错的时候返回错误代码。 if (status != 0) return status; try { // ��参数或者文件名�u�� string name = null; // 参数的value string value = null; // 读取的流是否为文件的标志位 boolean fileflag = false; // 要存储的文件。 file tmpfile = null; // 上传的文件的名字 string fname = null; fileoutputstream baos = null; bufferedoutputstream bos = null; // ��存储参数的hashtable paramht = new hashtable(); updfilearr = new arraylist(); int rtnpos = 0; byte[] buffs = new byte[bufsize * 8]; // �取得contenttype string contenttype = request.getcontenttype(); int index = contenttype.indexof("boundary="); string boundary = "--" + contenttype.substring(index + 9); string endboundary = boundary + "--"; // �从request对象中取得流。 servletinputstream sis = request.getinputstream(); // 读取1行 while ((rtnpos = sis.readline(buffs, 0, buffs.length)) != -1) { string strbuff = new string(buffs, 0, rtnpos); // 读取1行数据�n�� if (strbuff.startswith(boundary)) { if (name != null && name.trim().length() > 0) { if (fileflag) { bos.flush(); baos.close(); bos.close(); baos = null; bos = null; updfilearr.add(fname); } else { object obj = paramht.get(name); arraylist al = new arraylist(); if (obj != null) { al = (arraylist) obj; } al.add(value); system.out.println(value); paramht.put(name, al); } } name = new string(); value = new string(); fileflag = false; fname = new string(); rtnpos = sis.readline(buffs, 0, buffs.length); if (rtnpos != -1) { strbuff = new string(buffs, 0, rtnpos); if (strbuff.tolowercase().startswith( "content-disposition: form-data; ")) { int nindex = strbuff.tolowercase().indexof( "name=\""); int nlastindex = strbuff.tolowercase().indexof( "\"", nindex + 6); name = strbuff.substring(nindex + 6, nlastindex); } int findex = strbuff.tolowercase().indexof( "filename=\""); if (findex != -1) { fileflag = true; int flastindex = strbuff.tolowercase().indexof( "\"", findex + 10); fname = strbuff.substring(findex + 10, flastindex); fname = getfilename(fname); if (fname == null || fname.trim().length() == 0) { fileflag = false; sis.readline(buffs, 0, buffs.length); sis.readline(buffs, 0, buffs.length); sis.readline(buffs, 0, buffs.length); continue; }else{ fname = getfilenamebytime(fname); sis.readline(buffs, 0, buffs.length); sis.readline(buffs, 0, buffs.length); } } } } else if (strbuff.startswith(endboundary)) { if (name != null && name.trim().length() > 0) { if (fileflag) { bos.flush(); baos.close(); bos.close(); baos = null; bos = null; updfilearr.add(fname); } else { object obj = paramht.get(name); arraylist al = new arraylist(); if (obj != null) { al = (arraylist) obj; } al.add(value); paramht.put(name, al); } } } else { if (fileflag) { if (baos == null && bos == null) { tmpfile = new file(uploadpath + fname); baos = new fileoutputstream(tmpfile); bos = new bufferedoutputstream(baos); } bos.write(buffs, 0, rtnpos); baos.flush(); } else { system.out.println("test :" + value + "--" + strbuff); value = value + strbuff; } } } } catch (ioexception e) { status = 4; } return status; } private int precheck() { int errcode = 0; if ( request == null ) return 1; if ( uploadpath == null || uploadpath.trim().length() == 0 ) return 2; else{ file tmpf = new file(uploadpath); if (!tmpf.exists()) return 2; } string contenttype = request.getcontenttype(); if ( contenttype.indexof("multipart/form-data") == -1 ) return 3; return errcode; } public string getparameter(string name){ string value = ""; if ( name == null || name.trim().length() == 0 ) return value; value = (paramht.get(name) == null)?"":(string)((arraylist)paramht.get(name)).get(0); return value; } public string[] getparameters(string name){ if ( name == null || name.trim().length() == 0 ) return null; if ( paramht.get(name) == null ) return null; arraylist al = (arraylist)paramht.get(name); string[] strarr = new string[al.size()]; for ( int i=0;i<al.size();i++ ) strarr[i] = (string)al.get(i); return strarr; } public int getupdfilesize(){ return updfilearr.size(); } public string[] getupdfilenames(){ string[] strarr = new string[updfilearr.size()]; for ( int i=0;i<updfilearr.size();i++ ) strarr[i] = (string)updfilearr.get(i); return strarr; } private string getfilename(string input){ int findex = input.lastindexof("\\"); if (findex == -1) { findex = input.lastindexof("/"); if (findex == -1) { return input; } } input = input.substring(findex + 1); return input; } private string getfilenamebytime(string input){ int index = input.indexof("."); date dt = new date(); simpledateformat sdf = new simpledateformat("yyyymmddhhmmsssss"); return input.substring(0,index) + sdf.format(dt) + input.substring(index); } }
2.在jsp页面中进行引用该java类:
<%@page import="com.vogoal.util.jspfileupload"%> <% //初始化 jspfileupload jfu = new jspfileupload(); //设定request对象 jfu.setrequest(request); //设定上传的文件路径 jfu.setuploadpath("c:\\"); //上传处理 int rtn = jfu.process(); //取得form中其他input控件参数的值 string username = jfu.getparameter("username"); //如果对应同一个参数有多个input控件,返回数组 string[] usernamearr = jfu.getparameters("username"); //取得上传的文件的名字 string[] filearr = jfu.getupdfilenames(); //取得上传文件的个数,这个方法有点鸡肋 int filenumber = jfu.getupdfilesize(); //下面的是测试输出的代码。 // out.println("parameter:" + username); // out.println("parameter size:" + usernamearr.length); // out.println("filearr size:" + filearr.length); // if (filearr.length > 0) // out.println("filearr 0:" + filearr[0]); %>
第三点:struts2实现文件的上传和下载
第一步:在web-inf/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。
第二步:把form表的enctype设置为:“multipart/form-data“,如下:
java代码
public class uploadaction{ private file uploadimage; //文件 private string uploadimagecontenttype;//文件的类型 private string uploadimagefilename;//文件的名称 private string bookname;//书名 private string author;//作者 private string savepath;//文件的保存位置 //属性的getter/setter方法 public string upload() throws exception{ //实现上传代码,i/o操作完成 return "uploadsuccess"; } }
注:一个表单里的文件域对应action中三个属性,分别是文件,文件名,文件类型,命名是固定的,文件名必须表单中的文件域名称相同(uploadimage),文件名为:文件+filename,文件类型:文件+contenttype。
第四步:将我们的上传action配置到struts.xml中。
java代码
<action name="upload" class="com.gqy.uploadaction"> <param name="savepath">/uploadfile</param> <result>/success.jsp</result> </action>
注:指定上传文件的在服务器上的保存目录,需要在uploadaction中为定义savepath变量并为其添加相应的setter和getter方法,便于struts2将/uploadfile值赋给savepath属性,即要想在uploadaction中使用savepath变量必须在uploadaction定义。
手动配置文件过滤类型
<param name="allowtypes"> image/bmp,image/png,image/gif,image/jpeg </param>
手动配置文件大小限制
<param name="maximumsize" >1048576</param>
使用struts2的文件上传拦截器实现文件过滤
struts2提供了一个文件上传的拦截器—fileupload,通过配置该拦截器可以方便实现上传文件的过滤。
配置fileupload拦截器时,可以为其指定两个参数:
allowedtypes:指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开。
maximumsize:指定允许上传的文件大小,单位是字节。
提示:通过配置fileupload拦截器,可以轻松的实现文过滤,当文件过滤失败后,系统自动转入input逻辑视图,因此必须为该action配置名为input的逻辑视图,除此之外,还必须显示地为该action配置defaultstack的拦截器引用。
使用struts2的拦截器实现文件过滤配置如下:
<action name="uploadfileaction" class="com.actions.uploadfileaction"> <interceptor-ref name="defaultstack"> <!-- 配置允许上传的文件类型,多个用","分隔 --> <param name="fileupload.allowedtypes"> image/bmp,image/png,image/gif,image/jpeg,image/jpg ,image/x-png, image/pjpeg </param> <!-- 配置允许上传的文件大小,单位字节,本例为:1mb --> <param name="fileupload.maximumsize">1048576</param> </interceptor-ref> <result name="input">/jsp/onefilefileupload.jsp</result> <result name="success">/jsp/result.jsp</result> </action>
当用户上传失败后,需要有一定的提示信息。在struts2中,使用<s:fielderror/>标签即可将错误提示信息输出到页面中。
注:要想使用struts2错误提示信息,则上传文件的action类,必须继承actionsupport,否则struts2不会提供输出错误提示信息功能。
我们可以配置资源文件(.properties)来保存输出给用户的信息。
struts.messages.eror.file.too.large:当上传文件大小超过设定的值时,struts2将输出该key对应的提示信息。
struts.messages.error.content.type.not.allowed:当上传文件类型不符合设定的值时,struts2将输出该key对应的提示信息。
struts.messages.error.uploading:当上传文件时出现未知错误时,struts2将输出该key对应的提示信息。
我们还要将资源文件配置到struts.xml文件中,接下来看看我们的资源文件,已经包含中文了,得把它进行一下转换再配置到工程中。
在struts.xml中设定资源文件:
<constant name="struts.custom.i18n.resources" value="messages"/>或 <constant name="struts.custom.i18n.resources" value="messages_zh_cn"/>
用命令native2ascii d:\messages.properties d:\messages_zh_cn.properties将原有的资源文件转换成支持中的。
注:保持国际化,资源文件的名称后缀为: *_zh_cn+文件扩展名的形式。
对于多个文件上传的原理同上,但是需要注意的是,多个文件域的name属性名必须相同,而且在action中应该使用file [] 或者list<file>来接收。
个人觉得用这样的方式进行多个文件上传不是
很好。
struts2进行文件下载
struts2提供了stream结果类型,该结果类型专门用于支持文件下载的功能。当指定stream结果类型时,需要配置一个inputname参数,该参数指定了一个输入流,这个输入流是被下载文件的入口(即通过该入口才能实现文件以流的方式实现下载)。
实现文件下载的action
public class filedownloadaction implements action{ //该属性值在配置文件中指定,struts2会自动进行注入(即赋值),需要为该属性提供setter和 getter方法 private string inputpath;//指定要下载的文件的完整路径(路径名+文件名) /* * 实现下载的action类应该提供一个返回inputstream实例的方法,该方法对应在 <result.../>里的inputname属性值为targetfile */ public inputstream gettargetfile() throws exception{ return servletactioncontext.getservletcontext().getresourceasstream(inputpath); } //处理用户请求的execute方法,该方法返回success字符串 public string execute() throws exception{ return "success"; } }
对应action在struts.xml文件中的配置
<action name="download" class="com.filedownloadaction"> <!--指定被下载资源的位置--> <param name="inputpath">/uploadfile/demo.txt</param> <!--配置结果类型为stream的结果--> <result name="success" type="stream"> <!--指定下载文件的文件类型--> <param name="contenttype"></param> <!--指定下载文件的文件位置--> <param name="inputname">targetfile</param> <!--指定下载文件的下载方式及下载时的保存文件名,filename保存时的文件名必须有扩展名,扩展名指示了下载类型的图标--> <param name="contentdisposition"> attachment;filename=struts2.txt </param> <!--指定下载文件的缓冲区大小--> <param name="buffersize">4096</param> </result> </action>
以上所述是小编给大家介绍的java中实现文件上传下载的三种解决方案,希望对大家有所帮助