如何使用JSP / Servlet将文件上传到服务器? [英] How to upload files to server using JSP/Servlet?

查看:215
本文介绍了如何使用JSP / Servlet将文件上传到服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用JSP / Servlet将文件上传到服务器?我试过这个:
$ b

 < form action =uploadmethod =post> 
< input type =textname =description/>
< input type =filename =file/>
< input type =submit/>
< / form>

但是,我只获取文件名,而不是文件内容。当我向< form> 添加 enctype =multipart / form-data,那么 request.getParameter()返回 null



在研究期间,我偶然发现了 Apache Common FileUpload 。我试过这个:

pre $ File_temFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); //这条线是死的地方

不幸的是,servlet抛出一个没有明确信息和原因的异常。这里是堆栈跟踪:

pre $ SEVERE:servlet UploadServlet的Servlet.service()抛出异常
javax.servlet.ServletException :Servlet执行在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)上抛出异常
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233 206)

在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
$ b在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
。在组织.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
在org.apache.coyote .http11.Http 11Processor.process(Http11Processor.java:852)
在org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:588)
。在org.apache.tomcat.util.net。 JIoEndpoint $ Worker.run(JIoEndpoint.java:489)$ b $在java.lang.Thread.run(Thread.java:637)


解决方案

简介



要浏览并选择要上传的文件,您需要HTML < input type =file> 字段。正如 HTML规范所述,您必须使用 POST 方法,并且必须将表单的 enctype 属性设置为multipart / form-data


$ b

 < form action =uploadmethod =post enctype =multipart / form-data> 
< input type =textname =description/>
< input type =filename =file/>
< input type =submit/>
< / form>

提交这样一个表单后,二进制多部分表单数据可以在不同的格式比<$ c没有设置$ c> enctype 。



在Servlet 3.0之前,Servlet API本身不支持 multipart /格式数据。它仅支持 application / x-www-form-urlencoded 的默认表单enctype。使用多部分表单数据时, request.getParameter()和配置都将返回 null 。这就是众所周知的 Apache Commons FileUpload 出现的地方。



不要手动解析!



理论上可以根据 ServletRequest#getInputStream() 。然而,这是一个精确而乏味的工作,需要精确的了解 RFC2388 。你不应该试图自己做这个,或者复制一些在互联网上其他地方找到的本地无库代码。许多在线资源在这方面都失败了,比如roseindia.net。另请参阅上传pdf文件。你应该使用一个真正的图书馆,这个图书馆已经被数百万用户使用(并且被隐式测试!)了好多年。当你已经在Servlet 3.0或更新的版本上时,使用本地API

如果您至少使用Servlet 3.0(Tomcat 7,Jetty 9,JBoss AS 6,GlassFish 3等),那么您可以使用标准的API提供 HttpServletRequest#getPart() 收集单独的多部分表单数据项(大多数Servlet 3.0的实现实际上使用Apache Commons FileUpload在这个掩护下!)。另外,通常的表单字段可以通过 getParameter()通常的方式获得。首先用 @MultipartConfig 为了让它识别并支持 multipart / form-data 请求,从而得到 getPart()

  @WebServlet(/ upload)
@MultipartConfig
public class UploadServlet extends HttpServlet {
// ...
}

然后,执行 doPost()如下:
$ b

  protected void doPost(HttpServletRequest请求,HttpServletResponse响应)抛出ServletException,IOException {
String description = request.getParameter(description); //检索< input type =textname =description>
Part filePart = request.getPart(file); //获取< input type =filename =file>
String fileName = Paths.get(filePart.getSubmittedFileName())。getFileName()。toString(); // MSIE修复
InputStream fileContent = filePart.getInputStream();
// ...(在这里做你的工作)
}

Path#getFileName()。这是获取文件名的MSIE修复程序。这个浏览器错误地发送完整的文件路径,而不是只有文件名。

如果你有一个< input type =文件name =filemultiple =true/> 为多文件上传,收集如下(不幸的是,没有这样的方法 request.getParts (HttpServletRequest请求,HttpServletResponse响应)抛出ServletException异常,请参阅:http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&displaylang=zh-cn反过来, IOException {
// ...
List< Part> fileParts = request.getParts()。stream()。filter(part - >file.equals(part.getName()))。collect(Collectors.toList()); //检索< input type =filename =filemultiple =true> (Part filePart:fileParts){
String fileName = Paths.get(filePart.getSubmittedFileName())。getFileName()。toString();

// MSIE修复
InputStream fileContent = filePart.getInputStream();
// ...(在这里做你的工作)
}
}



当你不在Servlet 3.1中时,手动获取提交的文件名



请注意 Part#getSubmittedFileName() 是在Servlet 3.1中引入(Tomcat 8,Jetty 9,WildFly 8,GlassFish 4等)。如果你还没有使用Servlet 3.1,那么你需要额外的实用方法来获取提交的文件名。

  private static String(String)cd:part.getHeader(content-disposition)。split(;)){
if(cd.trim()。startsWith(文件名)){
String fileName = cd.substring(cd.indexOf('=')+ 1).trim().exc(\,);
return fileName .substring(fileName.lastIndexOf('/')+ 1).substring(fileName.lastIndexOf('\\\')+ 1); // MSIE fix。
}
}
返回null;
}





  String fileName = getSubmittedFileName(filePart); 

注意MSIE修正以获取文件名,这个浏览器错误地发送完整的文件路径而不是文件名。



当你不在Servlet 3.0上时,使用Apache Commons FileU pload



如果您还没有使用Servlet 3.0(是不是要升级?),通常的做法是使用 Apache Commons FileUpload 来解析多部分表单数据请求。它有一个很好的用户指南常见问题(仔细检查两者)。还有O'Reilly( cos MultipartRequest ,但它有一些(小的)错误,并且不再被主动维护多年。我不会推荐使用它。 Apache Commons FileUpload仍然在积极维护当前非常成熟。为了使用Apache Commons FileUpload,您至少需要在您的webapp的 / WEB-INF / lib

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆