如何使用jsp/servlet将文件上传到服务器?我试过这个:
<form action="upload" method="post">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
但是,我只得到文件名,而不是文件内容。当我加上 enctype="multipart/form-data"
到 <form>
,那么 request.getParameter()
退货 null
.
在研究过程中,我偶然发现了apache公共文件上传。我试过这个:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.
不幸的是,servlet抛出了一个没有明确消息和原因的异常。下面是stacktrace:
SEVERE: Servlet.service() for servlet UploadServlet threw exception
javax.servlet.ServletException: Servlet execution threw an exception
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:637)
9条答案
按热度按时间ia2d9nvy1#
导言
要浏览并选择要上载的文件,您需要一个html
<input type="file">
窗体中的字段。如html规范所述,您必须使用POST
方法和步骤enctype
窗体的属性必须设置为"multipart/form-data"
.提交这样的表单后,二进制多部分表单数据在请求主体中的格式与
enctype
未设置。在Servlet3.0之前,ServletAPI本机不支持
multipart/form-data
. 它只支持enctype的默认形式application/x-www-form-urlencoded
. 这个request.getParameter()
所有的配偶都会回来null
使用多部分表单数据时。这就是著名的apachecommons文件上传出现的地方。不要手动解析!
理论上,您可以根据
ServletRequest#getInputStream()
. 然而,这是一个精确和繁琐的工作,需要对rfc2388的准确知识。你不应该试着自己做这件事,或者复制粘贴一些在互联网上其他地方找到的没有库的代码。许多在线资源在这方面都失败了,比如roseindia.net。另请参见上载pdf文件。您更应该使用一个真正的库,它被使用(并且隐式地测试!)被数百万用户使用多年。这样一个库已经证明了它的健壮性。当您已经使用Servlet3.0或更新版本时,请使用本机api
如果您至少使用Servlet3.0(Tomcat7、Jetty9、JBossas6、GlassFish3等),那么您可以使用提供的标准api
HttpServletRequest#getPart()
收集单个的多部分表单数据项(大多数Servlet3.0实现实际上是在封面下使用ApacheCommonsFileUpload)。此外,标准格式字段也可以通过getParameter()
通常的方式。首先用
@MultipartConfig
为了让它认可和支持multipart/form-data
请求,从而获得getPart()
要工作:然后,实施
doPost()
具体如下:注意
Path#getFileName()
. 这是一个关于获取文件名的msie修复程序。此浏览器错误地沿名称而不是仅沿文件名发送完整文件路径。万一你有
<input type="file" name="file" multiple="true" />
对于多文件上传,请按以下方式收集它们(不幸的是,没有如下方法)request.getParts("file")
):当您还没有使用Servlet3.1时,请手动获取提交的文件名
请注意
Part#getSubmittedFileName()
在Servlet3.1中引入(Tomcat8、Jetty9、wildfly 8、glassfish 4等)。如果您还没有使用Servlet3.1,那么您需要一个额外的实用程序方法来获取提交的文件名。注意msie修复程序获取文件名。此浏览器错误地沿名称而不是仅沿文件名发送完整文件路径。
如果您还没有使用Servlet3.0,请使用ApacheCommonsFileUpload
如果您还没有使用Servlet3.0(是不是该升级了?),通常的做法是使用ApacheCommonsFileUpload来解析multpart表单数据请求。它有一个很好的用户指南和常见问题解答(仔细阅读两者)。还有o'reilly(“cos”)
MultipartRequest
,但它有一些(小)错误,多年来不再积极维护。我不建议用它。ApacheCommonsFileUpload仍在积极维护,目前非常成熟。为了使用apachecommons fileupload,您的webapp中至少需要有以下文件
/WEB-INF/lib
:commons-fileupload.jar
commons-io.jar
您最初的尝试很可能失败了,因为您忘记了commons io。下面是一个启动示例
doPost()
你的UploadServlet
使用apache commons fileupload时可能会出现以下情况:重要的是你不要打电话
getParameter()
,getParameterMap()
,getParameterValues()
,getInputStream()
,getReader()
等的要求。否则servlet容器将读取并解析请求主体,因此apachecommonsfileupload将获得一个空的请求主体。另请参见a.o.servletfileupload#parserequest(request)返回空列表。注意
FilenameUtils#getName()
. 这是一个关于获取文件名的msie修复程序。此浏览器错误地沿名称而不是仅沿文件名发送完整文件路径。或者,你也可以把这一切都 Package 在一个
Filter
它会自动解析所有内容,并将这些内容放回请求的parametermap中,以便您可以继续使用request.getParameter()
通常的方式和检索上传的文件request.getAttribute()
. 你可以在这篇博客文章中找到一个例子。getparameter()的glassfish3 bug仍返回null的解决方法
请注意,早于3.1.2的glassfish版本有一个bug,其中
getParameter()
仍然返回null
. 如果您的目标是这样一个容器,并且无法升级它,那么您需要从中提取值getPart()
借助此实用方法:保存上传的文件(不要使用getrealpath()或part.write()!)
请参阅下面的答案,以了解有关正确保存所获取数据的详细信息
InputStream
(the)fileContent
变量(如以上代码段所示)到磁盘或数据库:在servlet应用程序中保存上载文件的推荐方法
如何上传图片并保存到数据库中?
如何将part转换成blob,这样我就可以在mysql中存储它了?
提供上载的文件
有关如何将保存的文件从磁盘或数据库返回到客户端的详细信息,请参阅以下答案:
使用<h:graphicimage>或标记从webapps/webcontext/deploy文件夹外部加载图像
如何在jsp页面中从数据库检索和显示图像?
在javaweb应用程序中从应用服务器外部提供静态数据的最简单方法
支持http缓存的静态资源servlet的抽象模板
将形式化
下面是如何使用ajax(和jquery)上传的答案。请注意,收集表单数据的servlet代码不需要为此更改!只有响应的方式可能会改变,但这相当简单(即,不转发到jsp,只需打印一些json或xml甚至纯文本,这取决于负责ajax调用的脚本所期望的内容)。
如何使用jsp/servlet和ajax将文件上传到服务器?
通过xmlhttprequest以多部分形式发送文件
html5文件上传到java servlet
希望这些都有用:)
b1payxdu2#
如果您碰巧使用了springmvc,那么下面是:(我把这个放在这里,以防有人发现它有用)。
使用带有
enctype
属性设置为“multipart/form-data
“(与巴卢斯克的回答相同)在控制器中,Map请求参数
file
至MultipartFile
类型如下:您可以使用
MultipartFile
的getOriginalFilename()
以及getSize()
.我已经用spring版本测试过了
4.1.1.RELEASE
.mzmfm0qo3#
在tomcat6o7中没有组件或外部库
在web.xml文件中启用上载:
http://joseluisbz.wordpress.com/2014/01/17/manually-installing-php-tomcat-and-httpd-lounge/#enabling%20文件%20上传。
如你所见:
使用jsp上传文件。文件夹:
在html文件中
在jsp文件或servlet中
根据servlet要求编辑代码,比如最大文件大小、最大请求大小和其他可以设置的选项。。。
r7xajy2e4#
你需要
common-io.1.4.jar
要包含在您的lib
目录,或者如果您在任何编辑器中工作,比如netbeans,那么您需要转到项目属性,只需添加jar文件就可以了。为了得到
common.io.jar
文件只需google一下,或者直接访问apachetomcat网站,在那里你可以免费下载这个文件。但请记住一件事:如果您是windows用户,请下载二进制zip文件。7gs2gvoe5#
我对每个html表单使用公共servlet,不管它是否有附件。此servlet返回
TreeMap
其中键是jsp名称参数,值是用户输入,并将所有附件保存在固定目录中,然后您可以重命名您选择的目录。我想这对你有帮助dxxyhpgq6#
对于springmvc,我已经尝试了几个小时来实现这一点,并设法得到了一个更简单的版本,用于获取表单输入数据和图像。
要处理的控制器
希望有帮助:)
zdwk9cvp7#
如果您将geronimo与其嵌入的tomcat一起使用,则会出现此问题的另一个根源。在这种情况下,在多次迭代测试commons io和commons fileupload之后,问题来自处理commons jar的父类加载器。这是必须防止的。车祸总是发生在:
请注意,fileitems的列表类型已随commons fileupload的当前版本而更改,具体如下:
List<FileItem>
与以前的通用版本不同List
.我将commons fileupload和commons io的源代码添加到我的eclipse项目中,以跟踪实际错误,并最终获得一些见解。首先,抛出的异常是throwable类型,不是声明的fileioexception,甚至不是exception(这些异常不会被捕获)。其次,错误消息是模糊的,因为它声明类找不到,因为axis2找不到commons io。axis2根本不在我的项目中使用,而是作为标准安装的一部分作为geronimo存储库子目录中的文件夹存在。
最后,我找到了一个地方,提出了一个有效的解决方案,成功地解决了我的问题。必须对部署计划中的父加载程序隐藏jar。这被放入geronimo-web.xml中,我的完整文件如下所示。
de90aj5v8#
下面是一个使用apache commons fileupload的示例:
l7wslrjt9#
首先必须设置的enctype属性