关于HTTP POST上传文件时服务端的接收问题

wudeaaa wudeaaa 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
HTTP POST方法上传文件,客户端是socket发送,服务端Servlet接收,请求报文头如下:

POST /upload.jsp HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7da29f2d890386
Host: 192.9.200.246:8080
Content-Length: 1516663
Connection: Keep-Alive
Cache-Control: no-cache

-----------------------------7da29f2d890386
Content-Disposition: form-data; name="FileData"; filename="D:\set.pdf"
Content-Type: application/pdf

%PDF-1.6
%����
1 0 obj<</Type/Page/Contents 2 0 R/Parent 3 0 R/Resources 4 0 R/CropBox[0 0 595.22 842]/MediaBox[0 0 595.22 842]/Rotate 0>>
endobj
4 0 obj<</ColorSpace<</Cs6 5 0 R>>/ExtGState<</GS1 6 0 R>>/ProcSet[/PDF/Text]/Font<</F1 7 0 R/F3 8 0 R/TT3 9 0 R/F2 10 0 R>>>>
endobj
2 0 obj <</Filter/FlateDecode/Length 1887>>stream
-----------------------------7da29f2d890386--

服务端接收如下

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final int NONE=0;
final int DATAHEADER=1;
final int FILEDATA=2;
final int FIELDDATA=3;
//将请求消息的实体送到b变量中
int TotalBytes=request.getContentLength();
byte[] b=new byte[TotalBytes];
String contentType=request.getContentType();//请求消息类型
String fieldname=""; //表单域的名称
String fieldvalue=""; //表单域的值
String filename=""; //文件名
String boundary=""; //分界符
String lastboundary=""; //结束符
int filesize=0; //文件长度
Hashtable<String, String> formfields=new Hashtable<String, String>();
int pos=contentType.indexOf("boundary=");
//String fileID; //上传的文件ID
if(pos!=-1) //取得分界符和结束符
{
pos+="boundary=".length();
boundary="--"+contentType.substring(pos);
lastboundary=boundary+"--";
}
int state=NONE;
//得到数据输入流reqbuf
DataInputStream in=new DataInputStream(request.getInputStream());
in.readFully(b);
in.close();
String reqContent=new String(b,"UTF-8");//********如果文件过大会造成内容溢出,但是如果没有读入全部,又无法过滤消息头而得到内容字节数组*********/
BufferedReader reqbuf=new BufferedReader(new StringReader(reqContent));
boolean flag=true;
int i=0;
while(flag==true)
{
String s=reqbuf.readLine();
if((s==lastboundary)||(s==null)) break;
switch(state)
{
case NONE:
if (s.startsWith(boundary))
{
state=DATAHEADER;
i+=1;
}
break;
case DATAHEADER:
pos=s.indexOf("filename=");
if (pos==-1)
{ //将表单域的名字解析出来
pos=s.indexOf("name=");
pos+="name=".length()+1;
s=s.substring(pos);
int l=s.length();
s=s.substring(0,l-1);
fieldname=s;
state=FIELDDATA;
}
else
{ //将文件名解析出来
String temp=s;
pos=s.indexOf("filename=");
pos+="filename=".length()+1;
s=s.substring(pos);
int l=s.length();
s=s.substring(0,l-1);
pos=s.lastIndexOf("\\");
s=s.substring(pos+1);
filename=s;
//从字节数组中取出文件数组
pos=byteIndexOf(b,temp,0);
b=subBytes(b,pos+temp.getBytes().length+2,b.length);//去掉前面的部分
s=reqbuf.readLine();
b=subBytes(b,s.getBytes().length+4,b.length);
pos=byteIndexOf(b,boundary,0);
b=subBytes(b,0,pos-1);
File f=new File(formfields.get("FilePath")+"\\"+filename); //写入文件
DataOutputStream fileout=new DataOutputStream(new FileOutputStream(f));
fileout.write(b,0,b.length-1);
filesize=b.length-1;
state=FILEDATA;
}
break;
case FIELDDATA:
s=reqbuf.readLine();
fieldvalue=s;
formfields.put(fieldname,fieldvalue);
state=NONE;
break;
case FILEDATA:
while((!s.startsWith(boundary))&&(!s.startsWith(lastboundary)))
{
s=reqbuf.readLine();
if (s.startsWith(boundary))
{
state=DATAHEADER;
break;
}
}
break;
}
}
}

问题:服务端既想一下读到全部字符串(用来解析消息头,然后过滤掉得到字节数组),又想保存完整的字节数组byte[] b(b用来去除消息头后写入文件),如果文件过大,这里就会造成内存溢出,但是如果没有一下子读完,后面又无法解析,大家看一下有没有更好的解决方法。

DataInputStream in=new DataInputStream(request.getInputStream());
in.readFully(b);
in.close();
String reqContent=new String(b,"UTF-8");//会造成内存溢出
...全文

相关推荐

Spy-http-post-server-and-client.rar_http upload_post http_spy

file.php服务端"则是部署在服务器端的脚本,负责接收POST请求,解压并存储上传的文件。PHP是一种广泛使用的服务器端脚本语言,尤其适合处理这种Web交互任务。

小波思基

C#中使用HTTP POST上传文件的综合指南

在当今的网络应用中,文件上传是用户交互不可或缺的一部分。通过HTTP POST请求方式上传文件是实现这一功能的一种常见技术手段。特别是对于C#开发者,熟悉如何使用HTTP协议以及相关类库如HttpClient和WebClient来处理文件上传是基础且重要的技能。本章将为您提供一个概览,通过理解HTTP POST上传文件的工作原理和流程,帮助开发者更加高效地实现文件上传功能。我们将从HTTP POST请求的工作原理开始讲起,涉及请求与响应模型、MIME类型和请求头的构造。

蓉蓉蓉蓉

android批量文件上传(附服务端Demo)

在实际应用中,还需要考虑错误处理、进度显示、多线程上传等问题。确保服务端有足够的处理能力,并对上传的文件大小、类型进行限制,以防止安全问题。

杨景文Blog

图片从本地上传服务端

**传输**:转换后的数据可以通过HTTP或HTTPS协议发送到服务端。一般使用POST请求,将图片数据放在请求体中。如果文件较大,可能需要考虑分块上传或使用FormData对象。4.

LL继续前进

okhttp上传文件包含服务端(java)

,以及Java Servlet服务端接收并保存文件的过程。

heshuaihe
评论 19
收藏 已收藏
分享
返回顶部
wudeaaa
Web 开发 81,108 成员 341,721 内容