栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

在做文件上传之前我们需要先了解一下HTTP POST的附件上传协议。HTTP附件上传协议是RFC1876协议,RFC1876协议是在HTTP协议的基础上为INPUT标签增加了file属性,同时限定了Form的method必须为POST,ENCTYPE必须为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:LearnVideofileLoad这个目录下了。示例如下:

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/146860.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号