组件工作流程:WEB服务器request

ServletFil

eupLoad

DiskFileItem

Factory代表普通字段的FileItem代表上传文件1FileItem代表上传文件2FileItem

isFileForm

getFieldName

getString

getInputStream

getName

getInputStream

getName核心API-DiskFileItemFactory:DiskFileItemFactory是创建FileItem对象的工厂,这个工厂常用方法:1. public DiskFileItemFactory(int sizeThreshold, java.io.File repository),常用的构造函数。2. public void setSizeThreshold(int sizeThreshold),设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时, fileupload组件将使用临时文件缓存上传文件。3. public void setRepository(java.io.File repository),指定临时文件目录,默认值为System.getProperty("java.io.tmpdir")。核心API-ServletFileupLoad:

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装到一个FileItem对象中。常用方法有:1. boolean isMultipartContent(HttpServletRequest request),判断上传表单是否为上传表单类型。2. List parseRequest(HttpServletRequest request),解析request对象,并把表单中的每一个输入项包装到一个fileItem对象中,并返回一个保存了所有FileItem的list集合。3. setFileSizeMax(long fileSizeMax),设置上传文件的最大尺寸值。4. setSizeMax(long sizeMax),设置上传文件总量的最大值。5. setHeaderEncoding(java.lang.String encoding),设置编码格式。如果文件路径中存在中文可能会造成文件路径乱码,用此方法处理可以解决。6. setProgressListener(ProgressListener pListener),设置进程监听器,与AWT和Swing的事件处理机制一样。文件上传一点就会触发ProgressListener,这样我们就可以获取文件上传的进度。#上传文件案例:public class FileuploadServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//创建文件处理工厂,它用于生成FileItem对象。DiskFileItemFactory difactory = new DiskFileItemFactory();

//设置缓存大小,如果上传文件超过缓存大小,将使用临时目录做为缓存。difactory.setSizeThreshold(1024 * 1024);

//设置处理工厂缓存的临时目录,此目录下的文件需要手动删除。String dir = this.getServletContext().getRealPath("/");

File filedir = new File(dir + "filetemp");

if (!filedir.exists())

filedir.mkdir();

difactory.setRepository(filedir);

//设置文件实际保存的目录String userdir = dir + "files";

File fudir = new File(userdir);

if (!fudir.exists())

fudir.mkdir();

//创建request的解析器,它会将数据封装到FileItem对象中。ServletFileUpload sfu = new ServletFileUpload(difactory);

//解析保存在request中的数据并返回list集合List list = null;

try {

list = sfu.parseRequest(request);

} catch (FileUploadException e) {

e.printStackTrace();

}

//遍历list集合,取出每一个输入项的FileItem对象,并分别获取数据for (Iterator it = list.iterator(); it.hasNext();) {

FileItem fi = (FileItem) it.next();

if (fi.isFormField()) {

System.out.println(fi.getFieldName());

System.out.println(fi.getString());

} else {

//由于客户端向服务器发送的文件是客户端的全路径,在这我们只需要文件名即可String filename = fi.getName();

int index = filename.lastIndexOf("\\");

if(index != -1)

filename = filename.substring(index+1);

//向服务器写出文件InputStream in = fi.getInputStream();

FileOutputStream fos = new FileOutputStream(fudir + "/" +filename);

byte[] buf = new byte[1024];

int len = -1;

while((len = in.read(buf)) != -1){

fos.write(buf, 0, len);

}

//关闭流if(in != null){

try{

in.close();

}finally{

if(fos!=null)

fos.close();

}

}

}

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}上面的代码只是功能的练习,实际开发中的文件上传需要考虑诸多因素,我们接下来继续学习。#JS动态添加文件上传框和按钮的JavaScript代码:function add(){

var file = document.create_rElement_x("input");

file.type = "file";

file.name = "file";

var butt = document.create_rElement_x("input");

butt.type = "button";

butt.value = "删除";

butt.onclick = function rem(){

//必须使用按钮的父节点DIV的父节点来删除自己和自己的父节点DIV。this.parentNode.parentNode.removeChild(this.parentNode);

};

var div = document.create_rElement_x("div");

div.a(file);

div.a(butt);

var parent = document.getElementByIdx_x_x("files");

parent.a(div);

}#上传文件的处理细节(1):1.中文文件乱码的问题,可以调用两个方法来设置字符编码:servletUpLoader.setHeaderEncoding()或request.setCharacterEncoding()。我们可以在源文件的创建ServletFileUpload对象后边添加如下代码:sfu.setHeaderEncoding("UTF-8");

2.临时文件的删除,如果临时文件大于setSizeThreshold设置的缓存大小,Commons-fileupload组件将使用 setRepository设置的临时目录来保存上传的文件,上传完成后我们需要手动调用FileItem.delete来删除临时文件。建议不要修改缓 存区大小,如果设置缓存为1MB,1000个用户上传文件就需要1000MB内存,服务器会受不了的。我们删除掉setSizeThreshold的代 码,并在每次完成一个文件后添加下而的代码://删除临时目录中的文件fi.delete();#上传文件的处理细节(2):1.在上面的代码中,我们将文件的实际保存目录设置在WEB-INF目录之外。这样外部可以直接访问被上传的文件,这会造成安全问题。比如用户上传了一个带有 恶意脚本功能的JSP文件,然后从外部访问执行了JSP文件…后果不堪设想。所以我们将源代码中对应位置处修改如下://之所以放在"WEB-INF"目录下是为了防止上传的文件被直接被访问的安全问题String userdir = dir + "WEB-INF/files";

2.一个WEB应用会许多不同的用户访问,不同的用户可能会上传相同名称的文件,如果这样可能会造成文件覆盖的情况发生,所以我们必须保证文件名称的唯一性,我编写一个方法来生成唯一性名称的文件名:private String uuidName(String fileName){

UUID uuid = UUID.randomUUID();

return uuid.toString() + "_" + fileName;

}我们将代码“filename = filename.substring(index + 1);”修改为:filename = uuidName(filename.substring(index + 1))

3.如果一个目录下的文件过多,会极大减慢文件的访问速度。比如一个目录下的文件如果超过1000个,达到1万个呢?恐怖!我们必须编写一个目录结构生成算法,来分散存上传的文件。我们一个方法:private String hashPath(String dir, String fileName) {

int hashCode = fileName.hashCode();

int dir1 = (hashCode >> 4)& 0xf;

int dir2 = hashCode & 0xf;

String newpath = dir + "/" + dir1 + "/" + dir2 + "/";

File file = new File(newpath);

if(!file.exists()){

file.mkdirs();

}

return newpath + uuidName(fileName);

}上传文件的处理细节(3)

1.使用ProgressListener显示上传文件进度,在创建ServletFileUpload之后添加如下代码://设置文件上传进度监听器sfu.setProgressListener(new ProgressListener() {

public void update(long pBytesRead, long pContentLength, int pItems) {

System.out.println("已上传:" + pBytesRead + "总大小:"

+ pContentLength);

}

});

2.上面的代码会造成频繁的打印,为了使它在上传一定数量后再打印,比如上传10KB后再打印,我们修改上面的代码如下://设置文件上传进度监听器sfu.setProgressListener(new ProgressListener() {

long temp = -1;

public void update(long pBytesRead, long pContentLength, int pItems) {

long size = pBytesRead / 1024 * 1024 * 10;

if(temp == size)

return;

temp = size;

if(pBytesRead != -1)

System.out.println("已上传:" + pBytesRead + "总大小:"

+ pContentLength);

else

System.out.println("上传完成!");

}

});上面的代码比较经典,好好回味一下。#文件下载:WEB应用中实现文件下载的两种方式:1.超链接直接指向下载资源2.程序实现下载需设置两个响应头:(1).设置Content-Type的值为:application/x-msdownload。Web服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或HTML文件,而是一个要保存到本地的下载文件。(2). Web服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置 Content-Disposition报头。该报头指定了接收程序处理数据内容的方式,在 HTTP应用中只有 attachment是标准方式,attachment表示要求用户干预。在 attachment后面还可以指定 filename参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。在设置Content-Dispostion之前一定要指定 Content-Type。为实现文件下载,首先我们遍历目录下所有文件,Servlet:import java.io.File;

import java.io.IOException;

import java.util.HashMap;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class ListFileServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//获取目录String dir = this.getServletContext().getRealPath("/WEB-INF/files");

HashMap map = new HashMap();

listFile(new File(dir), map);

//将文件列表设置到request的属性中,然后由JSP页面打印列表。request.setAttribute("filemap", map);

request.getRequestDispatcher("/list.jsp").forward(request, response);

}

private void listFile(File f, HashMap map) {

if (f.isFile()) {

String path = f.getAbsolutePath().substring(

this.getServletContext().getRealPath("/").length());

String name = f.getName();

name = name.substring(name.indexOf("_")+1);

//BASE64Encoder encoder = new BASE64Encoder();

map.put(path, name);

} else {

File[] files = f.listFiles();

for (int i = 0; i < files.length; i++) {

listFile(files[i], map);

}

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

java图片上传下载_java web 文件上传与下载相关推荐

  1. java web 上传附件_JAVA WEB文件上传步骤

    JAVA WEB文件上传步骤如下: 实现 Web 开发中的文件上传功能,两个操作:在 Web 页面添加上传输入项,在 Servlet 中读取上传文件的数据并保存在本地硬盘中. 1.Web 端上传文件. ...

  2. java图片上传下载_Java中文件上传下载 --使用Minio

    Minio模板类: @RequiredArgsConstructor public class MinioTemplate implements InitializingBean { private ...

  3. java 上传断点续传_JAVA大文件上传断点续传解决方案

    javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 Save 改进后的代码不需要for ...

  4. java 看书浏览器官_JAVA读取文件流,设置浏览器下载或直接预览操作

    最近项目需要在浏览器中通过url预览图片.但发现浏览器始终默认下载,而不是预览.研究了一下,发现了问题: // 设置response的header,注意这句,如果开启,默认浏览器会进行下载操作,如果注 ...

  5. java 多重压缩下载_Java 多文件边压缩边下载

    有时我们希望在后台实时生成文件并下载到客户端 @GetMapping(value = "download") public void download(HttpServletRes ...

  6. WEB文件上传之JQuery ajaxfileupload插件使用(二)

    1.JQuery ajaxfileupload插件使用准备 下载地址: http://www.phpletter.com/DOWNLOAD/ 2.原理分析 ajaxfileupload也是利用ifra ...

  7. Java Web 文件上传下载

    文章目录 1文件上传概述 1.1文件上传的作用 1.2文件上传对页面的要求 1.3 比对文件上传表单和普通文本表单的区别 1.4 对普通文本表单的测试 1.5 文件上传对Servlet的要求 2 co ...

  8. java web 文件上传_Javaweb学习笔记10—文件上传与下载

    今天来讲javaweb的第10阶段学习.文件的上传与下载,今天主要说的是这个功能的实现,不用说了,听名字就是外行人也知道肯定很重要啦. 老规矩,首先先用一张思维导图来展现今天的博客内容. ps:我的思 ...

  9. java web 文件上传和下载

     在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直 ...

最新文章

  1. python语言入门编程猫-编程猫推出海龟编程器,打造Python教育产品矩阵
  2. 服务器拉取openssl文件,使用openssl从服务器获取证书
  3. Spring框架IOC和AOP的实现原理
  4. 使用 generator-easy-ui5 快速创建 SAP UI5 应用的工程结构
  5. [机器学习笔记]Note7--神经网络:学习
  6. 编写一个猜数字游戏程序:
  7. 服务器操作系统类型怎么查,服务器查看操作系统类型
  8. 2.4 在不同的划分上进行训练并测试
  9. 刷新率调高,或高于60Hz闪屏,忽明忽暗,晃动问题
  10. IOS UI TabBar标签栏的使用
  11. java实现模拟多道程序设计
  12. AHCI、RAID、IDE三种硬盘模式优缺点对比
  13. 深入java8的集合1:ArrayList的实现原理
  14. 学习C语言的心路历程
  15. 泊松分布 Poisson Distribution
  16. 微信小程序(一)天气预报
  17. 【特征工程】定性数据的编码
  18. ctf解密图片得到flag_CTF从入门到进(fang)阶(qi)之MISC
  19. 【20220207】【信号处理】希尔伯特变换定义及解调原理
  20. 用 SQL 做数据分析的十大常用功能,附面试原题解答!!

热门文章

  1. 专栏 | 基于 Jupyter 的特征工程手册:特征选择(一)
  2. appid 参数错误_辽宁罗茨风机参数
  3. 怎么把网页源码家入hexo博客_一款被大厂选用的 Hexo 博客主题
  4. VTK修炼之道71:交互与Widget_观察者/命令模式
  5. VTK修炼之道42:频域处理_高通滤波(理想+巴特沃兹)
  6. bash--shell高级编程-变量的替换
  7. Spring AOP进行日志记录,管理
  8. mybatisPlus分页限制500条数据
  9. Leetcode-移除链表元素
  10. Java学习开发入门基础教程系列