1.上传(不能使用BaseServlet):
  上传的作用,略
  上传的要求(对表单和Servlet都有要求):
    1.必须使用表单,而不能是超链接,method="post" 文件明显不能get把参数带在后面
    2.必须使用多部件表单数据 enctype="multipart/form-data"
    3.表单中必须添加文件表单项 input type="file" name="xxx"

    4.凡是带文件的表单的所有(所有!)数据都不能用getParameter()方法获取,带了enctype
      就无法使用此方法,而是使用getInputStream() 返回整个请求体

  多部件表单的体:
    1.一个表单项一个部件
    2.一个部件中包含请求头、空行、请求体
    3.普通表单项:一个头 Content-Disposition name=“xxx” 即表单项的名字,体就是表单项的值
      文件表单项:包含两个头:Content-Disposition name=“xxx”,表单项名称,和一个filename="xxx"即文件名称
      Content-Type:上传文件的MIME类型

  commons-fileupload.jar包登场,他有一个io的依赖包
  它可以帮我们解析request中的数据,一个表单数据封装到一个items对象中,调用fileItems的方法即可
    上传三步:
    1.工厂 DiskFileItemFactory
    2.解析器 ServletFileUpload
    3.表单项 FileItem

  创建工厂 有构造器
  创建解析器 给一个工厂,就可以new
  得到表单项 使用解析器得到集合数据
  给一个request List<FileItem> FileItemList = sfu.parseRequest(request);

给出一个小例子:

  JSP页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'form1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<form action="<c:url value='/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>

Servlet页面:

package cn.itacast.servlet;

import java.io.File;
import java.io.IOException;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UploadServlet2 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//上传三步,步骤见笔记
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(factory);
sfu.setFileSizeMax(100*1024);
try{
List<FileItem> FileItemList = sfu.parseRequest(request);
FileItem f1 = FileItemList.get(0);
FileItem f2 = FileItemList.get(1); System.out.println("普通表单项:"+f1.getFieldName()+"="+f1.getString("UTF-8"));
System.out.println("文件表单项:");
System.out.println("文件类型:"+f2.getContentType());
File file = new File("F:/2.jpg");
f2.write(file);
}catch(Exception e){
e.printStackTrace();
} }
}

  上传的细节:
    1.文件必须保存到WEB-INF下(当然C.D.E盘都可以,但强烈不建议),目的是为了不让浏览器直接访问

    2.文件名称相关:有的是绝对路径,需要进行切割(切割文件名过来),
    部分浏览器(IE6,遨游之类)这样

    Sting filename = f2.getName();
    int index = filename.lastIndexOf("\\");
    if(index != -1){
    String filename1 = filename.subString(index+1);
    }

    3.乱码问题:文件的名称乱码等都交给FileUpload来处理,使用时告诉它编码,request.setCharaterEncoding("UTF-8");
    fileUpload会自动调用处理
    当然,解析器也提供了一个方法
    ServletFileUpload.setHeaderEncoding();内部的方法,优先级高

    4.处理重名问题,为每个文件名称添加前缀(UUID),处理重名问题
    filename = CommonUtils.uuid()+"_"+filename;使用客户的文件名称再加我们的不重复前缀

    5.目录打散问题:不能在一个文件夹下存放过多文件
    首字母打散:如文件名称叫abc.txt 则保存到B目录下,不存在则创建
    局限也明显,中文等的太多复杂
    时间打散:使用当前日期作为目录,一天一个文件夹
    局限性:有时候周末目录爆满,工作日空空如也
    哈希打散(推荐):任何对象都有一个hashCode()方法,得到一个INT值
    得到哈希值
    把Int值转换成十六进制
    获取十六进制的前两位用来生成目录
    目录为两层,例如文件名 1A2B3C 生成目录 1/A/文件名
    最多可以生成INT的范围,4字节32位,8位十六进制
    最多42亿
    局限性体现在人工不知道在哪,找起来麻烦,但计算机很清楚

    切割文件名->加UUID->得到文件名的哈希值->Integer.toHexString()
    ->使用String.cahrAt()拿出构建目录的目录名+root文件路径("/WEB-INF/files/") mkdirs
    6.上传文件大小限制:单个文件大小限制
    整个请求大小限制

     解析器有相关的方法:sfu.setFilesizeMax(100*1024);100KB
    必须放在解析之前
    如果超出限制,在解析时会抛出异常

    限制整个表单请求大小 sfu.setSizeMax();也是解析前执行
    7.缓存大小与临时目录
    1.缓存大小:超出多大才向硬盘保存,默认10KB
    2.向硬盘的什么目录保存
    DiskFileItemFactory(int sizeThreshold, File repository)
    使用此构造器,可以指定缓存与临时目录

2.下载:下载就是客户端响应字节数据
  下载的要求:
    两个头一个流
    Content-Type (什么类型)
    Content-Dispositon (默认值是inline,浏览器能打开他就打开,图片,文字等)
    要弹下载框需要设置为 accathment;filename=xxx
    流就是要下载的文件数据

  下载的细节:
    显示在下载框的中文名称会出现乱码
    大部分主流浏览器都使用URL编码
    通用解决方案:frameName = new String(filename.getBytes(""),"");
    一个小工具类(此处略) filenameEncoding方法

  详细步骤:

文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载

文件下载功能的实现思路:

  1.获取要下载的文件的绝对路径

  2.获取要下载的文件名

  3.设置content-disposition响应头控制浏览器以下载的形式打开文件

  4.获取要下载的文件输入流

  5.创建数据缓冲区

  6.通过response对象获取OutputStream流

  7.将FileInputStream流写入到buffer缓冲区

  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

  借用苍狼大神的示例:

package gacl.response.study;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author gacl
* 文件下载
*/
public class ResponseDemo02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
downloadFileByOutputStream(response);//下载文件,通过OutputStream流
} /**
* 下载文件,通过OutputStream流
* @param response
* @throws FileNotFoundException
* @throws IOException
*/
private void downloadFileByOutputStream(HttpServletResponse response)
throws FileNotFoundException, IOException {
//1.获取要下载的文件的绝对路径
String realPath = this.getServletContext().getRealPath("/download/1.JPG");
//2.获取要下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.获取要下载的文件输入流
InputStream in = new FileInputStream(realPath);
int len = 0;
//5.创建数据缓冲区
byte[] buffer = new byte[1024];
//6.通过response对象获取OutputStream流
OutputStream out = response.getOutputStream();
//7.将FileInputStream流写入到buffer缓冲区
while ((len = in.read(buffer)) > 0) {
//8.使用OutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer,0,len);
}
in.close();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

JavaWeb基础—上传与下载的更多相关文章

  1. JavaWeb——文件上传和下载

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

  2. 【Java】JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  3. JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  4. javaWeb文件上传与下载

    文件上传与下载在项目中运用的使用频率很大 今天也花时间整理了一下 多文件上传图片回显 和文件下载  1.多文件上传 这里会涉及到几个属性 fileSizeThreshold:缓冲区文件的大小 如果上传 ...

  5. javaweb基础整理随笔-----上传与下载步骤详解

    这次整理的是上传与下载的原生代码解析: 上传:1.对页面的要求:enctype="multipart/form-data" method="post"      ...

  6. (转载)JavaWeb学习总结(五十)——文件上传和下载

    源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...

  7. JavaWeb学习总结,文件上传和下载

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

  8. JavaWeb学习总结(五十)——文件上传和下载

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

  9. JavaWeb学习 (二十八)————文件上传和下载

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

随机推荐

  1. BASE_DIR 拼接文件路径

    # C:/Disk_D/pycharm_stu/macboy/blog/views/tt.py 当前文件绝对路径 BASE_DIR = os.path.dirname(os.path.dirname( ...

  2. Mybatis显示SQL语句

    众所周知,hibernate可以通过配置show_sql在控制台显示sql语句,Mybatis可不可以呢?当然是可以的,将ibatis log4j运行级别调到DEBUG可以在控制台打印出ibatis运 ...

  3. java笔记--线程的插队行为

    对线程的插队行为的理解 在编写多线程时,会遇到让一个线程优先于其他线程运行的情况, 此时除了可以设置其优先级高于其他线程外,更直接的方式是使用Thread类的join()方法 --如果朋友您想转载本文 ...

  4. Jboss Jmx-Console和 Jboss web-console安全设置

    1.介绍 如果你暴露你的JBoss服务器通过网络(如通过启动服务器使用选项B 0.0.0.0或者通过改变jboss.bind.address首次出现0.0.0.0在.../jboss/server/d ...

  5. TreeView控件概述、属性与方法

    1.作用:用于显示Node结点的分层列表.2.添加到控件箱菜单命令:工程 | 部件,在部件对话框中选择:Microsoft Windows Common Controls 6.03.TreeView控 ...

  6. [翻译] ios-image-filters

    ios-image-filters https://github.com/esilverberg/ios-image-filters photoshop-style filter interface ...

  7. linux rz上传文件及出错解决方案

    在把Windows上的文件传至Linux端时用到SecureCRT,一般小文件都没有问题,文件太大时则出现了上传后的文件只有几K大小,当然大于2个G的是不可能传的上去的了.对于几百M到1G多的大文件要 ...

  8. 《CDN 之我见》原理篇——CDN的由来与调度

    CDN是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术.它能够有效解决网络带宽小.用户访问量大.网点分布不均等问题. 为了让大家更全面的了解 ...

  9. 铁乐学python_day21_面向对象编程3

    抽象类和接口类 以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某 ...

  10. 微信公众平台OAuth2.0授权

    1. 配置授权回调页面域名 进入微信公众平台后台后,依次进入开发者中心-权限表,找到网页授权获取用户基本信息,点击右侧的修改. 授权回调域名配置规范为全域名并且不带http,比如需要网页授权的域名为: ...