http文件上传的总结
来源:互联网 发布:淘宝账户被限制登录了 编辑:程序博客网 时间:2024/06/05 07:34
7.21
最近有人问我怎么进行文件上传,然后我就想到平常我们后台接受的文件要么就用各种文件上传接受jar包直接操作,要么就用struts2直接接收成File(话说File并不能指向内存中的文件内容,那这个File到底存在哪里是个问题)。所以我就想看看文件上传的原理,然后自己去实现下文件接收。
一、http文件报文的格式
-----------------------------92901418813201Content-Disposition: form-data; name="title"asd-----------------------------92901418813201Content-Disposition: form-data; name="image"; filename="1320140315.JPG"Content-Type: image/jpeg文件-----------------------------92901418813201--
这是我找到的某http报文,这是request获取的inputstream直接获得的报文,还有request中的头部有两个重要的信息:
Content-Type:multipart/form-data;boundary=—————————7d33a816d302b6
Content-Length: 424,
解释下 Content-Type中的boundary是当type是multipart时特有的,用来分割内容,据说是自动生成,并且报文内容中不会有和他一样的字符串。
Content-Length是刚刚request获得的inputstream的报文的长度,是总长度
然后报文中格式是:
--boundary+\r\n //注意http报文中换行是\r\n文件头信息+\r\n(可能还有头信息需要换行)\r\n信息内容+\r\n--boundary||如果是报文结尾的话就是--boundary--
所以根据这个报文格式进行处理,就可以获得文件了。
二、代码
我的截取方法很简单,现将报文接收到byte[]中,再转成String,按照boundary截取后再按格式截取,就获得文件,再转成byte[],
这里我被编码方式坑了一次,以前都没注意过编码方式的问题
package com.yc.servlet;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Userservlet extends HttpServlet { private static final long serialVersionUID = 1L; String Path = "E:/"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { Map<String, byte[]> map = parse(request); Set<String> filenamesset = map.keySet(); // 遍历获得所有文件名 for (String name : filenamesset) { // 对文件名遍历 进行存储 File tempfile = new File(Path + new Date().getTime() + name); FileOutputStream out = new FileOutputStream(tempfile); out.write(map.get(name)); // 读入到磁盘, out.flush(); out.close(); } } /* * * map 的存储: 只存储文件 文件名就是键 文件byte[] 是值 这个方法过滤不是multipart的报文 */ public Map<String, byte[]> parse(HttpServletRequest request)// throws IOException { int length = request.getContentLength(); String Type = request.getContentType(); String boundary = Type.substring(Type.indexOf("boundary") + 9,Type.length());//获得boundary InputStream in = request.getInputStream(); // 获取输入流 if (Type.startsWith("multipart/form-data;")) { // 判断是多数据上传 return subbyte(in, boundary, length); } else { throw new RuntimeException("非多数据情况"); } } /* * 这个方法进行截取 * */ public Map<String, byte[]> subbyte(InputStream in, String boundary, int length) throws IOException { Map<String, byte[]> map = new HashMap<String, byte[]>(); byte[] buffer = new byte[length]; in.read(buffer); String contentbuffer = new String(buffer, "iso8859-1");//为什么是iso8859-1那,这里我被坑了很久,下一篇写字符编码讲解为什么 System.out.println(contentbuffer); String[] contents = contentbuffer.split("(" + "--" + boundary + "--"+ ")|(" + "--" + boundary + ")");//按照 boundary分割 for (String c : contents) { if (c.indexOf("filename") != -1) { String name = c.substring(c.indexOf("filename=") + 10,c.indexOf("\"", c.indexOf("filename=\"") + 10)); String file1 = c.substring(c.indexOf("\r\n\r\n") + 4); file1 = file1.substring(0, file1.length() - 2); byte[] file2 = file1.getBytes("iso8859-1"); map.put(name, file2); } } return map; }}
这个处理方法并不好,我觉得应该还有某种更好的流操作,但是我流操作学的并不好,找不到一个可以进行截取的流,等我复习了流操作说不定可以改善下
0 0
- http文件上传的总结
- http上传文件的原理
- http 上传文件的方法
- HTTP 文件上传的基本原理
- HTTP上传文件的格式
- HTTP 文件上传的基本原理
- HTTP上传文件的boundary
- HTTP 文件上传的基本原理
- 总结文件上传的问题
- servlet的文件上传总结
- HTTP POST的文件上传问题
- 使用http 上传文件的原理
- 基于 HTTP POST multipart 的文件上传
- java的http协议文件上传 (一)
- java的http协议文件上传 (二)
- java的http协议文件上传 (三)
- HTTP协议上的文件上传
- 使用http 上传文件的原理
- Qt之坐标系统
- C# 索引器
- Java使用DOM解析xml文件
- Windows下从零开始学习nodejs4.X+express4.X开发--(3)创建服务器
- 分享抓取网站静态资源的工具
- http文件上传的总结
- AsyncTask和Handler的优缺点比较
- Core Data
- fail-fast机制
- 即时通讯实现方式(采用openfire和asmack方式)
- Swift Cocoapods use_frameworks!(报error Bridging header 'XXXXXX-Bridging-Header.h' does not exist 错误)
- 如何引入数据挖掘
- React Native backgroundColor 的颜色值
- 自动化测试架构设计