Web基础了解版12-上传下载

上传

两个步骤:

  1. 用户在页面中选择要上传的文件,然后将请求提交到Servlet
  2. Servlet收到请求,解析用户上传的文件,然后将文件存储到服务器

上传文件表单

<form action="Servlet" method="post" enctype="multipart/form-data">
    <input type="file" name="file" /><br /><br />
    <input type="submit" value="上传" />
</form>

注意:

  • 表单的method属性必须为post
  • 表单的enctype属性必须为multipart/form-data
  • 上传文件的控件是intput,type属性为file

注意:Servelet

  • 当enctype="multipart/form-data" 时,再使用getParamter()获取到内容永远为空。
  • 需要引入解析请求中的参数和文件,这个工具就是commons-fileupload。

commons-fileupload

它的作用就是可以从request对象中解析出,用户发送的请求参数和上传文件的流。

commons-fileupload包依赖commons-io,两个包需要同时导入

核心类:

  1. DiskFileItemFactory

    1. 工厂类,用于创建ServletFileUpload,设置缓存等
    2. 该类一般直接使用构造器直接创建实例
    3. 方法:
      • public void setSizeThreshold(int sizeThreshold):用于设置缓存文件的大小(默认值10kb)
      • public void setRepository(File repository):用于设置缓存文件位置(默认系统缓存目录)
  2. ServletFileUpload
    1. 该类用于解析request对象从而获取用户发送的请求参数(包括普通参数和文件参数)
    2. 该类需要调用有参构造器创建实例,构造器中需要一个DiskFileItemFactory作为参数
    3. 方法:
      • public List<FileItem> parseRequest(HttpServletRequest request):解析request对象,获取请求参数,返回的是一个List,List中保存的是一个FileItem对象,一个对象代表一个请求参数。
      • public void setFileSizeMax(long fileSizeMax):设置单个文件的大小限制,单位为B。如果上传文件超出限制,会在parseRequest()抛出异常FileSizeLimitExceededException。
      • public void setSizeMax(long sizeMax):限制请求内容的总大小,单位为B。如果上传文件超出限制,会在parseRequest()抛出异常SizeLimitExceededException。
  3. FileItem
    1. 该类用于封装用户发送的参数和文件,也就是用户发送来的信息将会被封装成一个FileItem对象,我们通过该对象获取请求参数或上传文件的信息。
    2. 该类不用我们手动创建,由ServletFileItem解析request后返回。
    3. 方法:
      • String getFieldName():获取表单项的名字,也就是input当中的name属性的值。
      • String getName():获取上传的文件名,普通的请求参数为null。
      • String getString(String encoding):获取内容,encoding参数需要指定一个字符集。

        ① 若为文件,将文件的流转换为字符串。

        ② 若为请求参数,则获取请求参数的value。

      • boolean isFormField():判断当前的FileItem封装的是普通请求参数,还是一个文件。

        ① 如果为普通参数返回:true

        ② 如果为文件参数返回:false

      • String getContentType():获取上传文件的MIME类型
      • long getSize():获取内容的大小
      • write():将文件上传到服务器
//创建工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建请求解析器
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//设置上传单个文件的的大小
fileUpload.setFileSizeMax(1024*1024*3);
//设置上传总文件的大小
fileUpload.setSizeMax(1024*1024*3*10);
//设置响应内容的编码
response.setContentType("text/html;charset=utf-8");
try {
    //解析请求信息,获取FileItem的集合
    List<FileItem> items = fileUpload.parseRequest(request);
    //遍历集合
    for (FileItem fileItem : items) {
        //如果是普通的表单项
        if(fileItem.isFormField()){
            //获取参数名
            String fieldName = fileItem.getFieldName();
            //获取参数值
            String value = fileItem.getString("utf-8");
            System.out.println(fieldName+" = "+value);
            //如果是文件表单项
        }else{
            //获取文件名
            String fileName = fileItem.getName();
            //获取上传路径
            String realPath = getServletContext().getRealPath("/WEB-INF/upload");
            //检查upload文件夹是否存在,如果不存在则创建
            File f = new File(realPath);
            if(!f.exists()){
                f.mkdir();
            };
            //为避免重名生成一个uuid作为文件名的前缀
            String prefix = UUID.randomUUID().toString().replace("-", "");
            //将文件写入到服务器中
            fileItem.write(new File(realPath+"/"+prefix+"_"+fileName));
            //清除文件缓存
            fileItem.delete();
        }  }
} catch (Exception e) {
    if(e instanceof SizeLimitExceededException){
        //文件总大小超出限制
        response.getWriter().print("上传文件的总大小不能超过30M");
    }else if(e instanceof FileSizeLimitExceededException){
        //单个文件大小超出限制
        response.getWriter().print("上传单个文件的大小不能超过3M");
    }
}
response.getWriter().print("上传成功");

下载

下载文件的关键点:

  1. 服务器以一个流的形式将文件发送给浏览器。
  2. 发送流的同时还需要设置几个响应头,来告诉浏览器下载的信息。
    • 具体响应头如下:

      • Content-Type

        • 下载文件的MIME类型
        • 可以通过servletContext. getMimeType(String file)获取
        • 也可以直接手动指定
        • 使用response.setContentType(String type);
        • 响应头样式:Content-Type: audio/mpeg
      • Content-Disposition
        • 下载文件的名字,主要作用是提供一个默认的用户名
        • 通过response.setHeader("Content-Disposition", disposition)设置
        • 响应头样式:Content-Disposition: attachment; filename=xxx.mp3
      • Content-Length
        • 下载文件的长度,用于设置文件的长处(不必须)
        • 通过response. setContentLength(int len)设置。
        • 设置后样式:Content-Length: 3140995
  3. 接下来需要以输入流的形式读入硬盘上的文件
    • FileInputStream is = new FileInputStream(file);
    • 这个流就是我们一会要发送给浏览器的内容
  4. 通过response获取一个输出流,并将文件(输入流)通过该流发送给浏览器
    • 获取输出流:ServletOutputStream out = response.getOutputStream();
    • 通过输出流向浏览器发送文件(不要忘了关闭输入流)

步骤演示

以下步骤都是在同一个Servlet的doGet()方法中编写的

1.获取文件的流:

String realPath = getServletContext().getRealPath("/WEB-INF/mp3/中国话.mp3");
//获取文件的File对象
File file = new File(realPath);
//获取文件的输入流
FileInputStream in = new FileInputStream(file);

2.获取头信息:

//获取文件的MIME信息
String contentType = getServletContext().getMimeType(realPath);
//设置下载文件的名字
String filename = "zhongguohua.mp3";
//创建Content-Disposition信息
String disposition = "attachment; filename="+ filename ;
//获取文件长度
long size = file.length();

3.设置头信息

//设置Content-Type
response.setContentType(contentType);
//设置Content-Disposition
response.setHeader("Content-Disposition", disposition);
//设置文件长度
response.setContentLength((int)size);

4.发送文件

//通过response获取输出流,用于向浏览器输出内容
ServletOutputStream out = response.getOutputStream();
//将文件输入流通过输出流输出
byte[] b = new byte[1024];
int len = 0;
while((len=is.read(b))> 0){
    out.write(b, 0, len);
}
//最后不要忘记关闭输入流,输出流由Tomcat自己处理,我们不用手动关闭
is.close();

乱码

中文文件名会出现乱码问题。解决此问题的方法很简单,在获取文件名之后为文件名进行编码:

filename = java.net.URLEncoder.encode(filename,"utf-8");

火狐浏览器比较特殊需要特殊处理一下。

1.先要获取客户端信息(通过获取请求头中的User-Agent信息)

String ua = request.getHeader("User-Agent");

2.然后判断浏览器版本,做不同的处理

//判断客户端是否为火狐
if(ua.contains("Firefox")){
    //若为火狐使用BASE64编码
    filename = "=?utf-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
}else{
    //否则使用UTF-8
    filename = URLEncoder.encode(filename,"utf-8");
}
String string = new String("你好.jpg".getBytes("gbk"), "iso8859-1");

原文地址:https://www.cnblogs.com/Open-ing/p/12151037.html

时间: 2024-08-30 14:19:39

Web基础了解版12-上传下载的相关文章

web基础----&gt;Fileupload文件的上传

这里我们介绍文件上传的知识,使用的是apache的Commons FileUpload框架. 文件上传的使用 项目的部分结构如下: 一.使用Commons FileUpload的上传功能,我们需要引入两个jar包:commons-fileupload和commons-io.首先我们列出html的部分 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g

Servlet Java Web开发(6)上传下载和邮件

上传 先看一个例子: 对应form的代码 <form action="<c:url value='/Upload1Servlet'/>" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username"/><br/> 照 片:<input type=&q

java web 文件上传下载

文件上传下载案例: 首先是此案例工程的目录结构: 处理上传: FileUploadServlet.java 1 package fnz.fileUploadTest; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.PrintWriter; 7 import java.text.SimpleDateFormat; 8 import java.

Robot Framework--13 RFS+AutoItLibrary测试web上传下载

转自:http://blog.csdn.net/tulituqi/article/details/21888059 Selenium2library在我们实际测试web页面的时候基本上已经够用了,不过还是会有部分情况下会脱离Selenium2library的控制,无法进行操作.比如说下载文件的时候,要选择保存文件在什么地方,比如说上传文件的时候,要选择上传哪个文件,这些在Selenium2library下都没有很好的处理办法.但是结合上AutoItLibrary,就可以很好的来进行处理了.结合A

Java Web总结(二)-- 上传和下载

  在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件.这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,st

2.1.5基础之命令行链接ftp dos中的ftp上传下载文件

Windows命令行batcmd脚本的应用之自动备份 异地备份2.1.5基础之命令行链接ftp dos中的ftp上传下载文件 讲解环境 VMware Workstation 12 桌面虚拟计算机软件创建虚拟机安装操作系统:http://edu.51cto.com/course/10007.html PC1:192.168.1.201 远程地址:192.168.100.100:2001 windows service2008 pc1 Admin111FTP虚拟用户 fileaa fileaaPC2

salesforce 零基础学习(四十二)简单文件上传下载

项目中,常常需要用到文件的上传和下载,上传和下载功能实际上是对Document对象进行insert和查询操作.本篇演示简单的文件上传和下载,理论上文件上传后应该将ID作为操作表的字段存储,这里只演示文件上传到Document对象中. 一.文件上传功能 apex代码 1 public with sharing class FileUploadUsedTransientController { 2 3 public transient Blob fileUploadBody{get;set;} 4

Win Form + ASP.NET Web Service 文件上传下载--HYAppFrame

本章节主要讲解HYAppFrame服务器端如何ASP.NET Web Service实现文件(含大文件)上传,WinForm客户端如何下载文件. 1    服务器端文件上传 1.1 上传文件 函数FileUpload(stringfileFullPath, byte[] file)用于上传文件,生成文件前检查文件路径所在文件夹是否存在,不存在则首先创建文件夹. [WebMethod(EnableSession = true,Description = "上传文件")] public i

Android与Asp.Net Web服务器的文件上传下载BUG汇总【更新】

遇到的问题: 1.java.io.IOException: open failed: EINVAL (Invalid argument)异常,在模拟器中的sd卡创建文件夹和文件时报错 出错原因可能是:(1)文件名称中含有不符合规范的字符,比如“:”,“?”或者空格等.(2)需要先创建文件夹目录再创建文件,不能直接创建文件. 2. android.os.NetworkOnMainThreadException异常,从服务器请求数据后,写入文件时报错 出错原因:在主线程内执行了访问http的操作,最

上传下载简单版

server------------ #!/usr/bin/env python # encoding: utf-8  # Date: 2018/6/7 import socketimport osimport jsonimport struct shar_dir = r'E:\python\PycharmProjects\python.base.demo\model3\socket1\上传下载\简单版本\server\share' phone = socket.socket(socket.AF