文件上传中的一个致命异常

指尖上的行者 2012-01-10 03:11:06
我通过struts1+apache的fileUpload实现文件上传功能,但是因为要考虑并发的问题,所以我加入了线程池对其进行管理,当把代码复制到run()方法中时,它提示要把request与response全部设成final类型,之后,问题就接踵而来了。在执行到:
List <FileItem> fileItems = upload.parseRequest(request);这一句时就报异常了,如下:
org.apache.commons.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is null
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:294)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:116)
at com.dtcloud.action.UploadAction$1.run(UploadAction.java:81)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)


在网上找了半天都没找到想对应的回答,我们做的是移动开发,后台是通过手机端访问的。在没加线程池的时候访问是正常的,知道的朋友还望指点一二,谢谢啦!!!
...全文
4236 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
johnsongya 2014-02-27
  • 打赏
  • 举报
回复
得,都2年过去了,有人应吗
johnsongya 2014-02-27
  • 打赏
  • 举报
回复
那个<s ......>在哪找啊
ilovefzq 2012-01-13
  • 打赏
  • 举报
回复
一班的web服务器中,如tomcat都是有线程机制的,不用考虑并发时的问题,要考虑也应该是高并发时的性能,这就与数据结构,数据库设计,代码优化有关,跟线程无关了
MiceRice 2012-01-13
  • 打赏
  • 举报
回复
所以,楼主啊,问题跟我说的是一致的。

你看你最后的两端代码:
threadPool.execute(new Runnable() {
...
});
return null;

当主线程利用threadPool启动了子线程去处理文件上传后,你的主线程其实就 return null; 了,那么中间件(Tomcat或JBOSS,不知道你用的是啥)就会把整个请求全部结束掉了,也就是request和response都会结束掉。那么你的子线程当然什么东西都干不了了。

你可以尝试在return null;这句话的前面增加
try {threadPool.awaitTermination(60, TimeUnit.SECONDS);} catch (Exception ex){}
看看问题是否迎刃而解?
但其实这就已经丧失了你最开始的设计初衷了。


但,总的来说,楼主,我认为你过度设计了。
中间件的整个设计本身已经有线程池的概念,并且也已经很好的支持了并发需求,你是不能企图用自己的线程池去接管它的工作的。原则上来说,J2EE开发,是不建议有类似创建子线程的代码的。

我认为你没有任何合理的理由去这么做。
如果你认为你有,那么请说出来,我们探讨下是否有更合理的模式,而不是采用这种方式。
若鱼1919 2012-01-13
  • 打赏
  • 举报
回复

org.apache.commons.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is null


form表单加上:enctype="multipart/form-data"

指尖上的行者 2012-01-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ldh911 的回复:]

没搞懂楼主是怎么用线程池去对上传做并发管理的。常规分析如下:

浏览器提交文件后,服务器会有一个线程负责处理这个请求,我们称其为“主线程”。

现在你启动一个子线程去接管这个请求,继续完成下载工作,但你的主线程在干啥呢?

我觉得你的主线程只能是在傻傻的等你启动的子线程完成任务吧?因为你的主线程不能返回(结束)啊,你一返回,中间件就把这个请求彻底结束了,你就没啥好玩的了。

所以……
[/Quote]
我这也是这么认为的,之所以要使用线程池是因为考虑到高并发的问题。
谢谢其他朋友的答复,你们说的那个因为缺少数据类型而导致错误的这种情况确实存在,但是我这里不是因为那个原因。当我不使用线程池的时候就没问题啦,以下是我的源码:

public ActionForward execute(ActionMapping mapping, ActionForm form,
final HttpServletRequest request, final HttpServletResponse response)
throws Exception {

ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool();

Properties config = getProperty(config_path);
if (config == null) {
config = loadConfig(config_path);
}
final String tempDir = config.getProperty("tempDir");//存储图片的临时目录
final String photoDir = config.getProperty("photoDir");//照片目录
final String photoUrl = config.getProperty("photoUrl");//照片的URL
final String memorySize = config.getProperty("memorySize");//内存缓冲大小
final String sizeMax = config.getProperty("sizeMax");//文件允许的最大值
final String outTime = config.getProperty("outTime");//设置线程在终止前可以保持空闲的时间限制
threadPool.setKeepAliveTime(Long.parseLong(outTime), TimeUnit.SECONDS);

final PrintWriter out = response.getWriter();
threadPool.execute(new Runnable() {
public void run() {
try {
// 创建磁盘工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存缓冲大小
factory.setSizeThreshold(Integer.parseInt(memorySize));
// 设置临时目录
File file = new File(tempDir);
if(!file.exists()){
file.mkdir();
}
factory.setRepository(file);
// 创建处理工具
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置最大允许的尺寸
int setFileSize = Integer.parseInt(sizeMax);
int fileSize = request.getContentLength();
upload.setSizeMax(setFileSize);

if (fileSize <= setFileSize) {
// 解析
String contentType = request.getContentType();//multipart/form-data; boundary=p89nCm2-NdBgJFcZIdCixdGVgEbKHP
if(contentType == null && "".equals(contentType)){
out.print("File Upload Error");
return;
}
List<FileItem> fileItems = upload.parseRequest(request);
Iterator<FileItem> iter = fileItems.iterator();

for (; iter.hasNext();) {

FileItem fileItem = (FileItem) iter.next();
// 判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false
if (fileItem.isFormField()) {
// 当前是一个表单项
out.print("form field : "
+ fileItem.getFieldName() + ", "
+ fileItem.getString());
} else {
// 当前是一个上传的文件
String fileName = fileItem.getName();
File fileDir = new File(photoDir + fileName);
fileItem.write(fileDir);

out.print(photoUrl + fileName);
}
}
} else {
out.print("你上传的文件过大");
}
} catch (Exception e) {
e.printStackTrace();
out.print("File Upload Fail!");
}
}
});
return null;
}
anhy 2012-01-12
  • 打赏
  • 举报
回复
估计是request过期了
huangxw000 2012-01-12
  • 打赏
  • 举报
回复
异常说是请求头文件信息是空,你就给一句源码,很难猜测哪里出问题吧。
指尖上的行者 2012-01-12
  • 打赏
  • 举报
回复
有知道的么???为什么将执行代码放入线程池中request就有问题啦???
我系大红花 2012-01-12
  • 打赏
  • 举报
回复
<s:form action="Upload" method="post" enctype="multipart/form-data">
加这句enctype="multipart/form-data";
如果不行,请发详细点的代码上来
一般是这个问题,因为前几天我也遇到这个问题
MiceRice 2012-01-12
  • 打赏
  • 举报
回复
没搞懂楼主是怎么用线程池去对上传做并发管理的。常规分析如下:

浏览器提交文件后,服务器会有一个线程负责处理这个请求,我们称其为“主线程”。

现在你启动一个子线程去接管这个请求,继续完成下载工作,但你的主线程在干啥呢?

我觉得你的主线程只能是在傻傻的等你启动的子线程完成任务吧?因为你的主线程不能返回(结束)啊,你一返回,中间件就把这个请求彻底结束了,你就没啥好玩的了。

所以,我对于楼主对上传还用了线程池去做并发管理,表示相当没看懂。
控制端采用IOCP模型,数据传输采用zlib压缩方式稳定快速,上线数量无上限,可同时控制上万台主机控制端自动检测CPU使用率调整自己的工作线程, 稳定高效宿主为svchost以系统服务启动,有远程守护线程,上线间隔为两分钟。心跳包机制防止意外掉线..支持HTTP和DNS上线两种方式自动恢复SSDT(这功能干什么,大家都知道,免杀自己做吧),安装本程序需要管理员权限控制端279K,返朴归真的界面,生成的服务端无壳,106 K,EXE内的资源用UPX压缩, 可安装多个服务端其它细节方面的功能大家自己去发现吧功能:文件管理 完全仿Radmin所写, 文件、文件夹批量上传、删除、下载、创建、重命名屏幕监视 扫描算法速度最快可达到120帧/秒,差异算法适合网络极差的情况下传输,传输速度快,控制屏幕,发送Ctrl+Alt+Del,剪贴板操作,7种色彩显示方式,等......键盘记录 可记录英文信息,离线记录(记录上限50M)功能远程终端 一个简单shell系统管理 进程管理,窗口管理,拨号上网密码获取视频查看 查看远程摄像头,快照,录像,压缩等功能...语音监听 监听远程语音,同时也可以把本地语音传送给远程,进行语音聊天,GSM610压缩方式,传输流畅会话管理 注销,重启,关机,卸载服务端其它功能 下载执行指定URL的程序,隐藏或者显示访问指定网址,清除系统日志地址位置 将IP数据库文件QQWry.Dat放置程序同目录下即可显示地理位置集群控制 可同时控制多台主机,同时打开视频监控等管理功能备注功能 .........注: 软件不断更新,有什么意见大家多多提,偶看可以的就采纳.....gh0st的成长,离不开大家的帮助.2008/1/27 11:16 : 优化了屏幕传输算法,CPU利用率更低2008/1/27 16:06 : 驱动以资源方式写入安装文件跟DLL文件,优化屏幕传输2008/1/27 17:26 : 修正驱动安装时的一个Bug2008/1/28 05:28 : 服务端安装强化,加入服务检测,守护线程强化,加入禁用监视,顺便做了下免杀2008/1/29 12:47 : 改变服务端安装启动方式,隐藏服务,去掉驱动程序和守护线程,感谢Lzx无私的帮助...2008/1/29 16:12 : 修正键盘记录重复问题,优化服务端上线方式2008/1/30 04:11 : 修正服务端网络内核的一个导致异常的Bug,优化服务端大小到100K2008/1/31 01:28 : 重写服务端网络内核,加入数据包验证,及重发功能,更加稳定2008/1/31 11:36 : 修正服务端网络内核一个导致数据包混乱的问题,加入帧速限制,传输不稳定的情况从此消失...2008/2/01 10:54 : 主动防御功能加强,过卡巴全监控,瑞星,Kis6,Kis7,Norton,ZoneAlarm,江民2008等杀毒软件.下个版本准备过所有杀软的主动...期待吧.2008/2/01 14:18 : 加入服务端异常处理,更新稳定,请各位帮助测试..2008/2/01 15:39 : 修正服务端删除后不能安装的致命错误2008/2/01 23:35 : 改写了下服务端一些函数,增加稳定性,春季过后重写服务端吧,简洁下程序.2008/2/02 19:51 : 修正服务端视频监控功能的一些BUG2008/2/03 00:40 : 屏幕监控加入显示远程鼠标功能2008/2/05 16:46 : 重写屏幕传输算法,屏幕传输更快,控制更稳定..2008/2/05 23:45 : 还是网络内核跟屏幕传输方面,只求更快,不求最快,前版本屏幕传输有问题,旧版本不能上线,请用最新版本...2008/2/06 17:32 : 服务端做了些优化,加入跟踪远程光标的功能,旧版本不能上线,请用最新版本2008/2/07 00:57 : 改了些服务端,没事优化优化,准备过完年,大整一下,新年快乐...2008/2/07 16:02 : 没事加了个托盘功能,做了些代码优化,一个人过年,有点郁闷...2008/2/07 20:42 : 修正服务端一个句柄泄漏的问题..2008/2/08 22:08 : 全面优化了下服务端,新加了备注功能.2008/2/09 22:58 : 修正一些大家提到的问题,Gh0st RAT Beta 2.1 发布2008/2/11 00:18 : 修正服务端安装的一个BUG,静心研究ACE,暂停更新...................2008/2/17 16:14 : 保存配置文件,服务端支持socks5代理上线,加入下载更新功能,屏幕控制加入,黑屏,锁定等功能2008/2/20 10:49 : 应大家要求,看了看江民2008的垃圾主动,连注册表都没,随便改了下服务端,过江民2008主动.其它有啥主动过不了的,抓图,我抽空解决2008/2/20 09:26 : 改了下服务端一些网络方面的东西,看对2003掉线情况是否有效,望大家测试,多谢了.2008/2/21 15:43 : 服务端掉线问题,重启后不上线问题,测试版本,请大家测试2008/2/22 19:47 : 解决重启后服务端不上线问题,加强对抗主动防御的功能2008/2/23 17:11 : 全面优化了下服务端,加强稳定性,请大家测试2008/2/23 19:03 : 修正视频监视的一个小BUG2008/2/24 01:55 : 文件管理加入本地和远程运行功能,优他了部分代码,旧版本不会上线,请用新版本2008/2/24 12:56 : 修正文件管理一个低级错误,下载更新的一个错误2008/2/26 00:00 : 完美解决重复安装,重复上线问题,发布gh0st2.5,2008/3/20 21:52 : 服务端全部优化一遍,加入语音监听,屏幕监视的算法优化...2.6发布2008/3/24 18:52 : 抽出时间来,视频采用选择性压缩,强大的H263压缩算法,100:1的压缩率,加入快照功能...2.7发布2008/3/25 02:42 : 修正网友提出的问题,如下载网址输入有限制等,一些人性化细节方面的修改...2008/3/26 05:01 : 修正视频的一个解码器处理的BUG,加入智能选择编码器,调整屏幕传输4位调色板....2.712008/3/28 11:01 : 修正视频对一些摄像头不兼容的bug,加入录像功能,修正服务端一个导致整体稳定性的bug,此版本历来最稳定的...不与前版本相兼容2008/4/16 01:28 : 屏幕算法加入热点跟踪,心跳包方式改用保活方式,优化网络内核,实际压缩测试2003服务器,超过4万台同时上线,服务端生成方式为文件尾追加配置信息,壳为upackDLL资源也用upack加了壳,脱壳后,可自由更改,导入,不影响使用,软件标题日期,不做改变,2.8是个好数字,改动了一些其它细节方面的问题2008/4/18 23:44 : 完美解决键盘记录重复记录等问题.2008/5/10 20:47 : 修正2003 R2下下载更新或者下载执行时造成服务器崩溃的BUG,以及更新后黑屏的BUG,发布3.02008/5/11 18:10 : 超时改为3分钟,采用双保活机制度,防止网络异常导致出现死连接, 致使务端无法上线的BUG,请不要再用旧版本,最近更新的都是一些致命问题2008/5/14 00:26 : 修正一些摄像头无法显示的BUG,发布3.2版本2008/5/16 02:48 : 更改服务端安装方式,以前的安装方式很不稳定,现在的更加稳定,在多种操作系统测试通过,可以自定义服务显示名称,描述....3.42008/5/17 15:03 : 换心跳方式,对付任何情况下产生的死连接,安装删除更加稳定,发布3.52008/5/17 20:32 : 修正3.5恢复SSDT失败的BUG,一个小小的笔误,实在不好意思.请大家不要用旧版本了,些版本是历来最稳定的,旧版本BUG太多,看更新记录就知道了,下个版本出来会有很长时间,大家可以放心的用,更新周期会变长2008/5/22 17:11 : 偶再三思考下,开源,开源是最好的办法,我就开源.....我就不信了...3.6开源视频压缩支持的编码格式,按优先级排列:Microsoft H.263 Video CodecIntel Indeo(R) Video R3.2Microsoft MPEG-4 Video Codec V2Cinepak Codec by Radius声明下软件的安装方式:如果安装时发现有相同配置的服务端已经安装过,就不安装也不删除,跟鸽子一个原理,我是靠字串区别的2008/3/2 06:35 : 本着我们红狼写gh0st的初衷,一个共享,免费,的软件,到今天为止,算是对大家一个交代,新版本开发,经小组内部讨论将此版本开源..装上VC6,打造属于你们自己的gh0st吧..我们不保留版权,任何信息,自由修改,多谢一直以来大家的支持,我们会继续努力的

81,091

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧