【JavaWeb】文件上传下载(213-221)
文件上传
213.文件上传-文件上传的介绍
1、要有一个 form 标签,method=post 请求
2、form 标签的 encType 属性值必须为 multipart/form-data 值
3、在 form 标签中使用 input type=file 添加上传的文件
4、编写服务器代码(Servlet 程序)接收,处理上传的数据
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><form action="http://192.168.31.74:8080/09_EL_JSTL/uploadServlet" method="post" enctype="multipart/form-data">用户名:<input type="text" name="username" /> <br>头像:<input type="file" name="photo" > <br><input type="submit" value="上传"></form>
</body>
</html>
214.文件上传-上传的http协议内容介绍
215.文件上传-上传用到的类和方法介绍
commons-fileupload.jar 需要依赖 commons-io.jar 这个包,所以两个包我们都要引入。
需要导入两个 jar 包:
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
API | 作用 |
---|---|
ServletFileUpload 类 | 用于解析上传的数据 |
FileItem 类 | 表示每一个表单项 |
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request); | 判断当前上传的数据格式是否是多段的格式。 |
public List<> parseRequest(HttpServletRequest request) | 解析上传的数据 |
boolean FileItem.isFormField() | 判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。true 表示普通类型的表单项,false 表示上传的文件类型 |
String FileItem.getFieldName() | 获取表单项的 name 属性值 |
String FileItem.getString() | 获取当前表单项的值 |
String FileItem.getName(); | 获取上传的文件名 |
void FileItem.write( file ); | 将上传的文件写到 参数 file 所指向抽硬盘位置 。 |
216.文件上传-使用fileupload解析上传的数据
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;public class UploadServlet extends HttpServlet {/*** 用来处理上传的数据* @param req* @param resp* @throws ServletException* @throws IOException*/@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1 先判断上传的数据是否多段数据(只有是多段的数据,才是文件上传的)if (ServletFileUpload.isMultipartContent(req)) {// 创建FileItemFactory工厂实现类FileItemFactory fileItemFactory = new DiskFileItemFactory();// 创建用于解析上传数据的工具类ServletFileUpload类ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);try {// 解析上传的数据,得到每一个表单项FileItemList<FileItem> list = servletFileUpload.parseRequest(req);// 循环判断,每一个表单项,是普通类型,还是上传的文件for (FileItem fileItem : list) {if (fileItem.isFormField()) {// 普通表单项System.out.println("表单项的name属性值:" + fileItem.getFieldName());// 参数UTF-8.解决乱码问题System.out.println("表单项的value属性值:" + fileItem.getString("UTF-8"));} else {// 上传的文件System.out.println("表单项的name属性值:" + fileItem.getFieldName());System.out.println("上传的文件名:" + fileItem.getName());fileItem.write(new File("e:\\" + fileItem.getName()));}}} catch (Exception e) {e.printStackTrace();}}}
}
文件下载
217.文件下载-文件下载的实现
response.setHeader(“Content-Disposition”, “attachment; fileName=1.jpg”);
这个响应头告诉浏览器。这是需要下载的。而 attachment 表示附件,也就是下载的一个文件。fileName=后面, 表示下载的文件名。
完成上面的两个步骤,下载文件是没问题了。但是如果我们要下载的文件是中文名的话。你会发现,下载无法正确显示出正确的中文名。
原因是在响应头中,不能包含有中文字符,只能包含 ASCII 码。
package com.atguigu.servlet;import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;public class Download extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1、获取要下载的文件名String downloadFileName = "2.jpg";
// 2、读取要下载的文件内容 (通过ServletContext对象可以读取)ServletContext servletContext = getServletContext();// 获取要下载的文件类型String mimeType = servletContext.getMimeType("/file/" + downloadFileName);System.out.println("下载的文件类型:" + mimeType);
// 4、在回传前,通过响应头告诉客户端返回的数据类型resp.setContentType(mimeType);
// 5、还要告诉客户端收到的数据是用于下载使用(还是使用响应头)// Content-Disposition响应头,表示收到的数据怎么处理// attachment表示附件,表示下载使用// filename= 表示指定下载的文件名// url编码是把汉字转换成为%xx%xx的格式if (req.getHeader("User-Agent").contains("Firefox")) {// 如果是火狐浏览器使用Base64编码resp.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" + new BASE64Encoder().encode("中国.jpg".getBytes("UTF-8")) + "?=");} else {// 如果不是火狐,是IE或谷歌,使用URL编码操作resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("中国.jpg", "UTF-8"));}/*** /斜杠被服务器解析表示地址为http://ip:prot/工程名/ 映射 到代码的Web目录*/InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);// 获取响应的输出流OutputStream outputStream = resp.getOutputStream();// 3、把下载的文件内容回传给客户端// 读取输入流中全部的数据,复制给输出流,输出给客户端IOUtils.copy(resourceAsStream, outputStream);}
}
218.文件下载-使用URLEncodeer解决谷歌和IE浏览器中午下载名乱码问题
如果客户端浏览器是 IE 浏览器 或者 是谷歌浏览器。我们需要使用URLEncoder 类先对中文名进行 UTF-8 的编码操作。
因为 IE 浏览器和谷歌浏览器收到含有编码后的字符串后会以 UTF-8 字符集进行解码显示。
// 把中文名进行 UTF-8 编码操作。
String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
// 然后把编码后的字符串设置到响应头中
response.setHeader("Content-Disposition", str);
219.文件下载-Base64编解码操作
如果客户端浏览器是火狐浏览器。 那么我们需要对中文名进行 BASE64 的编码操作。
这时候需要把请求头 Content-Disposition: attachment; filename=中文名
编码成为:Content-Disposition: attachment; filename==?charset?B?xxxxx?=
=?charset?B?xxxxx?= 现在我们对这段内容进行一下说明。
=?
charset B
xxxx
?=
220.文件下载-使用Base64编解码解决火狐浏览器附件中文乱码问题
因为火狐使用的是 BASE64 的编解码方式还原响应中的汉字。所以需要使用 BASE64Encoder 类进行编码操作。
// 使用下面的格式进行 BASE64 编码后
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
// 设置到响应头中
response.setHeader("Content-Disposition", str);
221.文件下载-使用User-Agent请求头判断,动态切换不同的方案解决所有浏览器附件中文乱码问题
那么我们如何解决上面两种不同编解码方式呢。我们只需要通过判断请求头中 User-Agent 这个请求头携带过来的浏览器信息即可判断出是什么浏览器。
String ua = request.getHeader("User-Agent");
// 判断是否是火狐浏览器
if (ua.contains("Firefox")) {// 使用下面的格式进行 BASE64 编码后String str = "attachment; fileName=" + "=?utf-8?B?"+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";// 设置到响应头中response.setHeader("Content-Disposition", str);
} else {// 把中文名进行 UTF-8 编码操作。String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");// 然后把编码后的字符串设置到响应头中response.setHeader("Content-Disposition", str);
}
【JavaWeb】文件上传下载(213-221)相关推荐
- javaweb文件上传下载
文件上传概述 1 文件上传的作用 例如网络硬盘!就是用来上传下载文件的. 在智联招聘上填写一个完整的简历还需要上传照片呢. 2 文件上传对页面的要求 上传文件的要求比较多,需要记一下: 必须使用表单, ...
- JavaWeb实现文件上传下载功能实例解析
转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...
- Java实现FTP批量大文件上传下载
用Java实现FTP批量大文件上传下载 <iframe id="I0_1416224567509" style="margin: 0px; padding: 0px ...
- JSON+AJAX+ThreadLocal+文件上传下载
文章目录 JSON和AJAX文档介绍 1. JSON介绍 1.1 JSON快速入门 1.2 JSON和字符串转换 1.2.1 JSON转字符串 1.2.2 字符串转JSON 1.2.3 JSON和字符 ...
- 文件上传下载和Excel读写全家桶
一.javaweb实现 upload package com.atqh.Servlet.FileServlet;import com.atqh.utils.ExcelUtil; import org. ...
- linux 安装上传文件,linux常用命令(二)文件上传下载及软件安装
1.上传下载工具安装 (1)WINDOWS 到linux的文件上传及下载: windows下打开secureCRT,通过SSH连到⾄至远程linux主机: 上传下载工具安装命令:yum -y inst ...
- 教你如何实现c#文件上传下载功能
简单介绍一下c#文件上传下载功能实现. NuGet 安装SqlSugar Model文件下新建 DbContext 类 public class DbContext {public DbContext ...
- [C# 网络编程系列]专题十一:实现一个基于FTP协议的程序——文件上传下载器...
引言: 在这个专题将为大家揭开下FTP这个协议的面纱,其实学习知识和生活中的例子都是很相通的,就拿这个专题来说,要了解FTP协议然后根据FTP协议实现一个文件下载器,就和和追MM是差不多的过程的,相信 ...
- SpringMVC整合fastdfs-client-java实现web文件上传下载
为什么80%的码农都做不了架构师?>>> 版权声明:本文为博主原创文章,转载请标明出处(http://blog.csdn.net/wlwlwlwl015)Thanks. 目录( ...
- 文件上传 java web_JavaWeb 文件上传下载
1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...
最新文章
- 【ACM】UVA - 340 Master-Mind Hints(一定要好好学英语...)
- idea修改java和jsp不起作用_使用IDEA编写jsp时EL表达式不起作用的问题及解决方法...
- 解决错误:No module named ‘Cryptodome‘ 和错误rosbag.bag.ROSBagException: unsupported compression type: lz4
- Oracle JDBC版本区别(转)
- php web server部署(PHP+Nginx+Redis+MySQL)
- 成功解决ValueError: ‘usecols‘ must either be list-like of all strings, all unicode, all integers or a ca
- 如果我要...(??版)
- Android SqliteManager 源码
- Arduino 代码机制
- C++|Java混合实验-java搭建get方法靶场,Qt发送请求获取数据
- jquery eaayui 学习(四)datagrid
- 算法提高 质因数2(java)
- 【整理】system\app中的APK一览
- 求出字符串中大写字母,小写字母和数字的个数
- 关于Linux中网络连接配置(NetworkManager)的一些笔记
- eq linux_Pr音频效果参考:滤波器与EQ
- C++学习(一八一)android的NDK、SDK版本的对应关系
- vue图片裁剪功能的实现
- 使用TextMeshPro实现打字机效果
- 魔兽世界 圣骑士唯一的远程武器任务