博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
How to upload files to server using JSP/Servlet?
阅读量:4319 次
发布时间:2019-06-06

本文共 7200 字,大约阅读时间需要 24 分钟。

转载:http://stackoverflow.com/questions/2422468/how-to-upload-files-to-server-using-jsp-servlet/2424824#2424824

 

 

Introduction

To browse and select a file for upload you need a HTML <input type="file"> field in the form. As stated in the you have to use the POST method and the enctype attribute of the form has to be set to "multipart/form-data".

After submitting such a form, the binary multipart form data is available in the request body in than when the enctype isn't set.

Before Servlet 3.0, the Servlet API didn't natively support multipart/form-data. It supports only the default form enctype of application/x-www-form-urlencoded. The request.getParameter() and consorts would all return null when using multipart form data. This is where the well known came into the picture.

Don't manually parse it!

You can in theory parse the request body yourself based on . However, this is a precise and tedious work which requires precise knowledge of . You shouldn't try to do this on your own or copypaste some homegrown library-less code found elsewhere on the Internet. Many online sources have failed hard in this, such as roseindia.net. See also . You should rather use a real library which is used (and implicitly tested!) by millions of users for years. Such a library has proven its robustness.

When you're already on Servlet 3.0 or newer, use native API

If you're using at least Servlet 3.0 (Tomcat 7, JBoss AS 6, GlassFish 3, etc), then you can just use standard API provided to collect the individual multipart form data items (most Servlet 3.0 implementations actually use Apache Commons FileUpload under the covers for this!). Also, normal form fields are available by getParameter() the usual way.

First annotate your servlet with in order to let it recognize and support multipart/form-data requests and thus get getPart() to work:

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

Then, implement its doPost() as follows:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String description = request.getParameter("description"); // Retrieves  Part filePart = request.getPart("file"); // Retrieves  String fileName = filePart.getSubmittedFileName(); InputStream fileContent = filePart.getInputStream(); // ... (do your job here) }

When you're not on Servlet 3.1 yet, manually get submitted file name

Note that was introduced in Servlet 3.1 (Tomcat 8, WildFly 8, GlassFish 4, etc). If you're not on Servlet 3.1 yet, then you need an additional utility method to obtain the submitted file name.

private static String getSubmittedFileName(Part part) { for (String cd : part.getHeader("content-disposition").split(";")) { if (cd.trim().startsWith("filename")) { String fileName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", ""); return fileName.substring(fileName.lastIndexOf('/') + 1).substring(fileName.lastIndexOf('\\') + 1); // MSIE fix. } } return null; }
String fileName = getSubmittedFileName(filePart);

Note the MSIE fix as to obtaining the file name. This browser incorrectly sends the full file path along the name instead of only the file name.

When you're not on Servlet 3.0 yet, use Apache Commons FileUpload

If you're not on Servlet 3.0 yet (isn't it about time to upgrade?), the common practice is to make use of to parse the multpart form data requests. It has an excellent and (carefully go through both). There's also the O'Reilly ("") MultipartRequest, but it has some (minor) bugs and isn't actively maintained anymore for years. I wouldn't recommend using it. Apache Commons FileUpload is still actively maintained and currently very mature.

In order to use Apache Commons FileUpload, you need to have at least the following files in your webapp's /WEB-INF/lib:

Your initial attempt failed most likely because you forgot the commons IO.

Here's a kickoff example how the doPost() of your UploadServlet may look like when using Apache Commons FileUpload:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { List
items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request); for (FileItem item : items) { if (item.isFormField()) { // Process regular form field (input type="text|radio|checkbox|etc", select, etc). String fieldName = item.getFieldName(); String fieldValue = item.getString(); // ... (do your job here) } else { // Process form file field (input type="file"). String fieldName = item.getFieldName(); String fileName = FilenameUtils.getName(item.getName()); InputStream fileContent = item.getInputStream(); // ... (do your job here) } } } catch (FileUploadException e) { throw new ServletException("Cannot parse multipart request.", e); } // ... }

It's very important that you don't call getParameter(), getParameterMap(), getParameterValues(), getInputStream(), getReader(), etc on the same request beforehand. Otherwise the servlet container will read and parse the request body and thus Apache Commons FileUpload will get an empty request body. See also a.o. .

Note the FilenameUtils#getName(). This is a MSIE fix as to obtaining the file name. This browser incorrectly sends the full file path along the name instead of only the file name.

Alternatively you can also wrap this all in a Filter which parses it all automagically and put the stuff back in the parametermap of the request so that you can continue using request.getParameter() the usual way and retrieve the uploaded file by request.getAttribute(). .

Workaround for GlassFish3 bug of getParameter() still returning null

Note that Glassfish versions older than 3.1.2 had wherein the getParameter() still returns null. If you are targeting such a container and can't upgrade it, then you need to extract the value from getPart() with help of this utility method:

private static String getValue(Part part) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream(), "UTF-8")); StringBuilder value = new StringBuilder(); char[] buffer = new char[1024]; for (int length = 0; (length = reader.read(buffer)) > 0;) { value.append(buffer, 0, length); } return value.toString(); }
String description = getValue(request.getPart("description")); // Retrieves 

Saving uploaded file (don't use getRealPath() nor part.write()!)

Head to the following answers for detail on properly saving the obtained InputStream (the fileContent variable as shown in the above code snippets) to disk or database:

Serving uploaded file

Head to the following answers for detail on properly serving the saved file from disk or database back to the client:

Ajaxifying the form

Head to the following answers how to upload using Ajax (and jQuery). Do note that the servlet code to collect the form data does not need to be changed for this! Only the way how you respond may be changed, but this is rather trivial (i.e. instead of forwarding to JSP, just print some JSON or XML or even plain text depending on whatever the script responsible for the Ajax call is expecting).

转载于:https://www.cnblogs.com/jitash/p/5145023.html

你可能感兴趣的文章
C#NULL条件运算符
查看>>
使用GZIP压缩网页内容(一)
查看>>
《深入浅出MFC》第二章 C++的重要性质
查看>>
关于智能硬件设备shell安全设计
查看>>
homework1
查看>>
3选择结构程序设计
查看>>
Python学习 12day__高级语法
查看>>
关于做产品的一点思考
查看>>
超大地形的处理 (Terrain Visualization)【转自知乎】
查看>>
html知识2
查看>>
Python—面向对象01
查看>>
Android DDMS ADB Hierarchy Viewer Lint
查看>>
Linux命令学习(5):more和less
查看>>
Linux 三剑客之sed命令总结
查看>>
倒计时
查看>>
36.Altium Designer(Protel)网络连接方式Port和Net Label详解
查看>>
读《分布式一致性原理》CURATOR客户端3
查看>>
iOS 虚拟机测试出现的相关问题
查看>>
MySQL crash-safe replication(3): MySQL的Crash Safe和Binlog的关系
查看>>
mac 无法打开xx ,因为无法确认开发者身份
查看>>