使用JSP和Servlet无法打印上传文件名及获取上传路径求助
解决Servlet文件上传中无法获取/打印上传路径的问题
看起来你已经搭好了前端的上传表单(enctype="multipart/form-data"设置正确这点很关键),核心问题就是在Servlet里没法拿到并打印文件最终保存的完整路径对吧?我给你两种常用的解决方案,你可以根据自己的项目情况选一种:
方案一:用Servlet 3.0+原生API(无需额外依赖)
从Servlet 3.0开始,原生支持文件上传,只要给你的Servlet加上@MultipartConfig注解就能轻松处理,代码如下:
import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.IOException; @WebServlet("/go") // 指定文件保存的根目录,同时设置大小限制 @MultipartConfig(location = "d:/new", fileSizeThreshold = 1024 * 1024, // 超过1MB的文件先存临时目录 maxFileSize = 1024 * 1024 * 5, // 单个文件最大5MB maxRequestSize = 1024 * 1024 * 10) // 整个请求最大10MB public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取上传的文件对象 Part filePart = request.getPart("fname"); // 从请求头里提取真实文件名(兼容不同浏览器) String fileName = extractFileName(filePart); // 把文件写入指定目录 filePart.write(fileName); // 拼接完整路径并打印 String fullUploadPath = "d:/new/" + fileName; System.out.println("文件上传完成,路径:" + fullUploadPath); // 也可以把路径返回给前端展示 response.getWriter().write("文件已上传至:" + fullUploadPath); } // 工具方法:从Part的Content-Disposition头中提取文件名 private String extractFileName(Part part) { String contentDisposition = part.getHeader("content-disposition"); for (String segment : contentDisposition.split(";")) { if (segment.trim().startsWith("filename")) { // 去掉引号和多余空格,拿到纯文件名 return segment.substring(segment.indexOf('=') + 1).trim().replace("\"", ""); } } // 如果拿不到文件名,用默认值 return "unknown_upload_file"; } }
关键点说明:
@MultipartConfig的location参数就是你要保存文件的根目录(这里是d:/new)extractFileName方法是为了兼容不同浏览器:有些浏览器(比如旧IE)会把本地路径一起传给服务器,这个方法能提取出纯文件名- 保存文件后直接拼接
location和文件名,就能得到你想要的d:/new/filename格式的路径,直接打印就行
方案二:用Apache Commons FileUpload(适合老版本Servlet)
如果你的项目用的是Servlet 3.0以下的版本,或者习惯用Apache的工具库,可以用Commons FileUpload来处理:
第一步:先引入依赖
你需要在项目里加入commons-fileupload和commons-io这两个jar包(如果是Maven项目,直接添加对应依赖即可)
第二步:Servlet代码实现
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.List; @WebServlet("/go") public class UploadServlet extends HttpServlet { // 定义上传目录 private static final String UPLOAD_DIR = "d:/new"; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 先检查是不是合法的文件上传请求 if (!ServletFileUpload.isMultipartContent(request)) { response.getWriter().write("这不是一个文件上传请求,请检查表单的enctype设置!"); return; } // 创建文件上传工厂和处理器 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); // 设置文件大小限制(可选) upload.setFileSizeMax(1024 * 1024 * 5); upload.setSizeMax(1024 * 1024 * 10); // 确保上传目录存在,不存在就创建 File uploadDirectory = new File(UPLOAD_DIR); if (!uploadDirectory.exists()) { uploadDirectory.mkdirs(); } try { // 解析请求,获取所有表单项 List<FileItem> formItems = upload.parseRequest(request); if (formItems != null && !formItems.isEmpty()) { // 遍历表单项,找到文件字段 for (FileItem item : formItems) { if (!item.isFormField()) { // 不是普通表单字段,就是文件 // 提取纯文件名(避免浏览器传递本地路径) String fileName = new File(item.getName()).getName(); // 拼接完整上传路径 String fullPath = UPLOAD_DIR + File.separator + fileName; File savedFile = new File(fullPath); // 保存文件到磁盘 item.write(savedFile); // 打印上传路径 System.out.println("文件上传成功,路径:" + fullPath); response.getWriter().write("文件已上传至:" + fullPath); } } } } catch (Exception e) { response.getWriter().write("文件上传失败:" + e.getMessage()); } } }
注意事项:
- 一定要确保
d:/new目录有写入权限,否则会抛出IO异常 - 两种方案中提取文件名的方式都是为了兼容不同浏览器的行为,避免拿到带本地路径的文件名
- 如果需要动态设置上传目录,也可以把路径放在配置文件里,不要硬编码(不过你现在需要的是固定路径,硬编码也没问题)
内容的提问来源于stack exchange,提问作者ronak roy
相关产品推荐
相关产品推荐

