文件上传和下载
发布日期:2021-08-21 02:35:14 浏览次数:4 分类:技术文章

本文共 9940 字,大约阅读时间需要 33 分钟。

文件上传概述1、上传对表单限制    *method="post"    *enctype="multipart/form-data"    *表单中需要添加文件表单项:2、上传对Servlet限制    *request.getParameter("xxx");这个方法在表单为enctype="multipart/form-data"时,它作废了。它永远都返回null。    *ServletInputStream request.getInputStream();返回整个请求的体    --------------------------------------多部件表单的体1、每隔出多个部件,即一个表单项一个部件2、一个部件中自己包含请求头和空行,以及请求体3、普通表单项    >一个头:Content-Disposition: 包含name="xxx",即表单项名称。    >体就是表单项的值4、文件表单项:    >两个头:        *Content-Disposition:包含name="xxx",即表单项名称;还有一个filename,表示上传文件的名称        *Content-Type:它是上传文件的MIME类型,例如:image/pjepg,表示上传的是图片。图片中jpg拓展名的图片    >体就是上传文件的内容。    ================================commons-fileupload    *commins-fileupload.jar    *commons-io.jar    这个小组件,它会帮我们解析request中的上传数据,解析后的结果是一个表单项数据封装到一个FileItem对象中。我们只需要调用FIleItem的方法即可!---------------------------1、上传三步    相关类:     *工厂:DiskFileItemFactory     *解析器:ServletFileUpload     *表单项:FileItem          1)。创建工厂:DiskFileItemFactory factory=new DiskFileItemFactory();     2)。创建解析器:ServletFileUpload sfu=new ServletFileUpload(factory);     3)。使用解析器来解析request,得到FileItem集合:List
files=suf.parseRequest(request); 2.FileItem *boolean isFormField(): 是否为普通表单选项,返回true为是,否则为文件表单项 *String getFieldName(): 返回当前表单项的名称 *String getString(String charset):返回表单项的值,不适用于文件表单项 *String getName():返回上传的文件名称 *long getSize():返回上传文件的字节数 *InputStream getInputStream():返回上传文件对应的输入流 *void write(File file):把上传的文件内容保存到指定的文件中 *String getContentType():获取文件类型 ----------------------------------上传的细节:1.文件必须保存在WEB-INF下 *目的是不让浏览器直接访问到! *把文件保存到WEB-INF目录下!2.文件名称问题 *有的浏览器上传的文件名是绝对路径,这需要切割! c:\files\baibing.jpg String filename=fi2.getName(); index=filename.lastIndexOf("\\"); if(index!=-1){ filename=filename.substring(index+1); } *文件名乱码或者普通表单项乱码:request.setCharacterEncoding("utf-8");因为fileupload内部会调用request.getCharacterEncoding(); >request.setCharacterEncoding("utf-8"); 优先级低 >ServletfileUpload.setHeaderEncoding("utf-8"); *文件同名问题:我们需要为每个文件添加名称前缀,这个前缀应该保证不能重复 >filename=CommonUtils.uuid()+"_"+filename3.目录打散 *不能再一个目录下存放过多文件。影响速度 >首字母打散:使用文件的首字母作为目录名称。例如abc.txt,我们保存在a目录下,如果a目录不存在,则自动创建并且保存在里面 >时间打散:使用当前日期做为目录。 >哈希打散: *通过文件名称得到int值,即调用hashCode() *把int值转换为16进制0~9,A~F *获取16进制的前两位用来生成目录,目录为两层!4.上传文件的大小限制 *单个文件大小限制 >sfu.setFileSizeMax(100*1024);:限制单个文件大小为100k >上面的方法调用,必须在解析器进行解析之前 >如果大小超出限制,解析器在parseRequest抛出异常FileUploadBase.FileSizeLimitExceededException *整个请求所有数据大小限制 >sfu.setSize(1024*1024);限制整个表单大小为1M >这个方法也必须在解析器开始解析之前调用 >如果超出限制,解析器在parseRequest抛出异常FileUploadBase.SizeLimitExceededException5.缓存大小与临时目录 *上传文件的步骤一般是先保存在内存再保存到硬盘上。但是内存大小会限制,所以先保存在硬盘上,然后你写入硬盘保存位置的时候从临时文件复制,然后删除临时文件 *缓存大小:超出多大才向硬盘保存!默认为10kb *临时目录:向硬盘的什么目录保存 设置缓存大小与临时目录:new DiskFileItemFactory(20*1024,new File("E:\\f\\temp")
package cn.itcast.web.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.FileUploadBase;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import cn.itcast.utils.CommonUtils;public class Upload3Servlet 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();        DiskFileItemFactory factory=new DiskFileItemFactory(20*1024, new File("E:\\f\\temp"));                ServletFileUpload upload=new ServletFileUpload(factory);        //        upload.setFileSizeMax(100*1024);//限制单个文件大小为100k//        upload.setSizeMax(1024*1024);//限制整个表单大小为1M//        System.out.println(1);        try {            List
list=upload.parseRequest(request); FileItem fi=list.get(1); String root=this.getServletContext().getRealPath("/WEB-INF/files"); /* * 生成二级目录 * 1)得到文件名称 * 2)得到hashCode * 3)转化成16进制 * 4)获取前2个字符用来生成目录 */ String filename=fi.getName(); /* * 处理文件名的绝对路径问题 */ int index=filename.lastIndexOf("\\"); if(index!=-1){ filename=filename.substring(index+1); } /* * 给文件添加yyid前缀,处理同名问题 */ String savename=CommonUtils.uuid()+"_"+filename; /* * 得到hashCode */ int hCode=filename.hashCode(); String hex=Integer.toHexString(hCode); /* * 获取hex的前两个字母,与root连接在一起,生成一个完整的路径 */ File dirFile=new File(root,hex.charAt(0)+"/"+hex.charAt(1)); /* * 创建目录链 */ dirFile.mkdirs(); /* * 创建目录文件 */ File destFile=new File(dirFile,savename); /* * 保存 */ fi.write(destFile); } catch (FileUploadException e) { if(e instanceof FileUploadBase.FileSizeLimitExceededException){ request.setAttribute("msg", "您上传的文件超出了100kb"); request.getRequestDispatcher("/form3.jsp").forward(request, response); }else if(e instanceof FileUploadBase.SizeLimitExceededException){ request.setAttribute("msg", "您上传的的总大小超出了1M"); System.out.println(2); request.getRequestDispatcher("/form3.jsp").forward(request, response); } } catch (Exception e) { e.printStackTrace(); } }}
View Code

 

 

下载1.下载就是向客户端响应字节数据!    原来我们响应的都是html的字符数据!    把一个文件变成字节数组,使用response.getOutputStream()来响应给浏览器    2.下载的要求    *两个头一个流     >Content-Type:你传递给客户端的文件时什么类型。例如:image/pjpeg        *通过文件名称调用ServletContext的getMimeType方法得到MIME类型     >Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!下载使用:attachment:filename=xxx        *在filename=后面跟随的是显示在下载框中的名称     >流:要下载的文件数据!     ------------------------------下载的细节1.显示在下载框中的中文名称时,会出现乱码    *FireFox:Base64编码    *其他大部分浏览器:URL编码。    通用方案:filename=new String(filename.getByte("GBK"),"ISO-8859-1") //个别字符不太好使

 

package cn.itcast.web.servlet;import java.io.FileInputStream;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.io.IOUtils;import cn.itcast.tool.utils.DownLoadUtils;public class Download1Servlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        /*         * 两个头一个流         * Content-Type         * Content-Disposition         * 流:下载文件的数据         */        String filename="E:\\KuGou\\陈粒 - 奇妙能力歌.mp3";                String framename=DownLoadUtils.filenameEncoding("陈粒-奇妙能力歌.mp3", request);        String ContentType=this.getServletContext().getMimeType(filename);//通过文件名获取文件MIME//        String ContentDisposition="attachment;filename=a.mp3";//        String ContentDisposition="attachment;filename="+new String("陈粒-奇妙能力歌.mp3".getBytes("GBK"),"ISO-8859-1");        String ContentDisposition="attachment;filename="+framename;//        System.out.println(new String("陈粒-奇妙能力歌.mp3".getBytes("GBK"),"ISO-8859-1"));//????-?????????è.mp3 我们的控制台乱码,但是浏览器喜欢这个        /*         Returns the MIME type of the specified file, or null if the MIME type is not known. The MIME type is determined by the configuration of the servlet container, and may be specified in a web application deployment descriptor. Common MIME types are "text/html" and "image/gif".          */        FileInputStream input=new FileInputStream(filename);        response.setHeader("Content-Type",ContentType);        response.setHeader("Content-Disposition", ContentDisposition);        //获取绑定了客户端的流        ServletOutputStream output=response.getOutputStream();        IOUtils.copy(input, output);        input.close();    }}package cn.itcast.tool.utils;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import javax.servlet.http.HttpServletRequest;import sun.misc.BASE64Encoder;public class DownLoadUtils {        public static String filenameEncoding(String filename,HttpServletRequest request) throws UnsupportedEncodingException{        String agent=request.getHeader("User-Agent");//获取浏览器        if(agent.contains("FireFox")){            BASE64Encoder base64Encoder=new BASE64Encoder();            filename="=?utf-8?B?"+base64Encoder.encode(filename.getBytes("utf-8"))+"?=";        }else if(agent.contains("MSIE")){            filename=URLEncoder.encode(filename,"utf-8");        }else{            filename=URLEncoder.encode(filename,"utf-8");        }        return filename;            }}
View Code

使用base64编码和解码:

package cn.itcast.base64;import java.io.IOException;import org.junit.Test;import sun.misc.BASE64Encoder;import sun.misc.BASE64Decoder;public class Demo1 {    @Test    public void fun1() throws IOException {                // BASE64编码        String s = "Username";        BASE64Encoder encoder = new BASE64Encoder();        s = encoder.encode(s.getBytes("UTF-8"));        System.out.println(s);                // BASE64解码        BASE64Decoder decoder = new BASE64Decoder();        byte[] bytes = decoder.decodeBuffer("dXNlcm5hbWU6");        System.out.println(new String(bytes, "UTF-8"));    }}
View Code

 

转载地址:https://blog.csdn.net/weixin_33708432/article/details/86277050 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:[转]ORACLE 动态执行SQL语句
下一篇:【转】Git详解之一:Git起步

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年03月03日 11时13分36秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

java ajax 修改数据库数据库数据库_AJAX 自学练习 无刷新提交并修改数据库数据并显... 2019-04-21
java并发编程指南博客_Java并发编程-synchronized指南 2019-04-21
java怎么中断阻塞状态_java并发编程()阻塞方法与中断方法 2019-04-21
java zlib 位运算_位运算入门:找出一个二进制数的最右端的第一个1;计算一个二进制数中1的个数;找出数组中唯一一个出现次数为奇数的数;找出数组中唯二两个出现次数为奇数的数... 2019-04-21
java lua热更新_lua热更新学习 2019-04-21
script执行php文件_php命令行(cli)下执行PHP脚本文件的相对路径的问题解决方法... 2019-04-21
apache 2.4 php5.4_apache2.4+php5.4+my sql 5.6,网站经常无故不能访问 2019-04-21
php apc.dll下载,PHP之APC缓存详细介绍 apc模块安装 2019-04-21
html贝塞尔曲线在线,贝塞尔曲线的一些事情_html/css_WEB-ITnose 2019-04-21
java blockingqueue源码_Java并发队列BlockingQueue实现之ArrayBlockingQueue源码分析 2019-04-21
Java前台显示近20天的东西_第十次课:前台首页设计及显示商品信息 2019-04-21
java开发web网站的路由设计_理解Web路由(浅谈前后端路由与前后端渲染) 2019-04-21
excel如何把顺序倒过来_在excel中怎么使文字颠倒顺序反过来显示呢? 2019-04-21
java 62进制 转换_序列号生成的另一种玩法--62进制如何玩? 2019-04-21
php正则表达式获取图片路径,php 常用正则表达式实例(图片地址,与指定内容获取)... 2019-04-21
脚本语言php是什么意思,PHP脚本语言 2019-04-21
matlab数学规划模型,数学规划模型 2019-04-21
视频提取音频php,如何提取视频中的音频,从视频文件中提取出音频输出成MP3格式... 2019-04-21
diy.php添加验证码,织梦dedecms自定义表单中加入验证码 2019-04-21
在php脚本中 通过可以获取,在PHP中,可以使用Unix时间戳获取精确的脚本执行时间。... 2019-04-21