精华内容
下载资源
问答
  • web文件上传

    千次阅读 2018-07-12 10:38:39
    今天在复习Web 的时候,做个一个文件上传的小Demo,发布一篇博客,记录一些笔记要点。和web做上传的一些注意事项。这个Demo 解决了Web上传问题中的以下问题: 1.实现web开发中的文件上传功能,需要完成2个步骤操作: ...

            今天在复习Web 的时候,做个一个文件上传的小Demo,发布一篇博客,记录一些笔记要点。和web做上传的一些注意事项。这个Demo 解决了Web上传问题中的以下问题:

    1.实现web开发中的文件上传功能,需要完成2个步骤操作:

    ①在web页面中添加上传输入项
    ②在servlet中读取上传文件的数据,并保存到本地盘中。

    如何在web页面中添加上传输入项?
    <input type="file">标签用于在web页面中添加文件上传输入项,设 置文件上传输入项时刻须注意。
    1.必须要设置inpu输入项的name属性,否则浏览器将不会发送上传文件的数据.
    2.必须把form的enctype属性设置为multipart/form-data,设置该值后,浏览器在上传文件时,将把文件数据附带在http
    请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。

    DisKFileItemFactory是创建 FileItem 对象的工厂,这个工厂类常用方法:
    public void setSizeThreshold(int size Threshould)
    设置内存缓冲区的大小,默认为10k,当上传文件大于缓冲区大小时,fileupload组件将使用
    临时缓存上传文件。
    public void  (java.io.File.repository)
    指定临时文件目录,默认值为
    System.getProperty("java.lang.tmpdir");

    public DiskFileItemFactory(int size Threshould,java.ioo.File repository)
    构造函数

    上传文件乱码问题:
    DiskFileItemFactory factory = new DiskFileItemFactoy();
    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setEncoding("UTF-8");

    inpuvalue = new String(inputValue.getBytes("iso-8859-1","UTF-8"));

    ServletFileUpload.setHeaderEnconding("UTF-8");
    1.上传文件乱码:
    1.1 ServletFileUpload.setHeaderEnconding("UTF-8");
    1.2 解决普通输入项的乱码(注意:表单类型为Multipart/form-data的时候,设置request的编码是无效的)
    FileItem.setString("UTF-8"); //解决乱码
    2.在处理表单之前,要记得调用:
    ServletFileUpload.isMultipartContent
    3.设置解析器缓冲器大小,以及临时文件的删除
    设置解析器缓冲区大小   DiskFileItemFactory.setSizeThreshould(1024*1024);方法
    临时文件的删除,在程序中处理完成上传文件后,一定要记得调用item.delete()方法,以删除临时文件

    4.再上传系统时候,注意上传文件的目录,这个文件的保存目录不能让外界直接访问到.不然后服务器有很大的漏洞。

    5.限制上传文件的类型
    List types = Arrays.asList(".jpg",".gif",".avi",".txt"); 
    6.限制上传文件的大小
    ServletFileUpload负责处理上传的数据,并将表单中每个输入项封装成一个FileItem对象中,常用方法有:
    boolean isMultipartContent(HttpServletRequest request)
    判断上传表单是为Multipart/form-data类型
    List<FileItem> list = upload.parseRequest(request);
    解析request对象,并把表单中的每个输入项包装成一个fileItem对象,并返回一个保存了所有FileItem的list集合.
    setFile SizeFileMax(long fileSizeMax)
    设置单个上传文件总量的最大值
    setSizeMax(long sizeMax)
    设置上传文件总量的最大值
    setHeaderEconding(java.lang.String encoding)
    设置编码格式
    setProgressListener(ProgressListener pListener)

    7.如何判断空上传输入项
    String filename = item.getName().substring(item.getName().lastIndexOf("\\")+1); //获取到文件名称
    String ext = filename.substring(filename.lastIndexOf(".")+1); //获得文件的扩展名
    if(filename==null || filename.trim().equals("")){
    continue;
    }

    8.为避免上传文件的覆盖,程序在保存上传文件时,要为文件生成唯一的文件名
    public String generateFileName(String filename){
    return UUID.randomUUID().toString() + "_" + filename;
    }

    String savepath = this.getServletContext().getRealPath("/WEB-INF/upload");
    String saveFileName = generateFileName(filename);
    //File.separator   常量分隔符   /
    FileOutputStream out = new FileOutputStream(savepath + File.separator + saveFileName); //指定目录下

    9.目录文件上限问题(哈希目录)  原理:文件名转换成哈希值  根据哈希第四位生成一级目录
    在web工程中难免会有目录保存的文件过多而见降低打开目录的效率.一般来说一个目录保存1000个文件属于正常。对于1000个,目录打开效率就会降低
    所以我们使用一种将目录的名字转换成哈希值打散存储
    public String generateSavePath(String pathe,String filename){
    int hashcode = filename.hashCode(); //121212
    int dir1 = hashcode&15;
    int dir2 = (hashcode>>4)&0xf;

    String savepath = path + File.separator + dir1 + File.separator + dir2;
    if(!file.exists()){
    file.mkdirs(); //因为需要创建多级目录  所以这里一定是mkdirs()  不是mkdir()函数
    }
    return savepath;
    }

    图示举例:
    哈希值在计算机中的保存以二进制保存   为数字

    0011 1010 0111 1111 1010 1110 0110 0111
    ---------------------------------------    二进制 1111 = 15 十进制
    0000 0000 0000 0000 0000 0000 0000 1111

    结果:000 0000 0000 0000 0000 0000 0000 0111 7
    按照哈希值的第四位 保存 二进制0111 = 十进制 7 保存到文件目录为7的目录下,第四位最大为15-最小为0,故总共16个一级目录
    一级目录不够,再利用哈希值的第5-8位,生成二级目录.类似可以生成三级目录、四级目录、无极目录... 代码如下:

    //解决目录上限(1000个最佳)问题
    public String generateSavePath(String path,String filename){
    int hashcode = filename.hashCode(); //哈希值
    int dir1 = hashcode&15; //一级目录
    int dir2 = (hashcode>>4)&0xf; //二级目录  哈希值的第5~8位
    String savepath = path + File.separator + dir1 + File.separator + dir2;
    File file = new File(savepath);
    if(!file.exists()){
    file.mkdirs();
    }
    return savepath;
    }

    10.后台进度条数据(设置监听器 ServletFileUpload.setProcessListener())
    (监听器一定要设在解析之前)使用解析器调用update方法
    void update(long pBytesRead,long pContentLength,int pItems);
    //每 1M 进度条涨一下
    ProgressListener progressListener = new ProgerssListener(){
    private long megaBytes = -1;
    public void update(long pBytesRead,long pContentLength,int pItems){
    long mBytes = pBytesRead / 1000000;
    if(megBytes == aBytes){
    return ;
    }
    megaBytes = mBytes;
    System.out.println("We are currently reading item "+pItems);
    if(pContenLength == -1){
    System.out.println("So far "+pBytesRead +"Bytes have been read ");
    }else{
    System.out.println("So far."+pBytesRead +"of "+ pContentLength +"bytes have been read.");
    }
    }
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Arrays;
    import java.util.List;
    import java.util.UUID;

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    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.ProgressListener;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;

    @WebServlet("/UploadServlet")
    public class UploadServlet extends HttpServlet{
    /**

    */
    private static final long serialVersionUID = 1L;
    //处理上传数据
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    DiskFileItemFactory factory = new DiskFileItemFactory(); //创建一个工厂  默认缓冲区大小为10k
    //设置缓冲区大小为 1 M  如果上传文件大于1M,则上传的文件将不再保存在缓冲区,将会保存在临时文件中,读取数据的时候也会从临时文件中读取
    factory.setSizeThreshold(1024*1024);  
    //设置临时文件保存目录   / 代表web工程    将/temp设置为临时保存文件目录
    factory.setRepository(new File(this.getServletContext().getRealPath("temp")));
    ServletFileUpload upload = new ServletFileUpload(factory); //创建解析器

    //在解析数据之前  做后台页面数据生成进度条
    upload.setProgressListener(new ProgressListener() {
    private long megaBytes = -1 ;
    @Override
    public void update(long pBytesRead, long pContentLength, int pItems) {
    long mBytes = pBytesRead / 1000000;
    if(mBytes == -1){
    return ;
    }
    megaBytes = mBytes;
    System.out.println("已经读取文件个数:"+pItems);
    if(pContentLength == -1){
    System.out.println("已经读取"+pBytesRead+"字节");
    }else{
    System.out.println("读取了"+ pBytesRead +"字节");
    }
    }
    });

    //解决中文乱码问题
    upload.setHeaderEncoding("UTF-8");
    //限制单个文件上传大小   100 M
    upload.setFileSizeMax(1024*1024*100);
    //限制上传数据的类型
    List types = Arrays.asList("txt","avi","gif","jpg");
    if(!upload.isMultipartContent(request)){ //若果不是上传表单数据
    String nameString = request.getParameter("username");
    System.out.println("name:"+nameString);
    return ;
    }
    try {
    System.out.println("//");
    System.out.println(this.getServletContext().getRealPath("/WEB-INF/upload"));
    System.out.println("----------------------------------");
    List<FileItem> list = upload.parseRequest(request); //调用解析器解析request,得到并保存所有上传数据的List
    for (FileItem item : list) {
    if(item.isFormField()){ //判断是否为输入项
    //为输入项
    String  inputName = item.getFieldName(); //获得文件的名称
    String  inputvalue = item.getString(); //获得文件的值
    String  inputValue = new String(inputvalue.getBytes("iso-8859-1"));
    System.out.println(inputName+"="+inputValue);
    }else{
    //代表输入项中封装的是文件
    String filename = item.getName().substring(item.getName().lastIndexOf("\\")+1); //获取到文件名称
    String ext = filename.substring(filename.lastIndexOf(".")+1); //获得文件的扩展名
    if(filename==null || filename.trim().equals("")){
    continue;
    }
    /*if(!types.contains(ext)){
    request.setAttribute("message","本系统不支持上传"+ext+"文件类型");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
    return ;
    }*/
    System.out.println("filename:"+filename);
    InputStream in = item.getInputStream(); //获得inputStream流
    //设置缓冲区
    int len = 0;
    byte buffer[] = new byte[1024];
    String saveFileName = generateFileName(filename); //调用gerenate函数 生成唯一的文件名称
    String savepath = generateSavePath(this.getServletContext().getRealPath("/WEB-INF/upload"),saveFileName);
    //File.separator   常量分隔符   /
    FileOutputStream out = new FileOutputStream(savepath + File.separator + saveFileName); //指定目录下
    while((len = in.read(buffer)) > 0){
    out.write(buffer,0,len);
    }
    in.close();
    out.close();
    item.delete(); //删除上传完毕后的临时文件
    }
    }
    }catch (FileUploadBase.FileSizeLimitExceededException e) {
    request.setAttribute("message","文件大小不能超过 5 M");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
    return ;
    }catch (FileUploadException e) {
    e.printStackTrace();
    }
    }

    //解决同名文件覆盖问题
    public String generateFileName(String filename){
    //UUID.randomUUID().toString() 74e59732-f339-4546-bf91-42c6c83696ea 全球唯一标识
    return UUID.randomUUID().toString() + "_" + filename;
    }

    //解决目录上限(1000个最佳)问题
    public String generateSavePath(String path,String filename){
    int hashcode = filename.hashCode(); //哈希值
    int dir1 = hashcode&15; //一级目录
    //0x 代表16进制  16进制 0 1 2 . . . A(10) B C D E F(15) 则0xf = 1111 最高为补24位 0000 0000 0000 0000 0000 0000 1111 
    //hashcode>>4 哈希值向前移动4位 若原来为0101 1000 0010 0001 1111 1100 1010 1111 移动后为0101 1000 0010 0001 1111 1100 1010
    int dir2 = (hashcode>>4)& 0xf; //二级目录   
    String savepath = path + File.separator + dir1 + File.separator + dir2;
    File file = new File(savepath);
    if(!file.exists()){
    file.mkdirs();
    }
    return savepath;
    }
    }

    };

     

    1.创建Web工程

     

    2.编写UploadServlet.java代码

    package com.nyist.cn.Servlet;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Arrays;
    import java.util.List;
    import java.util.UUID;

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    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.ProgressListener;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;

    @WebServlet("/UploadServlet")
    public class UploadServlet extends HttpServlet{
    /**

    */
    private static final long serialVersionUID = 1L;
    //处理上传数据
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    DiskFileItemFactory factory = new DiskFileItemFactory(); //创建一个工厂  默认缓冲区大小为10k
    //设置缓冲区大小为 1 M  如果上传文件大于1M,则上传的文件将不再保存在缓冲区,将会保存在临时文件中,读取数据的时候也会从临时文件中读取
    factory.setSizeThreshold(1024*1024);  
    //设置临时文件保存目录   / 代表web工程    将/temp设置为临时保存文件目录
    factory.setRepository(new File(this.getServletContext().getRealPath("temp")));
    ServletFileUpload upload = new ServletFileUpload(factory); //创建解析器

    //在解析数据之前  做后台页面数据生成进度条
    upload.setProgressListener(new ProgressListener() {
    private long megaBytes = -1 ;
    @Override
    public void update(long pBytesRead, long pContentLength, int pItems) {
    long mBytes = pBytesRead / 1000000;
    if(mBytes == -1){
    return ;
    }
    megaBytes = mBytes;
    System.out.println("已经读取文件个数:"+pItems);
    if(pContentLength == -1){
    System.out.println("已经读取"+pBytesRead+"字节");
    }else{
    System.out.println("读取了"+ pBytesRead +"字节");
    }
    }
    });

    //解决中文乱码问题
    upload.setHeaderEncoding("UTF-8");
    //限制单个文件上传大小   100 M
    upload.setFileSizeMax(1024*1024*100);
    //限制上传数据的类型
    List types = Arrays.asList("txt","avi","gif","jpg");
    if(!upload.isMultipartContent(request)){ //若果不是上传表单数据
    String nameString = request.getParameter("username");
    System.out.println("name:"+nameString);
    return ;
    }
    try {
    System.out.println("//");
    System.out.println(this.getServletContext().getRealPath("/WEB-INF/upload"));
    System.out.println("----------------------------------");
    List<FileItem> list = upload.parseRequest(request); //调用解析器解析request,得到并保存所有上传数据的List
    for (FileItem item : list) {
    if(item.isFormField()){ //判断是否为输入项
    //为输入项
    String  inputName = item.getFieldName(); //获得文件的名称
    String  inputvalue = item.getString(); //获得文件的值
    String  inputValue = new String(inputvalue.getBytes("iso-8859-1"));
    System.out.println(inputName+"="+inputValue);
    }else{
    //代表输入项中封装的是文件
    String filename = item.getName().substring(item.getName().lastIndexOf("\\")+1); //获取到文件名称
    String ext = filename.substring(filename.lastIndexOf(".")+1); //获得文件的扩展名
    if(filename==null || filename.trim().equals("")){
    continue;
    }
    /*if(!types.contains(ext)){
    request.setAttribute("message","本系统不支持上传"+ext+"文件类型");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
    return ;
    }*/
    System.out.println("filename:"+filename);
    InputStream in = item.getInputStream(); //获得inputStream流
    //设置缓冲区
    int len = 0;
    byte buffer[] = new byte[1024];
    String saveFileName = generateFileName(filename); //调用gerenate函数 生成唯一的文件名称
    String savepath = generateSavePath(this.getServletContext().getRealPath("/WEB-INF/upload"),saveFileName);
    //File.separator   常量分隔符   /
    FileOutputStream out = new FileOutputStream(savepath + File.separator + saveFileName); //指定目录下
    while((len = in.read(buffer)) > 0){
    out.write(buffer,0,len);
    }
    in.close();
    out.close();
    item.delete(); //删除上传完毕后的临时文件
    }
    }
    }catch (FileUploadBase.FileSizeLimitExceededException e) {
    request.setAttribute("message","文件大小不能超过 5 M");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
    return ;
    }catch (FileUploadException e) {
    e.printStackTrace();
    }
    }

    //解决同名文件覆盖问题
    public String generateFileName(String filename){
    //UUID.randomUUID().toString() 74e59732-f339-4546-bf91-42c6c83696ea 全球唯一标识
    return UUID.randomUUID().toString() + "_" + filename;
    }

    //解决目录上限(1000个最佳)问题
    public String generateSavePath(String path,String filename){
    int hashcode = filename.hashCode(); //哈希值
    int dir1 = hashcode&15; //一级目录
    //0x 代表16进制  16进制 0 1 2 . . . A(10) B C D E F(15) 则0xf = 1111 最高为补24位 0000 0000 0000 0000 0000 0000 1111 
    //hashcode>>4 哈希值向前移动4位 若原来为0101 1000 0010 0001 1111 1100 1010 1111 移动后为0101 1000 0010 0001 1111 1100 1010
    int dir2 = (hashcode>>4)& 0xf; //二级目录   
    String savepath = path + File.separator + dir1 + File.separator + dir2;
    File file = new File(savepath);
    if(!file.exists()){
    file.mkdirs();
    }
    return savepath;
    }

    }

    4.上传文件测试

     

    运行结果:

    ............

    ............

    ............

    已经读取文件个数:3

    读取了83787776字节
    已经读取文件个数:3
    读取了83791830字节
    已经读取文件个数:3
    读取了83795884字节
    已经读取文件个数:3
    读取了83795968字节
    已经读取文件个数:3
    读取了83800022字节
    已经读取文件个数:3
    读取了83804076字节
    已经读取文件个数:3
    读取了83804160字节
    已经读取文件个数:3
    读取了83808214字节
    已经读取文件个数:3
    读取了83812268字节
    已经读取文件个数:3
    读取了83812352字节
    已经读取文件个数:3
    读取了83816406字节
    已经读取文件个数:3
    读取了83820460字节
    已经读取文件个数:3
    读取了83820544字节
    已经读取文件个数:3
    读取了83824598字节
    已经读取文件个数:3
    读取了83828652字节
    已经读取文件个数:3
    读取了83828736字节
    已经读取文件个数:3
    读取了83831201字节
    username=监听器上传视频数据

    filename:02-处理上传需要注意的细节.avi

     

    展开全文
  • 最近公司产品使用openwrt,其中在使用openwrt的web方式升级内核和文件系统时(即sysupgrade固件)时,发现校验文件时提示The uploaded image file does not contain a supported format. Make sure that you choose ...

    最近公司产品使用openwrt,其中在使用openwrt的web方式升级内核和文件系统时(即sysupgrade固件)时,发现校验文件时提示The uploaded image file does not contain a supported format. Make sure that you choose the generic image format for your platform.于是在网上找了些资料,总结如下:
    ###网上提供的解决方法:
    1.在openwrt-ar71xx-generic-db120-squashfs-sysupgrade.bin的起始位置增加32字节,但是尝试后无果。参考OpenWrt image conversion
    2.跟踪调用过程,分析原因,写的不是很清楚,不过给我提供了思路。参考openwrt Web刷写新的固件提示文件格式问题
    ###自己的解决思路:
    1.使用wscp软件将openwrt-ar71xx-generic-db120-squashfs-sysupgrade.bin文件上传至路由器文件系统中。
    2.使用sysupgrade命令升级openwrt-ar71xx-generic-db120-squashfs-sysupgrade.bin,命令如下:

    openwrt-ar71xx-generic-db120-squashfs-sysupgrade.bin
    

    3.根据步骤2中提示的错误信息,定位具体shell脚本,我的板子提示如下信息:

    Invalid image type.
    	Image check 'platform_check_image' failed.
    

    4.根据提示错误信息在板子上定位具体文件,find / -type f|xargs grep “platform_check_image”,我最终定位在/lib/upgrade/platform.sh脚本中。
    5.在/lib/upgrade/platform.sh的platform_check_image函数中增加打印信息:echo $magic_long,其中magic_long为openwrt-ar71xx-generic-db120-squashfs-sysupgrade.bin的头4字节,我的对不上,于是在openwrt根目录下修改 vim ./linux/ar71xx/base-files/lib/upgrade/platform.sh中将magic_long修改成自己的升级固件的头四字节(注意:十六进制的),重新编译内核,校验通过。

    展开全文
  • web文件上传下载原理浅析

    万次阅读 2017-12-11 10:58:36
    一、web文件上传浅析 现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于java的Commons FileUpload、还有Struts1.x和Struts2中带的上传文件功能(实际上,Struts2在底层也使用了Commons ...

    一、web文件上传浅析

    现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于javaCommons FileUpload、还有Struts1.xStruts2中带的上传文件功能(实际上,Struts2在底层也使用了Commons FileUpload)。在asp.net中也有相应的上传文件的控件。

    虽然现在有很多上传组件可以利用,但是了解Web上传文件的原理,对于处理突然出现的问题会有很大的帮助,下面就来讲一下通过浏览器上传文件的基本原理。在了解了原理之后,就可以非常容易地自制满足自身需要的上传组件了。

    众所周知,在客户端代码中需要使用<input type='file' name='file' />来选择要上传的文件,并上传,代码如上:

    <html>
        <head>
            <title>upload</title>
            <meta http-equiv="description" content="this is my page">
            <meta http-equiv="content-type" content="text/html; charset=GB18030">
        </head>
    
        <body>
            <form action="servlet/UploadFile" method="post"
                enctype="multipart/form-data">
                <input type="file" name="file1" id="file1" />
                <input type="file" name="file2" id="file2" />
                <input type="submit" value="上传" />
            </form>
        </body>
    </html>
       从上面的代码可以看出,有两个文件选择框(file1file2),在上传文件时,<form>标签必须加上enctype="multipart/form-data",否则浏览器无法将文件内容上传到服务端。下面我们来做个实验。在ServletdoPost方法中编写如下的代码,如果想使用asp.net或其他的语言或技术,也可以很容易实现相应的功能。

     public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException
        {
            java.io.InputStream is = request.getInputStream();
            java.io.FileOutputStream fos = new java.io.FileOutputStream("d:\\out.txt");
            
            byte[] buffer = new byte[8192];
            int count = 0;
            while((count = is.read(buffer)) >0)
            {
                fos.write(buffer, 0, count);
            }        
            fos.close();
        }
       上面的功能非常简单,只是通过request获得一个InputStream对象,并通过这个对象从客户端获得发送过来的字节流(注意,一定要用字节流,因为,上传的文件可能是二进制文件,如图象文件,因此,使用字节流会更通用)。并将这些字节流保存在D盘的out.txt文件中。然后我们打开out.txt,文件的内容如图1所示:
               
     

                                                                                                                               图1

     由于out.txt是使用文本形式打开的,并且file1上传的是a.jpg(一个图象文件),因此,显示的是一些乱码。我们可以不用管它们。只需要看看这些内容的头部。我们很快就可以找到规律。每一个文件内容的头部都由“-----------------------------30514443229777”分隔,然后是这个文件的属性,如下:

    Content-Disposition: form-data; name="file1"; filename="a.jpg"

    Content-Type: image/jpeg

    其中包含了文件选择框的name属性,还有上传的文件名(filename字段),要注意的,firefox在上传时,这个filename属性值只是文件名,如果使用IE,就是带路径的文件名,如D:"a.jpg

    接下来的规则就和HTTP的头一样了,以一个空行("r"n)分隔。后面就是文件的具体内容。现在最关键的文件的结尾,从图1可以看出,文件的结尾也是“-----------------------------30514443229777”,因此,可以断定,第一个上传的文件(包括文件头)是夹在两个“-----------------------------30514443229777”之间的。而“-----------------------------30514443229777”就是multipart/form-data协议的分隔符。但这里还有一个最关键的问题。这个分隔符每次上传都不一样,服务端是如何知道每次上传的这个分隔符的呢?

    实际上,这个分隔符是通过HTTP请求头的Content-Type字段获得,可通过下面的代码输出这个字段值:

    System.out.println(request.getHeader("Content-type"));

    输出的内容如下:

    multipart/form-data; boundary=---------------------------106712230227687

    只要在服务端获得boundary后面的值即可。经过测试,Content-Type中的分隔符号中的“-”比实际上传的“-”少两个,不知是怎么回事。不过这没关系,我们可以认为每一个文件块是以""r"n—“结尾的,或是直接将从boundary获得的分隔符加两个“”。而最后结尾的分隔符是“---------------------------106712230227687—”,后面多了两个“”。

    综合上述,也就是说,一个文件块是以“---------------------------106712230227687”开头,以“”结尾,从图2可以看出这一切。

                                             

                                                                                                                             图 2

    至于剩下的工作,就是按着上面的规则来分析这些字符流了。分析的方法很多。在这里就不详述了。

          multipart/form-data规 范原文:http://www.ietf.org/rfc/rfc2388.txt 
       Form-based File Upload in HTML:http://www.ietf.org/rfc/rfc1867.txt

    二、web文件下载浅析

    文件下载流程

    服务器端编码原理下载分析:在服务端通过response可以获取到输出流,在服务端通过输入流将文件流获取到然后通过response获取输出流直接写回到浏览器即可完成下载。

    服务器端下载两个响应头设置

    1. 怎样能通知浏览器,下载文件是什么:通过response.setContentType设置响应数据的mimeType类型。获取一个文件的mimeType类型,ServletContext.getMimeType(String filename)
    2.  设置下载文件名称:response.setHeader("Content-Disposition","attachement;filename=下载名称")

    下载乱码问题

    对于下载时,我们在显示文件下载名称的时候,如果包含了中文,就可能出现乱码问题。原因在于不同的浏览器,他们在处理下载文件的时候编码不一致,ie浏览器使用的是utf-8编码,而firefox使用的是base64编码。所以在下载还需要设置编码格式。示例如下:
    		response.setCharacterEncoding("utf-8");
    		String filename = request.getParameter("filename");
    		String downPath = path+"/upload";
    		FileInputStream in = new FileInputStream(downPath+File.separator+filename);
    
    		if(request.getHeader("user-agent").toLowerCase().contains("msie")){
    			filename = URLEncoder.encode(filename, "UTF-8");
    		}else{
    			filename = new String(filename.getBytes("UTF-8"),"iso-8859-1");
    		}
    		response.setHeader("content-disposition", "attachment;filename="+filename);
    		response.setHeader("content-type",this.getServletContext().getMimeType(filename));
    
    		OutputStream os = response.getOutputStream();
    		byte[] buffer = new byte[1024];
    		int len=0;      
    		while((len=in.read(buffer))!=-1) {
    			os.write(buffer, 0, len);
    		}
    		in.close();
    		os.close(); 

    转载地址:https://www.cnblogs.com/nokiaguy/archive/2008/05/29/1209858.html
    
    



    展开全文
  • 当使用WWW访问Web服务时,安全策略会阻止跨域的请求访问,会返回类似...解决办法:为提供Web服务的目录配置安全策略文件,即crossdomain.xml,crossdomain.xml文件的写法如下: domain=

    当使用WWW访问Web服务时,安全策略会阻止跨域的请求访问,会返回类似“Rejected because no crossdomain.xml policy file was found”等错误信息。
    解决办法:为提供Web服务的目录配置安全策略文件,即crossdomain.xml,crossdomain.xml文件的写法如下:


    <?xml version="1.0" encoding="ISO-8859-1"?>
    <cross-domain-policy>
    <allow-access-from domain="*"/>
    </cross-domain-policy>


    domain=“*” 表示该服务目录允许任何外域来访问,你也可以把“*”替换成指定的域名,如下:

    <allow-access-from domain=”*.taobao.com”/>

    <allow-access-from domain="*" to-ports="1200-1220"/>开放的端口


    crossdomain.xml起初是adobe搞的,为了让flash跨域访问文件。

    该配置文件放于服务器端的根目录下面。来设置让哪些域名下面的swf文件能够访问我服务器上的内容。

    注意: crossdomain.xml必须是一个ASCII文件。
    该文件要放置在服务器的根目录下,例如:www.xy.net/crossdomain.xmlhttp://ip:port/crossdomain.xml

    本地调试程序时解决跨域问题的方法:
    菜单设置:Edit->Project Settings->Eidtor


    展开全文
  • 在通过WEB更新系统升级包时弹出提示“The uploaded image file does not contain a supported format. Make sure that you choose the generic image format for your platform.” 这个问题在网上也找了些资料,有...
  • Webarchive文件

    千次阅读 2017-08-09 11:55:48
    一:生成 二:使用 ...1:用mac自带浏览器Safari:随便打卡一个网页,comd+S 保存到本地的文件就是.ewbarchive文件,这个文件是本地的。...2.1:webarchive文件转换成htm文件 Step 1: 建
  • .webarchive文件转换成html文件

    千次阅读 2018-01-05 11:01:58
    Mac OS X系统带有文件转换功能,可以把webarchive文件变成html文件
  • java web文件下载功能实现

    万次阅读 多人点赞 2014-09-20 17:38:54
    需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法:  一:通过超链接实现下载 在HTML网页中,通过超链接链接到要下载的文件的地址 Insert title here 通过链接下载文件 压缩包 ...
  • HCI,CPCI-S) 数据库搜索的文献导出为Endnote支持的格式之后,生成的是扩展名为*.ciw格式文件。为此,很多人将其导入到Endnote中时不知应该选用哪个filter而一筹莫展。 其实很简单,这个filter叫:ISI-CE。在...
  • Web文件上传原理

    千次阅读 2014-07-03 11:35:21
    采用WEB技术实现B/S(浏览器/服务器)结构的管理系统是办公自动化的发展趋势。基于WEB技术的管理系统,由于开发周期短;... 许多基于WEB的应用都涉及文件上传操作。常见的文件上传技术有:基于HTTP协议的
  • Web字体逐渐成为话题,这项让未来Web更加丰富多彩的技术拥有多种实现方案,其中之一是通过@font-face属性在网页中嵌入自定义字体,主流的浏览器都支持这项技术,本文介绍主要的几种Web字体格式及字体格式转换。...
  • 小程序中打开pdf格式原本可以使用web-view(承载网页的容器。...但是src里面放pdf的链接涉及到了兼容性问题(苹果手机可以正常打开pdf格式文件,安卓打开为空白) 所以如果src里面放pdf格式就会...
  • 2中思路,一种是转换后显示,比如vectordraw,将dwg转换成vds格式,再在web中显示,支持图层啊之类。还有CADViewer JS是转成SVGA,pdf等格式,然后用web浏览……其实转换格式也是一个办法,用golang在后端,当有请求...
  • move_uploaded_file();...这段代码分为两个文件,一个为upload.html,一个是upload.php upload.html [form] enctype=”multipart/form-data” action=”upload.php” method=”post”> [input type="hidden" nam
  • ZIP文件格式分析

    万次阅读 多人点赞 2016-06-12 14:55:41
    官方文档https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.2.0.txt格式说明在官方文档中给出的ZIP格式如下: Overall .ZIP file format: [local file header 1] [file data 1] [data descriptor 1] . . ...
  • 最近在做一个"考评系统",是用C# asp.net编写的Web文件。今天在实现一个功能"将页面显示的GridView中的数据,导出到Excel表格中"时遇到这样一个错误: C# 导出Excel文件 打开Excel文件格式与扩展名指定格式不一致。...
  • 网页html web直接打开cad文件dwg格式等的方法

    万次阅读 热门讨论 2018-06-16 22:18:04
    用mxdraw控件,似乎只支持ie。但支持中文字体最好,有小小水印,但是我们网页上打开图纸,不都是只是为了瞄一眼嘛,不在乎这点水印。html调用代码:&lt;!DOCTYPE HTML PUBLIC "...&gt; ...
  • webarchive文件转换成htm文件

    千次阅读 2013-03-11 13:56:27
    Mac OS X系统带有文件转换功能,可以把webarchive文件变成html文件。方法是:   Step 1: 建立一个文件夹,把你的webarchive文件放入文件夹内。 Step 2 在终端(Terminal)下输入:textutil -convert html空格 ...
  • python web 上传文件

    千次阅读 2019-07-12 09:41:08
    python上传文件 一、.写html文件文件名为upfile.html) 上传文件 {% csrf_token %} 说明: 1、表单中enctype="multipart/form-...默认情况,这个编码格式是application/x-ww...
  • web文件上传大小限制

    千次阅读 2017-04-27 20:39:18
    一般分为两种方式,一种是服务器端判断文件大小进行限制,这种方法的存在明显的缺陷,当用户过多后,数据上传到服务器之后,在对其进行监测,大大增加了宽带和服务器的压力。 另一种是放在前端进行大小监测, ...
  • java实现web文件无刷新上传(二)

    千次阅读 2013-09-09 10:35:01
    实现web开发中的文件上传功能,需完成如下二步操作: 1、在web页面中添加上传输入项 2、在servlet中读取上传文件的数据,并保存到本地硬盘中。 如何在web页面中添加上传输入项? 标签用于在web页面中添加文件上传输入...
  • ctf-web:关于文件上传漏洞的深入研究

    万次阅读 2020-10-14 18:12:15
    上次我们研究了关于文件上传的漏洞,这次我们研究的内容属于上节课的补充内容,关于文件上传的绕过与防御. 怎么说呢,算是一种锻炼吧. 因为下个月有个awd的比赛,因此最近会经常发一些关于web的内容. 其实我还是挺慌的,...
  • Web文件上传方法总结大全 上传文件与与上传数据区别 上传数据主要指json等简单字符串,上传文件指的是上传word、excel图片等。在上传数据的时候enctype默认为第一个application/x-www-form-urlencoded,而上传...
  • 详解网站WEB日志格式

    万次阅读 2013-02-18 09:50:16
    它主要记录了网站访问记录数据内容,是网站分析和网站数据仓库的数据基础来源,而网站分析和数据分析也将对SEO产生一定的影响,所以了解WEB日志的格式和组成将有利于我们更好地进行网站数据的收集、处理和分析,从而...
  • Java Web工程中的web.xml配置文件

    千次阅读 2018-12-18 08:57:01
    Java Web工程中的web.xml配置文件 前言 1. xml文件 xml文件:Extentsible Markup Language即可扩展标记语言,是用来定义其它语言的一种元语言,其前身是SGML(标准通用标记语言)。xml文件是互联网数据传输的重要...
  • Web Handler 文件 ashx

    千次阅读 2012-11-13 21:09:37
     .ashx 文件用于写web handler的。.ashx文件与.aspx文件类似,可以通过它来调用HttpHandler类,它免去了普通.aspx页面的控件解析以及页面处理的过程。其实就是带HTML和C#的混合文件。  .ashx文件适合产生...
  • webarchive文件转换成htm文…

    千次阅读 2017-05-04 10:32:13
    原文地址:webarchive文件转换成htm文件作者:xhbaxf Mac OS X系统带有文件转换功能,可以把webarchive文件变成html文件。方法是:   Step 1: 建立一个文件夹,把你的webarchive文件放入文件夹内。 Step 2 在...
  • 【何为配置文件】  百度百科解释:用户配置文件就是在用户登录电脑时,或是用户在使用软件时,软件系统为用户所要加载所需环境的设置和文件的集合。它包括所有用户专用的配置设置,如程序项目、屏幕颜色、网络连接...
  • Web字体逐渐成为话题,这项让未来Web更加丰富多彩的技术拥有多种实现方案,其中之一是通过@font-face属性在网页中嵌入自定义字体,主流的浏览器都支持这项技术,本文介绍主要的几种Web字体格式及各浏览器兼容情况。...
  • Markdown文件是当下比较流行的内容展示格式,简书、github等都推荐使用md文件来展示内容。本文讨论web页面如何加载和展示markdown md文件,并提供了一个来自有道的markdown web编辑、预览器。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 782,848
精华内容 313,139
关键字:

web文件格式