下载功能
  TEZNKK3IfmPf 2023年11月12日 26 0

需求:把服务器当中的文件直接下载到电脑当中

  • 直接使用​​a​​ 标签来去下载
  • 有些内容浏览器会自动解析
  • 浏览器不能解析的文件才会被下载
  • ​.jpg​​​、​​png​​​、​​zip​​​、​​mp4​​​、​​rar​​,等等不同的文件格式自己按照如下的方式去试试就知道效果了

下载功能

  • 通过发送​​Servlet​​ 请求来去下载
  • 通过发送一个​​Servlet​​ 请求,把文件名发送给服务器
  • 发送给服务器后,服务器接收到文件名参数,获取文件的绝对地址
  • 通过流的形式来去写到浏览器
  • 还得要告诉浏览器文件是什么类型
  • 浏览器是以​​MIME​​ 的类型来去识别的
this.getServletContext().getMimeType("BNTang");
response.setContentType("MIME");

下载功能

  • 设置响应头,告诉浏览器不要去解析,是以附件的形式打开
response.setHeader("Content-Dsiposition", "attachment;filename=" + filename);

下载功能

  • 最终步骤最终代码如下:
  1. 接收文件名参数
  2. 获取 mime 类型
  3. 设置响应类型,告诉浏览器是以什么类型响应的
  4. 告诉浏览器是以附件的形式下载
  5. 获取文件的绝对路径
  6. 读取文件流
  7. 获取输出流
  8. 把内容写出到输出流

下载功能

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getParameter("filename");

String mime = this.getServletContext().getMimeType(filename);

response.setContentType(mime);

response.setHeader("Content-Disposition", "attachment;filename=" + filename);

String path = this.getServletContext().getRealPath("download/" + filename);

System.out.println(path);

FileInputStream in = new FileInputStream(path);

ServletOutputStream out = response.getOutputStream();

byte[] buffer = new byte[1024];

int len = 0;

while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}

in.close();
out.close();
}

下载功能

下载功能

解决中文文件名称乱码的问题

  • 获取中文参数报错的问题
  • 高版本​​tomcat​​​ 中的新特性:就是严格按照​​RFC 3986​​ 规范进行访问解析
  • 而​​RFC 3986​​​ 规范定义了​​url​​​ 中只允许包含英文字母(a-zA-Z)数字(0-9)​​-_.~​​ 4个特殊字符
  • 以及所有保留字符(RFC3986 中指定了以下字符为保留字符 →​​! * ’ ( ) ; : @ & = + $ , / ? # [ ]​​)

 

 

  • ​.../conf/catalina.properties​​ 中,找到最后注释掉的一行
# tomcat.util.http.parser.HttpParser.requestTargetAllow=|

下载功能

  • 改成​​tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}​​,表示把{}放行

下载功能

  • 把获取的字符串参数的字节码获取,再重新使用​​utf-8​​ 编码
  • 在设置以附件形式打开时,不同的浏览器会对默认的名字进行解码
  • 所以根据不同的浏览器,要对名称进行编码之后,再放入文件名
  • 对文件名进行编码,不同的浏览器编码方式不一样,要先获取​​agent​​,取出浏览器的类型
  • 根据不同的浏览器类型设置对应的编码方式
  • 步骤如下:
  1. 接收文件名称
  2. 获取​​mimeType​
  3. 设置浏览器响应类型
  4. 先对传入的参数转成二进制流,再使用​​UTF-8​​ 进行编码
  5. 获取浏览器的信息
  6. 判断是哪一种浏览器,根据不同的浏览器获取一个编码的文件名
  7. 设置以附件的形式下载,传的名称是编码过的名称
  8. 获取文件的绝对路径
  9. 读取文件流
  10. 获取输出流
  11. 把文件写到响应当中

 

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getParameter("filename");
String mime = this.getServletContext().getMimeType(filename);
response.setContentType(mime);

filename = new String(filename.getBytes("ISO8859-1"), "UTF-8");

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

if (agent.contains("MSIE")) {
// IE编码
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐编码
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 浏览器编码
filenameEncoder = URLEncoder.encode(filename, "utf-8");
}
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
String path = this.getServletContext().getRealPath("download/" + filename);
FileInputStream in = new FileInputStream(path);

ServletOutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];

int len = 0;

while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}

in.close();
out.close();
}
  • 测试方式同上
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2023年11月14日   64   0   0 xmlJavaEE
  TEZNKK3IfmPf   2023年11月13日   52   0   0 java浏览器Web
  TEZNKK3IfmPf   2024年03月29日   108   0   0 浏览器
  TEZNKK3IfmPf   2023年11月14日   25   0   0 浏览器
TEZNKK3IfmPf