使用Servlet处理一个上传的文件
在Java Web开发中,Servlet是用于处理HTTP请求的重要组件。当涉及到文件上传时,Servlet扮演着接收和存储上传文件的角色。本篇文章将详细介绍如何使用Servlet处理一个上传的文件,包括使用`getReader()`、`getInputStream()`以及`getPart()`和`getParts()`方法。 了解文件上传的基本原理。在HTML表单中,我们需要设置`enctype="multipart/form-data"`,以允许文件作为二进制数据进行传输。以下是一个简单的HTML上传表单示例: ```html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title></title> </head> <body> <form action="upload" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="filename" value="" /><br> <input type="submit" value="Upload" name="upload" /> </form> </body> </html> ``` 这个表单允许用户选择一个文件,并通过POST请求发送到服务器的`/upload`路径。 在Servlet端,我们可以使用`doPost()`方法来处理文件上传。传统的做法是使用`getInputStream()`读取整个请求体,然后解析出文件内容。以下是一个简单的示例: ```java @WebServlet("/upload") public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 读取请求Body byte[] body = readBody(request); // ... } // 读取请求body private byte[] readBody(HttpServletRequest request) throws IOException { int formDataLength = request.getContentLength(); DataInputStream dis = new DataInputStream(request.getInputStream()); byte[] body = new byte[formDataLength]; dis.readFully(body); dis.close(); return body; } } ``` 但是,这种方法需要手动解析上传文件的边界,比较复杂。因此,Servlet 3.0引入了`Part`接口,提供了更方便的方式来处理文件上传。你可以使用`request.getPart("filename")`来获取名为`filename`的`Part`对象,然后调用`Part`的`write()`方法将其写入到服务器上的文件系统。 ```java @WebServlet("/upload") public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Part filePart = request.getPart("filename"); String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); File uploadedFile = new File("/path/to/save/" + fileName); Files.copy(filePart.getInputStream(), uploadedFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } } ``` 如果需要处理多文件上传,可以使用`request.getParts()`方法,它会返回一个`Part`的`Enumeration`,你可以遍历它们并分别处理每个文件。 总结来说,处理文件上传有多种方式。传统的方式是使用`getInputStream()`配合手动解析,而Servlet 3.0及以上版本提供了`Part`接口,使得文件上传变得更加简单。在实际开发中,应根据项目需求和所使用的Servlet版本选择合适的方法。注意,无论哪种方法,都需要确保文件上传的安全性,例如限制文件大小、检查文件类型等,以防止恶意文件上传。