Java中用Socket实现HTTP文件上传实例
发布时间 - 2026-01-11 00:36:06 点击率:次我想做过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:\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实现文件上传功能
# 上传
# 做过
# 这一行
# 自己的
# 上传文件
# 都是
# 增加了
# 我想
# 是在
# 我在
# 也会
# 又有
# 下了
# 作了
# 在对
# 定了
# 试着
# 来实现
# 这里下载
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在香港服务器上快速搭建免备案网站?
电商网站制作价格怎么算,网上拍卖流程以及规则?
jQuery validate插件功能与用法详解
香港服务器网站推广:SEO优化与外贸独立站搭建策略
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
Laravel如何自定义分页视图?(Pagination示例)
如何在IIS管理器中快速创建并配置网站?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
EditPlus中的正则表达式 实战(4)
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
C#如何调用原生C++ COM对象详解
如何续费美橙建站之星域名及服务?
Android GridView 滑动条设置一直显示状态(推荐)
php json中文编码为null的解决办法
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
,南京靠谱的征婚网站?
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
如何彻底删除建站之星生成的Banner?
Python数据仓库与ETL构建实战_Airflow调度流程详解
如何用虚拟主机快速搭建网站?详细步骤解析
悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
JS去除重复并统计数量的实现方法
北京网站制作公司哪家好一点,北京租房网站有哪些?
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
如何在宝塔面板中修改默认建站目录?
MySQL查询结果复制到新表的方法(更新、插入)
HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
新三国志曹操传主线渭水交兵攻略
Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理
如何在万网利用已有域名快速建站?
三星网站视频制作教程下载,三星w23网页如何全屏?
IOS倒计时设置UIButton标题title的抖动问题
如何撰写建站申请书?关键要点有哪些?
简历在线制作网站免费版,如何创建个人简历?
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】

