欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaEE实现前后台交互的文件上传与下载

程序员文章站 2024-03-06 21:56:32
首先为大家介绍相关的技术: service方法中的两个重要参数。 servletrequest – 用接收用户的请求,它的作用是: 可获取请求头信息。...

首先为大家介绍相关的技术
service方法中的两个重要参数。
servletrequest – 用接收用户的请求,它的作用是:

  • 可获取请求头信息。
  • 可设置请请求的字符编码。
  • 可获得用户传递的参数。post或get。
  • 可获取远程(即访问者)的ip地址。
  • 可获取输入流,如用户上传文件、相片等。

它的一个子接口:javax.servlet.http.httpservletrequest
servletresponse – 用于向用户返回数据。

  • 设置响应类型- contenttype
  • 设置编码-setcharacterencoding
  • 获取输出流。

它的一个子接口:javax.servlet.http.httpservletresponse
文件下载技术:
文件下载技术相当于文件上传技术相对而言比较简单。我们以下载图片为例:
图片都是先浏览再下载
1.前端代码:

<span style="font-size:14px;"><a href="img">查找文件夹下面的所有图片</a><br/></span> 

前台只需要一句话就可以搞定了。直接通过web.xml查找后台的程序
2.后台显示代码:

<span style="font-size:14px;">public class showimg extends httpservlet { 
 public void doget(httpservletrequest request, httpservletresponse response) 
   throws servletexception, ioexception { 
<span style="white-space:pre"> </span>dopost(request, response);//为了防止异常,将doget和dopost连接在一起 
 }</span> 
 
<span style="font-size:14px;">public void dopost(httpservletrequest request, httpservletresponse response) 
   throws servletexception, ioexception { 
 
  request.setcharacterencoding("utf-8"); 
  response.setcontenttype("text/html;charset=utf-8"); 
  printwriter out = response.getwriter();</span> 
 
<pre name="code" class="html"><span style="font-size:14px;">//<span style="white-space:pre">  </span>调出servletcontext,当然也可以直接调用---当一一列出图片的时候需要文件的绝对路径</span> 
servletcontext context =getservletcontext();string path=context.getrealpath("/imgs");//找到该文件夹的绝对路径file file =new file(path);
 
<span style="font-size:14px;">//<span style="white-space:pre">  </span>找到文件夹之后,列出所有图片供用户浏览 
  string files[] =file.list(); 
  for(string fn:files){</span> 
 
<pre name="code" class="html"><span style="font-size:14px;">//一个个的全部显示出来</span> 

string img="<img src='imgs/"+fn+"'/>";
// out.print("<a href=imgs/'"+fn+"'>下载图片</a>");string str="<a href='down?name=imgs/"+fn+"'>下载图片</a>";//提供下载的超链接,传参---传文件名给用户链接内容下面写out.print(str);out.print(img+"<br/>");}}

3.文件的具体下载
首先必须设置相应的协议。下载协议就需要设置相应的下载头

<span style="white-space:pre"> </span><span style="font-size:18px;"><strong>response.setcontenttype("application/force-download"</strong>);//设置相应头</span> 

下载的时候需要显示当前图片的文件名,需要从前台获取,并且从下载获得之后写到前台去

<span style="font-size:18px;"> <span style="white-space:pre"> </span>outputstream out=response.getoutputstream();//获得输出流 
 string name=request.getparameter("name");//从客服端传过来的参数名 
 int num=name.lastindexof("/"); 
 string aa=name.substring(num+1); 
 aa=urlencoder.encode(aa, "utf-8");//若是中文需要重新编码 
 //system.out.println(aa); 
 response.setheader("content-disposition",<span style="color:#ff0000;">"<strong>attachment;filename</strong></span>='"+aa+"'");//获取从那边传过来的文件名,以便于存储的时候为下载用户名</span> 

 进行具体的下载

<span style="font-size:18px;"> string filename=this.getservletcontext().getrealpath(name);//获得绝对路径,传文件名过来,同时传了可以获得的绝对路径就可以进行读可写了 
 inputstream in=new fileinputstream(filename); 
 byte[] b=new byte[1024]; 
 int len=0; 
 while((len=in.read(b))!=-1){ 
 out.write(b, 0, len); 
 }</span> 

效果图:

JavaEE实现前后台交互的文件上传与下载

点击之后的效果图:

JavaEE实现前后台交互的文件上传与下载

传文件名不一样

JavaEE实现前后台交互的文件上传与下载

文件上传技术
文件上传要是自己去写会很麻烦,所以我们可以用别人的包,下载链接点击打开链接
表单:

客户端发送http必须使用multipart/form-data数据类型,表示复合数据类型。

即:<form enctype=“multipart/form-data”>

在表单中使用<input type=“file” name=“somename”/>html标签。

需要的包:

commons-fileupload.jar,核心上传文件工具都在这个包中。

commons-io.jar – 上传文件所需要的包

JavaEE实现前后台交互的文件上传与下载

详解:
diskfileitemfactory-创建监时文件目录,指是缓存区大小
servletfileupload用于解析httpservletrequest。返回一组文件对象。
fileitem – 表示用户上传的每一个文件对像。
主要流程:
file f  = new file("f:/ex/temp");//指定临时文件存放位置
diskfileitemfactory ff =new diskfileitemfactory(1024*1024*5, f);//临时文件的大小和存放位置
servletfileupload sf =new servletfileupload(ff);
       list<fileitem> list=sf.parserequest(request);//开始解析
for(fileitem it:list){//获得文件名。以及用到uuid解决重名的问题
fileutils.copyinputstreamtofile(it.getinputstream(), new file(path+"/"+filename));//写的指定的文件夹中
}
1、前台代码:

<span style="font-size:18px;"><h2>上传文件</h2> 
 <form action="upfile" method="post" <span style="color:#ff0000;">enctype="multipart/form-data"</span> >//必须要写,不然后台没办法去接收数据 
 <!-- 必须添加这个enctype="multipart/form-data"--> 
 file1<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/> 
 请输入名称:<input type="text" <span style="color:#ff6666;">name</span>="desc"/><br/> 
 file2<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/> 
 请输入名称:<input type="text"<span style="color:#ff0000;"> name</span>="desc"/><br/> 
 <input type="submit" value="提交"/> 
 </form></span> 

2、后台代码:
2-1首先创建一个基于硬盘的工厂,用来存放临时文件

//指定临时存放位置 
file f = new file("f:/ex/temp");//指定临时文件存放位置 
diskfileitemfactory ff =new diskfileitemfactory(1024*1024*5, f);//临时文件的大小和存放位置 

2-2 创建一个用servletfileupload对象,并且设置文件大小,最大允许传多大的文件

//创建用于解析的对象 
 servletfileupload sf =new servletfileupload(ff); 
 sf.setfilesizemax(1024*1024*10);//仅仅允许单个存放位置最大值是 10m 
 sf.setsizemax(1024*1024*20);//所有文件的最大值是20m 
 string path =this.getservletcontext().getrealpath("/imgs"); 
 system.out.println("存储路径:"+path); 

2-3 开始解析对象

<span style="white-space:pre"> </span>list<fileitem> list=sf.parserequest(request);//获得从前台传过来的所有信息,前台必须填写enctype="multipart/form-data" 
  for(fileitem it:list){ 
  it0=it; 
//<span style="white-space:pre">  </span>若是普通表单对象--可以直接判断出 
  if(it.isformfield()){//是普通表单项,如 type=text里面name的值 
   string name=it.getstring("utf-8"); 
   system.out.println("基本表单项 name:"+name);//下面写的解释的名字 
  }else{ 
<span style="white-space:pre">  </span>// 这就是前台选择的文件名 
   string name=it.getname();//具体的文件路径---绝对路径 
//   string str=it.getstring();//文件里面的内容 
//   system.out.println("str"+str); 
   string contenttype=it.getcontenttype(); 
   long size=it.getsize(); 
 <span style="white-space:pre">  </span>system.out.println(name+","+contenttype+","+size); 
<pre name="code" class="html" style="font-size: 18px;">//<span style="white-space:pre">   </span>在服务器端的资源文件名不能用中文,浏览器会自动编码-------必须要把用户上传的文件名转成没有中文的名字存储, 
   //为了让用户在下载时能还原出原来的名字,就要把原文件名和映射名的对应关系存储起来,在用户下载时再转换回来 

 //映射名string id=uuid.randomuuid().tostring().replace("-", "");//全球唯一uuid来进行//文件名string lastname=name.substring(name.lastindexof("."));//文件格式//名字文件格式都找到了---组合string filename =id+lastname;//新的文件名//拷贝流。让它写到相应位置fileutils.copyinputstreamtofile(it.getinputstream(), new file(path+"/"+filename));//path为存储的绝对路径--之前定义的}
这样能实现简单的上传,但是,这种上传是没有一点安全行了。完整的代码中附上了防一般的小问题还是没问题的

JavaEE实现前后台交互的文件上传与下载

选择文件之后

JavaEE实现前后台交互的文件上传与下载

查看web服务器img里面的文件,文件已经上传到该页面《文件名为uuid生成的文件名》

JavaEE实现前后台交互的文件上传与下载

文件上传源代码:

<span style="font-size:14px;">package cn.hncu.upfile;import java.io.file; 
import java.io.ioexception; 
import java.io.printwriter; 
import java.io.writer; 
import java.util.list; 
import java.util.uuid; 
import javax.servlet.servletexception; 
import javax.servlet.http.httpservlet; 
import javax.servlet.http.httpservletrequest; 
import javax.servlet.http.httpservletresponse;import org.apache.commons.fileupload.fileitem; 
import org.apache.commons.fileupload.fileuploadexception; 
import org.apache.commons.fileupload.disk.diskfileitemfactory; 
import org.apache.commons.fileupload.servlet.servletfileupload; 
import org.apache.commons.io.fileutils; 
public class myupfile extends httpservlet { 
<span style="white-space: pre;"> </span>//doget防止有人在用户栏输入地址。没有响应 
<span style="white-space: pre;"> </span>@override 
<span style="white-space: pre;"> </span>protected void doget(httpservletrequest req, httpservletresponse resp) 
<span style="white-space: pre;"> </span>throws servletexception, ioexception { 
<span style="white-space: pre;"> </span>resp.setcontenttype("utf-8"); 
<span style="white-space: pre;"> </span>writer wr=resp.getwriter(); 
<span style="white-space: pre;"> </span>wr.write("暂不支持该上传方式"); 
<span style="white-space: pre;"> </span>} 
<span style="white-space: pre;"> </span> 
<span style="white-space: pre;"> </span>public void dopost(httpservletrequest request, httpservletresponse response) 
<span style="white-space: pre;"> </span>throws servletexception, ioexception { 
<span style="white-space: pre;"> </span>request.setcharacterencoding("utf-8"); 
<span style="white-space: pre;"> </span>response.setcontenttype("text/html;charset=utf-8"); 
<span style="white-space: pre;"> </span>printwriter out=response.getwriter(); 
<span style="white-space: pre;"> </span>//防护 以普通表单上传 法一: 
<span style="white-space: pre;"> </span>//返回值 get (null) post1(apllication/x-form-urlencoded,普通表单) post2(file:multipart/form-data,文件上传表单) 
//<span style="white-space: pre;"> </span>string type =request.getcontenttype(); 
//<span style="white-space: pre;"> </span>if(!type.contains("mulitpart/form-data")){ 
//<span style="white-space: pre;"> </span>out.write("不支持普通表单的上传2"); 
//<span style="white-space: pre;"> </span>return ; 
//<span style="white-space: pre;"> </span>} 
<span style="white-space: pre;"> </span>// 法二 
<span style="white-space: pre;"> </span>boolean boo=servletfileupload.ismultipartcontent(request); 
<span style="white-space: pre;"> </span>if(boo==false){ 
<span style="white-space: pre;"> </span>out.print("不支持普通表单的上传1"); 
<span style="white-space: pre;"> </span> 
<span style="white-space: pre;"> </span>} 
<span style="white-space: pre;"> </span> 
<span style="white-space: pre;"> </span>//指定临时存放位置 
<span style="white-space: pre;"> </span>file f = new file("f:/ex/temp");//指定临时文件存放位置 
<span style="white-space: pre;"> </span>diskfileitemfactory ff =new diskfileitemfactory(1024*1024*5, f);//临时文件的大小和存放位置 
<span style="white-space: pre;"> </span> 
<span style="white-space: pre;"> </span>//创建用于解析的对象 
<span style="white-space: pre;"> </span>servletfileupload sf =new servletfileupload(ff); 
<span style="white-space: pre;"> </span>sf.setfilesizemax(1024*1024*10);//仅仅允许单个存放位置最大值是 10m 
<span style="white-space: pre;"> </span>sf.setsizemax(1024*1024*20);//所有文件的最大值是20m 
<span style="white-space: pre;"> </span>string path =this.getservletcontext().getrealpath("/imgs"); 
<span style="white-space: pre;"> </span>system.out.println("存储路径:"+path); 
<span style="white-space: pre;"> </span>//开始进行解析 
<span style="white-space: pre;"> </span>fileitem it0=null;//用于在finally中进行删除临时文件 
<span style="white-space: pre;"> </span>try { 
<span style="white-space: pre;"> </span>list<fileitem> list=sf.parserequest(request);//获得从前台传过来的所有信息,前台必须填写enctype="multipart/form-data" 
<span style="white-space: pre;"> </span>for(fileitem it:list){ 
<span style="white-space: pre;"> </span>it0=it; 
<span style="white-space: pre;"> </span>if(it.isformfield()){//是普通表单项,如 type=text里面name的值 
<span style="white-space: pre;">  </span>string name=it.getstring("utf-8"); 
<span style="white-space: pre;">  </span>system.out.println("基本表单项 name:"+name);//下面写的解释的名字 
<span style="white-space: pre;"> </span>}else{ 
<span style="white-space: pre;">  </span>string name=it.getname();//具体的文件路径 
//<span style="white-space: pre;">  </span>string n1=it.getfieldname(); 
//<span style="white-space: pre;">  </span>string str=it.getstring();//文件里面的内容 
//<span style="white-space: pre;">  </span>system.out.println("str"+str); 
//<span style="white-space: pre;">  </span>system.out.println("n1:"+n1); 
<span style="white-space: pre;">  </span>string contenttype=it.getcontenttype(); 
<span style="white-space: pre;">  </span>long size=it.getsize(); 
<span style="white-space: pre;">  </span>//防止文件为空 
<span style="white-space: pre;">  </span>if(size==0){ 
<span style="white-space: pre;">  </span>continue;//文件为空,直接返回; 
<span style="white-space: pre;">  </span>} 
<span style="white-space: pre;">  </span>//用户名。必须要填写 
<span style="white-space: pre;">  </span>if(name==null||name.trim()==""){ 
<span style="white-space: pre;">  </span>continue; 
<span style="white-space: pre;">  </span>} 
<span style="white-space: pre;"> </span>//<span style="white-space: pre;"> </span>system.out.println(name+","+contenttype+","+size); 
<span style="white-space: pre;">  </span>//在服务器端的资源文件名不能用中文,浏览器会自动编码-------必须要把用户上传的文件名转成没有中文的名字存储, 
<span style="white-space: pre;">  </span>//为了让用户在下载时能还原出原来的名字,就要把原文件名和映射名的对应关系存储起来,在用户下载时再转换回来 
<span style="white-space: pre;">  </span>//映射名 
<span style="white-space: pre;">  </span>string id=uuid.randomuuid().tostring().replace("-", ""); 
<span style="white-space: pre;">  </span>//文件名 
<span style="white-space: pre;">  </span>string lastname=name.substring(name.lastindexof(".")); 
<span style="white-space: pre;">  </span>//名字文件格式都找到了---组合 
<span style="white-space: pre;">  </span>string filename =id+lastname; 
<span style="white-space: pre;">  </span>//拷贝流。让它写到相应位置 
<span style="white-space: pre;">  </span>fileutils.copyinputstreamtofile(it.getinputstream(), new file(path+"/"+filename));}<span style="white-space: pre;"> </span>}} catch (fileuploadexception e) { 
<span style="white-space: pre;"> </span>throw new runtimeexception("文件上传解析错误。"+e); 
<span style="white-space: pre;"> </span>}finally{ 
<span style="white-space: pre;"> </span>if(it0==null){ 
<span style="white-space: pre;"> </span>it0.delete();//删除临时文件 
<span style="white-space: pre;"> </span>}}out.close();}}</span><span style="font-size: 18px;"> 
</span> 
文件下载源代码:
[html] view plaincopyprint?
<span style="font-size:14px;">package cn.hncu.downimg; 
 
import java.io.fileinputstream; 
import java.io.ioexception; 
import java.io.inputstream; 
import java.io.outputstream; 
import java.io.printwriter; 
import java.net.urlencoder; 
 
import javax.servlet.servletexception; 
import javax.servlet.http.httpservlet; 
import javax.servlet.http.httpservletrequest; 
import javax.servlet.http.httpservletresponse; 
 
public class downimgdemo extends httpservlet { 
 
 
 public void doget(httpservletrequest request, httpservletresponse response) 
 throws servletexception, ioexception { 
 dopost(request, response); 
 } 
 
 
 public void dopost(httpservletrequest request, httpservletresponse response) 
 throws servletexception, ioexception { 
 //设置相应头 
 response.setcontenttype("application/force-download"); 
 //给前台传用户名 
 /*传固定的用户名 
 string aa="1.jpg";//若是中文,需要编码 
 aa=urlencoder.encode(aa, "utf-8"); 
 response.setheader("content-disposition", "attachment;filename='"+aa+"'");////必须要加“attachment;”,否则会变成浏览 
 */ 
 
 outputstream out=response.getoutputstream();//获得输出流 
 string name=request.getparameter("name");//从客服端传过来的参数名 
 int num=name.lastindexof("/"); 
 string aa=name.substring(num+1); 
 aa=urlencoder.encode(aa, "utf-8");//若是中文需要重新编码 
 //system.out.println(aa); 
 response.setheader("content-disposition","attachment;filename='"+aa+"'");//获取从那边传过来的文件名,以便于存储的时候为下载用户名 
 
 string filename=this.getservletcontext().getrealpath(name);//获得绝对路径 
 inputstream in=new fileinputstream(filename); 
 byte[] b=new byte[1024]; 
 int len=0; 
 while((len=in.read(b))!=-1){ 
 out.write(b, 0, len);}}}</span><span style="font-size: 18px;"> 
</span> 

以上就是本文的全部内容,希望对大家的学习有所帮助。