javaweb-文件的上传下载

本文用到的jar包:

文件上传:commons-fileupload-1.2.1.jar;

commons-io-1.4.jar;

本文需要掌握的知识:html+dom

1 文件的上传概述;

1.1 用户把本地的文件储存到服务器上,就是文件的上传;

1.2 实现文件的上传(目前而言要使用第三方jar包);

1.2.1 jspSmartupload;

适用范围:应用在jsp的模型一里(嵌入执行上传下载操作的JSP文件中)  ;

1.2.2 fileUpload;

来源:Apache commons下面的开源,免费项目(谢谢老板);

适用范围:(mvc模式);

1.3 要使用文件的上传,需要满足三个要求:

①表单数据提交,提交方式为post提交;

②在表单里有一个文件的上传想<input type=”file” name=”filename”/>

③在form里面,要设置一个属性值,enctype,设置为multipart/form-data(必须设置,不然只有一个文件名之类的)

2  文件上传的原理分析:

从请求响应信息可知;

Content-Type:multipart/form-data;

通过请求正文可以得到结论:

①找到分割线;

②根据分割线区别不同的项;

③普通输入项得到的是值;

④文件上传项,得到文件的内容,把内容写到服务器里面一个文件中;

⑤使用输入流得到文件上传的内容,使用输出流把文件的内容写到服务器上;

3,文件上传的代码实现的步骤(固定步骤,照着写就可以了);

3.1 :创建磁盘文件工厂;

new DiskFileItemFactory();

3.2:创建核心上传类;

new ServletFileUpload(FileItemFactory fileItemFactory);

3.3:使用核心上传类解析request对象;

parseRequest(-----request(全类名就不写了));

返回的是一个List集合,集合中有多个FileItem,泛型为<FileItem>;

3.4:遍历list集合,得到每个FileItem;

3.5:判断是普通输入项还是文件上传项;

Boolean isFormField();

3.6:如果是普通输入项;如果是文件上传项编写文件上传的代码;

普通输入项:

getField():得到普通输入项name的值;

getString():得到普通输入项里面输入的值;

文件上传项:

得到通过表单提交的文件的输入流,getInputStream;

创建输出流,写出文件到服务器的相应的位置(输出位置要带有盘符,通过

getServletContext().getRealPath(相对路径)可以获取.为什么要这样做,是因为项目在别的服务器上真实路径就不一定一致了,所以要通过相对路径获取到真实路径);

4,核心API的学习(主要是一些重要的方法);

4.1 DiskFileItemFactory(磁盘文件项工厂)(核心上传类,重点在于构造);

构造方法;

DiskFileItemFactory(int sizeThreshold,java.io.File repository);

两个参数:

第一个参数设置上传文件缓冲区的大小;

第二个参数.如果上传文件超出了缓冲区,产生临时文件,设置临时文件路径

(可以看做是先用一个等大小的临时文件做占位,然后数据一步步填充);

DiskFileItemFactory() 无参构造,也可以设置缓冲区;

setSizeThreadshold(int sizeThreadshold):设置上传文件的缓冲区(单位是字节byte);

setRepository(java.io.File repository):设置临时文件路径;

4.2 ServletFileUpload:核心上传类;

构造方法;

ServletFileUpload(FileItemFactory fileItemFactory);

重要方法:;

parseRequest(javax.servlet.HttpServletRequest request):解析request对象;

返回一个list<FileItem>集合,每一个元素都是一个FileItem;

在他的父类中还有一个很重要的方法;

setHeaderEncoding(java.lang.String encoding);设置上传文件名称的编码;

setFileSizeMax(long filesizeMax)”:设置单个文件的大小;

setSIzeMax(long sizeMax): 设置单个文件的总大小;

4.3 FileItem:文件项

Boolea isFormField():判断是否是普通输入项;

getFieldName():得到普通输入项.name的属性值;

getString():得到普通输入项的文本值;

getString(encoding):设置输入项中文本的编码;

getName():得到上传文件的名称(但是有些浏览器得到的带路径的名称,所以要进行截取操作,哭);

getInputStream():得到表单提交的文件输入流;

Delete():删除临时文件(要在关闭流之后删除);

5 JS控制多文件的上传

5.1 需求:在上传的表单里面有两个按钮,一个是上传文件的按钮,一个是增加的按钮,增加上传项.

点击增加按钮之后,增加一行,一个上传输入项和一个删除的按钮

点击删除按钮之后,删除该行

点击上传按钮之后,把当前的文件上传到服务器里面去

5.2 使用js增加一行和删除一行

<script type="text/javascript">

//增加一行

function addFile(){

//在table里面增加一行

var table = document.getElementsByTagName("table")[0];

table.innerHTML+="<tr><td><input type=‘file‘ name=‘filename‘/></td><td><input type=‘button‘ value=‘删除‘ onclick=‘dele(this)‘/><td/><tr/> ";

}

//删除一行

function dele(who){

//获取当前点击的删除按钮所在的tr

var tr=who.parentNode.parentNode;

//拿到爸爸

var table=tr.parentNode;

//通过爸爸删除儿子

table.removeChild(tr);

}

</script>

5.3 使用button提交表单的方法

//通过按钮提交表单实现上传

function uploadFile(){

var form =document.getElementsByTagName("form")[0];

form.submit();

}

5.4 常见问题的解决:

5.4.1 当已经存在名字重复的文件,再次上传会新文件覆盖原文件

解决方式:在上传的文件名称里添加一个随机的唯一的字符串,保证每个文件都是唯一的值(可以通过uuid生成,也可以使用毫秒数,不过推荐用uuid更加保险

//生成一个随机的唯一的id值

String id = UUID.randomUUID().toString();

JSP页面(为什么我没找到jsp代码选择)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="${pageContext.request.contextPath }/servlet/Upload2" method="post"  enctype="multipart/form-data">
        <input type="button" value="上传" onclick="uploadFile()"/>
        <input type="button" value="增加" onclick="addFile()"/><hr/>
        <table>

        </table>
        <%--
        <input type="file" name="filename"/><input type="button" value="删除"/>
        --%></form>
</body>
<script type="text/javascript">
    //通过按钮提交表单实现上传
    function uploadFile(){
        var form =document.getElementsByTagName("form")[0];
        form.submit();
    }
    //增加一行
    function addFile(){
        //在table里面增加一行
        var table = document.getElementsByTagName("table")[0];
        table.innerHTML+="<tr><td><input type=‘file‘ name=‘filename‘/></td><td><input type=‘button‘ value=‘删除‘ onclick=‘dele(this)‘/><td/><tr/> ";
    }
    //删除一行
    function dele(who){
        //获取当前点击的删除按钮所在的tr
        var tr=who.parentNode.parentNode;
        //拿到爸爸
        var table=tr.parentNode;
        //通过爸爸删除儿子
        table.removeChild(tr);
    }
</script>
</html>

servlet处理页面(对应的图片文件就不放上来了)

package com.zzx.upload;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class Upload2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            //1,創建磁盤文件工廠
            DiskFileItemFactory dff = new DiskFileItemFactory();
            //2,創建核心上傳類
            ServletFileUpload fileupload = new ServletFileUpload(dff);
            fileupload.setHeaderEncoding("utf-8");
            //3,解析对应的请求数据
            List<FileItem> fl = fileupload.parseRequest(request);
            for (FileItem fileItem : fl) {
                 //判断是否是普通输入项
                if(fileItem.isFormField()){
                    //如果是普通输入项,就得到普通输入项name的属性值,和输入的值
                    String name = fileItem.getFieldName();
                    String value = fileItem.getString();
                    System.out.println(name + ":" + value);
                }else{
                    //如果是文件上传项
                    //获取上传的文件名称,但是有的浏览器里面带的是带路径的名称
                    String filename = fileItem.getName();
                    //优化,判断是否带/,如果带"/"就进行截取,否则就直接用
                    int lens=filename.lastIndexOf("/");
                    if(lens!=-1){
                        filename=filename.substring(lens+1);
                    }
                    //获取文件上传的输入流
                    InputStream is =fileItem.getInputStream();
                    //得到文件夹带盘符的路径
                    String path = getServletContext().getRealPath("/upload");
                    //输出流
                    OutputStream os =new FileOutputStream(path + "/" + filename);
                    //流对接
                    int len=0;
                    byte[]arr =new byte[1024*8];
                    while((len = is.read(arr))!=-1){
                        os.write(arr,0,len);
                    }
                    //关流
                    is.close();
                    os.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }

}

6 文件的下载:

6.1 把服务器上文件保存到本地硬盘,这个过程称为文件的下载

6.2 文件下载的实现方式:

6.2.1:  实现超链接的文件下载

弊端:有的文件无法实现下载,而是显示在页面上(比如图片)

6.2.2:  通过代码实现文件下载

无论什么格式的文件都可以下载

实现步骤:

第0步:设置要下载的文件MIME类型(可选)

第一步:设置头信息,Content-Disposition,无论什么格式,都是以下载的方法打开

第二步:服务器得到文件的输入流

第三步:创建输出流,写出到浏览器

第四步:流对接

具体代码:

6.3 常见问题:

6.3.1 当文件名携带中文的时候(中文名称会乱码,不显示之类的问题)

6.3.2 原因:不同浏览器编码不同

ie浏览器采用的是url编码,

火狐浏览器采用的是base64编码,

6.3. 3  ① 区分不同的浏览器

通过请求头 User-Agent,得到当前浏览器的请求类型

②根据不同的浏览器设置不同的编码(IE,谷歌解决方式一致)

这里是文件下载的页面

package com.zzx.down;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

import com.sun.xml.internal.messaging.saaj.util.Base64;
/*
 * 这个页面是实现文件的下载
 */
public class DownServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            //0,得到文件的路径
        String path = getServletContext().getRealPath("/down/图片.jpg");
            //得到文件名
            //这里寻找"/"要注意使用"\\"才能正确的截取
        String filename = path.substring(path.lastIndexOf("\\")+1);
        //得到请求的浏览器类型
        String agent = request.getHeader("User-Agent");
        //判断浏览器类型
        System.out.println(agent);
        if(agent.contains("Firefox")){
            //如果是火狐,进行base64编码
            filename = "=?UTF-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8")) + "?=";
        }else{
            //url编码,谷歌,IE都可以通过这样设置
            filename=URLEncoder.encode(filename, "UTF-8");
        }
            //1,设置文件的mime类型
            //先得到文件的mime类型
        String type = getServletContext().getMimeType(filename);
            //设置
        response.setContentType(type);
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);
           //得到输入流
        InputStream is = new FileInputStream(path);
           //得到输出流
        OutputStream os = response.getOutputStream();
           //2,流对接
        int a=0;
        byte[]arr =new byte[1024*8];
        while((a = is.read(arr))!=-1){
            os.write(arr,0,a);
        }
        //3,关流
        os.close();    //会自动关闭,不过要养成关流的习惯
        is.close();

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }

}
时间: 2024-12-21 23:34:07

javaweb-文件的上传下载的相关文章

JAVAWEB之文件的上传下载

文件上传下载 文件上传: 本篇文章使用的文件上传的例子使用的都是原生技术,servelt+jdbc+fileupload插件,这也是笔者的习惯,当接触到某些从未接触过的东西时,总是喜欢用最原始的东西将他们表达出来.下面是具体的步骤,大家可以跟着我一步一步的用apache的fileupload插件来完成文件的上传下载. 1.创建一个web工程,我们这里取名为fileupload 2.导入相关jar包,,数据源使用的是apache-c3p0数据源,以及上传下载插件包,goson库,以及mysql驱动

通过scp实现文件的上传下载

一.什么是scp? Scp 是SSH自带的一个内置命令,是安全拷贝的意思,可以实现文件的上传和下载,传输速率快,    安全性高. 二.通过scp实现文件的上传下载 1.  从服务器下载文件到本地 (1)不指定身份下载 例:下载服务器172.25.254.116的/home/student/test/QQ/12.txt到本地/home/kiosk/ 不指定身份下载默认以当前登陆用户下载,如果当前登陆用户对下载文件没有读写权限将不能下载 (2)指定身份下载 例:以root身份下载服务器172.25

文件的上传下载

文件的上传下载包括文件的上传和文件的下载两部分,下面以项目的形式给出,项目的结构如下图所示: 项目的思路如下: 1.启动项目,输入地址:http://localhost:8080/fileUpload/upload/upload.jsp,进入文件上传界面upload.jsp. 2.文件上传的路径是UploadHandleServlet,创建临时保存文件路径(在项目的根目录的web-inf下面):                                   D:\ruanjian\tomc

asp.Net文件的上传下载(2) 转

Asp.net 上传.下载文件 2011-01-08 16:21:48|  分类: .NET |  标签: |举报 |字号大中小 订阅 首先我们要判断用户是否选择了要上传文件,我们可用下面这句实现: if(File1.PostedFile.ContentLength>0)  如果用户有上传的文件,则:   string name = File1.PostedFile.FileName ;//获取输入的文件名字      int i= name.LastIndexOf(".") ;

asp.net文件的上传下载

Web.Config 配置文件 <?xml version="1.0"?> <configuration> <appSettings>    <add key="FileUploadPath" value="Upload/" />    <add key="FileTypeLimit" value=".zip,.rar,.dox,.ppt,.txt,.mp3&qu

HttpClient实现文件的上传下载

1 HTTP HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源. 虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活.HttpClient 用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议. 一般的情况下我们都是使用Chrome或者

Asp.net实现MVC处理文件的上传下载功能实例教程

这篇文章主要介绍了Asp.net实现MVC处理文件的上传下载功能,比较全面而系统的对Asp.net MVC的文件上传下载功能进行了深入分析,有很好的借鉴价值,需要的朋友可以参考下 上传于下载功能是程序设计中非常常见的一个功能,在ASP.NET程序开发中有着非常广泛的应用.本文就以实例形式来实现这一功能. 一.概述 如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUploa

python使用ftplib模块实现FTP文件的上传下载

python已经默认安装了ftplib模块,用其中的FTP类可以实现FTP文件的上传下载 FTP文件上传下载 # coding:utf8 from ftplib import FTP def upload(f, remote_path, local_path): fp = open(local_path, "rb") buf_size = 1024 f.storbinary("STOR {}".format(remote_path), fp, buf_size) f

用struts2实现文件的上传下载

在做B/S系统时经常会有文件上传下载的需求,现就基于struts2框架实现其功能 Struts2框架默认采用Commons-fileupload组件完成文件上传功能.? 使用Struts2框架实现文件上传功能,只需在Action中定义一个java.io.File类型的成员并为之设立setter方法,方法名要和参数名对应.? 客户端上传的文件, Struts2框架会自动将其保存在临时文件中,封装成java.io.File类对象.如果还想得到上传的文件名和文件类型,需按照如下命名规则在Action中

struts2 文件的上传下载 表单的重复提交 自定义拦截器

文件上传中表单的准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置为 post 需添加 <input type=“file”> 字段. Struts 对文件上传的支持 在 Struts 应用程序里, FileUpload 拦截器和 Jakarta Commons FileUpload 组件可以完成文件的上传. 步骤:1. 在 Jsp 页面的文件上传表单里使用