文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-05-31 16:56

关注

我想做过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把每种实体进行了分割。具体的看下图:

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

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

我在前面的文章中写过创建一个自己的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();   } } 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯