全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Java中用Socket实现HTTP文件上传实例

我想做过web开发的程序员大部分都做过文件上传的功能,大多数时候我们都是借助于commons-fileupload这样的jar包实现的。下面我试着通过读取Socket的输入流来实现一个文件上传的功能。

在做文件上传之前我们需要先了解一下HTTP POST的附件上传协议。HTTP附件上传协议是RFC1876协议,RFC1876协议是在HTTP协议的基础上为INPUT标签增加了file属性,同时限定了Form的method必须为POSTENCTYPE必须为multipart/form-data。RFC1867协议对HTTP头作了适当地变更,content-type头由以前的:content-type:application/x-www-form-urlencoded变为content-type:multipart/form-data;+空格+boundary=字符串。RFC1867增加了文件上传得功能,而上传文件内容自然也会被加入到HTTP的实体中。现在因为既有HTTP一般的参数实体,又有上传文件的实体,所以用boundary把每种实体进行了分割。具体的看下图:

接下来就开始我们的代码部分吧。

我在前面的文章中写过创建一个自己的Web服务器,现在我们的重点要放在对socket的输入流的解析中。具体代码如下:

public void parseRequest() { 
  LineNumberReader br = new LineNumberReader(new InputStreamReader(inputStream)); 
  StringBuffer sb = new StringBuffer(); 
  String str = null; 
  try { 
    //读取请求行 
    String requestLine = br.readLine(); 
    if (!StringUtils.isEmpty(requestLine)) { 
      sb.append(requestLine); 
      String[] reqs = requestLine.split(" "); 
      if (reqs != null && reqs.length > 0) { 
        if ("GET".equals(reqs[0])) { 
          method = "GET"; 
        } else { 
          method = "POST"; 
        } 
      } 
    } 
    //读取请求头 
    while ((str = br.readLine()) != null) { 
      if ("".equals(str)) { 
        break; 
      } 
      if (!StringUtils.isEmpty(str)) { 
        if (str.indexOf(":") > 0) { 
          String[] strs = str.split(":"); 
          headers.put(strs[0].toLowerCase(), strs[1].trim()); 
        } 
      } 
      sb.append(str).append("\n"); 
    } 
    //POST请求,Content-type为 multipart/form-data 
    String contentType = null; 
    if ("POST".equals(method) && ((contentType = headers.get("content-type")) != null 
        && headers.get("content-type").startsWith("multipart/form-data"))) { 
      //文件上传的分割位 这里只处理单个文件的上传 
      String boundary = contentType.substring(contentType.indexOf("boundary") + 
          "boundary=".length()); 
      //解析消息体 
      while ((str = br.readLine()) != null) { 
        //解析结束的标记 
        do { 
          //读取boundary中的内容 
          //读取Content-Disposition 
          str = br.readLine(); 
          //说明是文件上传 
          if (str.indexOf("Content-Disposition:") >= 0 && str.indexOf("filename") > 0) { 
            str = str.substring("Content-Disposition:".length()); 
            String[] strs = str.split(";"); 
            String fileName = strs[strs.length - 1].replace("\"", "").split("=")[1]; 
            System.out.println("fileName = " + fileName); 
            //这一行是Content-Type 
            br.readLine(); 
            //这一行是换行 
            br.readLine(); 
            //正式去读文件的内容 
            BufferedWriter bw = null; 
            try { 
              bw = new BufferedWriter(new OutputStreamWriter(new 
                  FileOutputStream("G:\\LearnVideo\\fileLoad" + 
                  File.separator + fileName), "UTF-8")); 
              while (true) { 
                str = br.readLine(); 
                if (str.startsWith("--" + boundary)) { 
                  break; 
                } 
                bw.write(str); 
                bw.newLine(); 
              } 
              bw.flush(); 
            } catch (Exception e) { 
 
            } finally { 
              if (bw != null) { 
                bw.close(); 
              } 
            } 
          } 
          if (str.indexOf("Content-Disposition:") >= 0) { 
            str = str.substring("Content-Disposition:".length()); 
            String[] strs = str.split(";"); 
            String name = strs[strs.length - 1].replace("\"", "").split("=")[1]; 
            br.readLine(); 
            StringBuilder stringBuilder = new StringBuilder(); 
            while (true) { 
              str = br.readLine(); 
              if (str.startsWith("--" + boundary)) { 
                break; 
              } 
              stringBuilder.append(str); 
            } 
            parameters.put(name, stringBuilder.toString()); 
          } 
        } while (("--" + boundary).equals(str)); 
        //解析结束 
        if (str.equals("--" + boundary + "--")) { 
          break; 
        } 
      } 
    } 
    //System.out.println(sb.toString()); 
    //获取URI 
    uri = StringUtils.parserUri(sb.toString(), " "); 
    int flag = -1; 
    //说明有参数 
    if ((flag = uri.indexOf('?')) >= 0) { 
      String oldUri = uri; 
      uri = uri.substring(0,flag); 
      String parameterPath = oldUri.substring(flag+1); 
      String[] parameter = parameterPath.split("&"); 
      if (parameter != null && parameter.length > 0) { 
        for (int i = 0; i < parameter.length; i++) { 
          String str1 = parameter[i]; 
          if((flag = str1.indexOf('=')) >= 0){ 
            String key = str1.substring(0,flag); 
            String value = str1.substring(flag+1); 
            parameters.put(key,value); 
          }else{ 
            parameters.put(str,null); 
          } 
        } 
      } 
    } 
  } catch (IOException e) { 
    e.printStackTrace(); 
  } 
} 

我们启动自己创建的Web服务器,然后在浏览器中输入:http://localhost:8004/static/uploadPage.html,页面如下:

选择我们要上次的文件,然后点击上传按钮,我们会发现我们的功能已经被上传到G:\LearnVideo\fileLoad这个目录下了。示例如下:

完整的代码请从这里下载:FullStackTraining_jb51.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# socket实现文件上传  # java  # socket实现http  # socket  # http  # 文件上传  # Java 基于TCP Socket 实现文件上传  # Socket+JDBC+IO实现Java文件上传下载器DEMO详解  # Java Socket+mysql实现简易文件上传器的代码  # JavaWeb实现文件上传下载功能实例解析  # JAVA中使用FTPClient实现文件上传下载实例代码  # java实现FTP文件上传与文件下载  # JavaWeb实现文件上传下载功能实例详解  # java web图片上传和文件上传实例  # Java实现文件上传至服务器的方法  # java使用Socket实现文件上传功能  # 上传  # 做过  # 这一行  # 自己的  # 上传文件  # 都是  # 增加了  # 我想  # 是在  # 我在  # 也会  # 又有  # 下了  # 作了  # 在对  # 定了  # 试着  # 来实现  # 这里下载 


相关文章: 清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?  定制建站方案优化指南:企业官网开发与建站费用解析  Python如何创建带属性的XML节点  焦点电影公司作品,电影焦点结局是什么?  建站之星ASP如何实现CMS高效搭建与安全管理?  香港服务器选型指南:免备案配置与高效建站方案解析  实现点击下箭头变上箭头来回切换的两种方法【推荐】  宝塔建站助手安装配置与建站模板使用全流程解析  广州网站建站公司选择指南:建站流程与SEO优化关键词解析  网站制作企业,网站的banner和导航栏是指什么?  自助网站制作软件,个人如何自助建网站?  如何快速配置高效服务器建站软件?  建站之星安装路径如何正确选择及配置?  ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?  微信小程序 五星评分(包括半颗星评分)实例代码  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  如何通过商城免费建站系统源码自定义网站主题?  如何配置IIS站点权限与局域网访问?  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  网站制作知乎推荐,想做自己的网站用什么工具比较好?  番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?  如何快速搭建FTP站点实现文件共享?  沈阳制作网站公司排名,沈阳装饰协会官方网站?  定制建站模板如何实现SEO优化与智能系统配置?18字教程  威客平台建站流程解析:高效搭建教程与设计优化方案  重庆网站制作公司哪家好,重庆中考招生办官方网站?  南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?  宝塔建站后网页无法访问如何解决?  建站主机功能解析:服务器选择与快速搭建指南  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  ,制作一个手机app网站要多少钱?  如何配置支付宝与微信支付功能?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  如何选购建站域名与空间?自助平台全解析  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  广东专业制作网站有哪些,广东省能源集团有限公司官网?  如何在IIS7上新建站点并设置安全权限?  定制建站是什么?如何实现个性化需求?  如何快速查询网址的建站时间与历史轨迹?  大连网站设计制作招聘信息,大连投诉网站有哪些?  制作网站的过程怎么写,用凡科建站如何制作自己的网站?  c++ stringstream用法详解_c++字符串与数字转换利器  Swift中循环语句中的转移语句 break 和 continue  如何选择PHP开源工具快速搭建网站?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  C#怎么使用委托和事件 C# delegate与event编程方法  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  宿州网站制作公司兴策,安徽省低保查询网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。