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

首先为大家介绍相关的技术
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>

效果图:

点击之后的效果图:

传文件名不一样

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

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

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

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

需要的包:

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

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

详解:
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为存储的绝对路径--之前定义的}
这样能实现简单的上传,但是,这种上传是没有一点安全行了。完整的代码中附上了防一般的小问题还是没问题的

选择文件之后

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

文件上传源代码:

<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> 

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

(0)

相关推荐

  • 实现前后端数据交互方法汇总

    此文章适合前后端协同开发经验不足的新手阅读. HTML赋值 输出到 Element 的 value 或 data-name <input type="hidden" value="<?php echo $user_avatar;?>" /> <div data-value="<?php echo $user_avatar;?>"></div> 渲染结果 <input type=&q

  • 原生node.js案例--前后台交互

    本案例包含4部分:(1)HTML部分:(2)ajax部分:(3)JavaScript部分:(4)node服务器部分.另外,因为牵涉到服务器,所以这里没法"效果预览". 执行过程为: (1)在浏览器地址栏输入网址,向node服务器发送HTML请求:服务器接到请求后,返回一个HTML文件给客户端: (2)客户端浏览器对HTML进行渲染,遇到<script>标签后,再次向服务器请求,服务器响应一个JavaScript文件给客户端, (3)客户端浏览器对JavaScript文件进行

  • 利用Node.js+Koa框架实现前后端交互的方法

    前言 对于一个前端工程师来说不仅仅要会前端的内容,后端的技术也需要熟练掌握.今天我就要通过一个案例来描述一下前端是如何和后端进行数据交互的. koa 是由 Express 原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的 Web 框架.使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率.koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手. 准备工作 首先

  • Spring MVC前端与后端5种ajax交互方法【总结】

    前端ajax与后端Spring MVC控制器有以下五种数据交互方式.(前台使用了dhtmlxGrid,后端使用了fastjson) 方式一 通过URL传参 通过URL挂接参数,如/auth/getUser?userid='6' 服务器端方法可编写为:getUser(String userid),也可新增其他参数如HttpSession, HttpServletRequest,HttpServletResponse,Mode,ModelAndView等. 方式二 单值传参 前台调用如: ajaxP

  • SpringMVC实现前端后台交互传递数据

    本人对springmvc前端交互不太懂,搜索了很多关于springmvc前端交互介绍,下面我来记录一下,有需要了解的朋友可参考.希望此文章对各位有所帮助. Controller.java代码: @Controller public class DataController { //一.接收和通过ModelMap传出参数,不需要视图解析器,测试时加了解析器,顾返回值不需后缀 //普通参数 @RequestMapping("/data1") public String data1(@Req

  • SpringMVC前端和后端数据交互总结

    本文主要介绍了SpringMVC前端和后端数据交互的资料,特地发出来记录一下.有需要的朋友可以了解一下. 控制器 作为控制器,大体的作用是作为V端的数据接收并且交给M层去处理,然后负责管理V的跳转.SpringMVC的作用不外乎就是如此,主要分为:接收表单或者请求的值,定义过滤器,跳转页面:其实就是servlet的替代品. 传值方式 springmvc最方便的一点就是可以通过注释方式来定义它的url. @Controller public class formMVC { @RequestMapp

  • Silverlight融合ajax实现前后台数据交互

    事出偶然,本来公司强调的是用WCF 做项目审批流程,WPF /E 增强用户体验:由于个人的无知与偷懒,我产生了天真的想法:用WPF/E 来做审批流程,这不是一举两得吗. 下面介绍的就是用Silverlight (微软在07 年9 月将WPF/E 更名为Silverlight )融合ajax 做的审批流程.界面上的审批流程从下向上包括3部分,部门审批,科技处审批,厂长审批.实现的功能是可以定制审批流程,比如审批流程是部门审批--> 厂长审批,也可以定制成科技处审批--> 厂长审批.定制的数据存在

  • 前后台交互过程中json格式如何解析以及如何生成

    前台: 复制代码 代码如下: $.ajax({ type: "POST", url: "GetMenuRole.ashx", data: "", dataType: "json", success: function (data) { if (data.Status == false) { alert(data.ErrorReason); } else { //解析这个菜单列表 alert(data.MenuList); }

  • jQuery Ajax前后端使用JSON进行交互示例

    需求: 前端通过jQuery Ajax传输json到后端,后端接收json,对json进行处理,后端返回一个json给前端 这里使用servlet的方式 1.采用$.post方法 index.jsp页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <%

  • 前端ajax的各种与后端交互的姿势

    前端中常常用的与后端交换数据的话,通常是要用到ajax这种方法的 但是交互的方式有很多种,很多取决于你后端的属性,我这儿主要列举我目前项目比较常用的两种方式 --一个是我们通用的web api和控制器, 首先我们来仔细看看ajax来与webapi做的交互数据 这里先简单描述一下web api的四种属性--GET,POST,PUT,DELETE 这里面我永昌使用的是GET和POST 如果这时候我们需要用到AJAX与那些数据做后端交互的话 $.ajax({ url: "你的webapi",

随机推荐