如何使用JSP/Servlet将文件上传到服务器?

720
如何使用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"时,request.getParameter()返回null。
在研究过程中,我偶然发现了Apache Common FileUpload。我尝试了这个方法:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.

很遗憾,该servlet抛出了一个没有明确消息和原因的异常。以下是堆栈跟踪:
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)

也许这篇文章会有所帮助:https://www.baeldung.com/upload-file-servlet - Adam Gerard
1
@Adam:他们从我的答案中抄袭,并在其上添加了一堆广告,试图通过此赚钱。是的,好文章。 - BalusC
1
不,实际上没有复制任何内容。我写了那篇文章的第一稿以及补充代码。核心参考文档可以在这里找到:https://commons.apache.org/proper/commons-fileupload/using.html(并且在文章中有链接和引用)。示例部分是从核心参考文档中摘录的(这就是参考文档的目的——作为参考点),但并非全部(请注意,参考文档没有详细说明)。谢谢! - Adam Gerard
请查看以下链接:https://sandny.com/2017/05/18/servlet-file-upload - ricky
14个回答

1257

介绍

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

<form action="upload" method="post" enctype="multipart/form-data">
    <input type="text" name="description" />
    <input type="file" name="file" />
    <input type="submit" />
</form>

提交这样的表单后,二进制多部分表单数据以不同的格式出现在请求体中,与未设置enctype时不同。
在Servlet 3.0之前(2009年12月),Servlet API不原生支持multipart/form-data。它只支持默认的表单enctype application/x-www-form-urlencoded。当使用多部分表单数据时,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等,它们自2010年以来已经存在),那么您可以直接使用标准API提供的HttpServletRequest#getPart()来收集各个多部分表单数据项(大多数Servlet 3.0实现实际上在底层使用Apache Commons FileUpload来实现此功能!)。此外,普通表单字段可以通过getParameter()以常规方式获取。
首先,在您的servlet上使用@MultipartConfig进行注解,以便让它识别和支持multipart/form-data请求,从而使getPart()正常工作。
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
    // ...
}

然后,按照以下方式实现它的doPost()方法:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String description = request.getParameter("description"); // Retrieves <input type="text" name="description">
    Part filePart = request.getPart("file"); // Retrieves <input type="file" name="file">
    String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
    InputStream fileContent = filePart.getInputStream();
    // ... (do your job here)
}

请注意Path#getFileName()。这是一个针对MSIE的修复,用于获取文件名。该浏览器错误地将完整文件路径与文件名一起发送,而不仅仅是文件名。
如果您想通过multiple="true"上传多个文件的话,
<input type="file" name="files" multiple="true" />

或者以传统的方式使用多个输入。
<input type="file" name="files" />
<input type="file" name="files" />
<input type="file" name="files" />
...

然后你可以按照以下方式收集它们(不幸的是,没有request.getParts("files")这样的方法):
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ...
    List<Part> fileParts = request.getParts().stream().filter(part -> "files".equals(part.getName()) && part.getSize() > 0).collect(Collectors.toList()); // Retrieves <input type="file" name="files" multiple="true">

    for (Part filePart : fileParts) {
        String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
        InputStream fileContent = filePart.getInputStream();
        // ... (do your job here)
    }
}

当你还没有使用Servlet 3.1时,手动获取提交的文件名

请注意,Part#getSubmittedFileName()是在Servlet 3.1中引入的(Tomcat 8,Jetty 9,WildFly 8,GlassFish 4等,它们自2013年以来就存在)。如果你还没有使用Servlet 3.1(真的吗?),那么你需要一个额外的实用方法来获取提交的文件名。

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);

注意MSIE修复以获取文件名。该浏览器错误地发送完整的文件路径,而不仅仅是文件名。
当您尚未使用Servlet 3.0时,请使用Apache Commons FileUpload
如果您尚未使用Servlet 3.0(是时候升级了吗?它已经发布了十多年了!),常见做法是使用Apache Commons FileUpload来解析多部分表单数据请求。它有一个出色的用户指南和常见问题解答(请仔细阅读两者)。还有O'Reilly("cos")的MultipartRequest,但它有一些(轻微的)错误,并且多年来没有得到积极维护。我不建议使用它。Apache Commons FileUpload仍在积极维护,并且目前非常成熟。
为了使用Apache Commons FileUpload,您需要至少在您的Web应用程序的/WEB-INF/lib目录下拥有以下文件: 你的初始尝试失败很可能是因为你忘记了commons IO。
以下是一个启动示例,展示了在使用Apache Commons FileUpload时,你的UploadServlet的doPost()方法可能会是什么样子的。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        List<FileItem> 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);
    }

    // ...
}

非常重要的是,在同一请求之前不要调用getParameter(),getParameterMap(),getParameterValues(),getInputStream(),getReader()等方法。否则,Servlet容器将读取和解析请求体,因此Apache Commons FileUpload将获得一个空的请求体。另请参阅{{link1:ServletFileUpload#parseRequest(request)返回一个空列表}}。
请注意FilenameUtils#getName()。这是一个用于获取文件名的MSIE修复程序。该浏览器错误地将完整的文件路径与名称一起发送,而不仅仅是文件名。
或者,您还可以将所有内容包装在一个Filter中,自动解析并将内容放回请求的参数映射中,以便您可以继续使用request.getParameter()的常规方式,并通过request.getAttribute()检索上传的文件。 {{link2:您可以在此博客文章中找到一个示例}}。

解决GlassFish3中getParameter()仍返回null的bug的方法

请注意,早于3.1.2版本的Glassfish存在一个bug,即getParameter()仍然返回null。如果您的目标容器是这样的版本且无法升级,那么您需要使用这个实用方法从getPart()中提取值:

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 <input type="text" name="description">
    

保存上传的文件(不要使用getRealPath()part.write()!)

请参考以下答案,了解如何正确将获取到的InputStream(如上面代码片段中显示的fileContent变量)保存到磁盘或数据库:

提供上传的文件

请参考以下答案,了解如何正确地从磁盘或数据库中将保存的文件返回给客户端:

将表单转换为Ajax

请参考以下答案,了解如何使用Ajax(和jQuery)上传文件。请注意,收集表单数据的servlet代码无需更改!只需要更改响应的方式,但这相对来说是微不足道的(即不是转发到JSP,而是根据Ajax调用的脚本期望的内容打印一些JSON、XML甚至纯文本)。

使用Servlet 3.0,如果违反了MultipartConfig条件(例如:maxFileSize),调用request.getParameter()将返回null。这是故意的吗?如果在调用getPart之前获取一些常规(文本)参数(并检查IllegalStateException),会发生什么情况?这会导致NullPointerException在我有机会检查IllegalStateException之前被抛出。 - theyuv
@BalusC,我创建了一个与此相关的帖子,你有什么想法可以从File API webKitDirectory中检索额外的信息。更多细节请参见https://stackoverflow.com/questions/45419598/retrieve-uploaded-relativepath-file-on-server-side - Rapster
答案在“当您已经使用Servlet 3.0或更高版本时”部分是误导性的,因为根据文档getSubmittedFileName方法自Servlet规范3.1以来就可用于Part接口,Tomcat 8+支持3.1规范。 - raviraja
1
是的,如果有人尝试在Tomcat 7中使用3.0部分的代码,则可能会遇到“String fileName = Paths.get(filePart.getSubmittedFileName())。getFileName()。toString(); // MSIE fix.”这一部分类似于我的问题。 - raviraja
2
@aaa:当您出于不明确的原因使用Reader和/或Writer将字节转换为字符时,可能会发生这种情况。不要这样做。在读写上传的文件时,在所有地方使用InputStream/OutputStream,而不是将字节转换为字符。PDF文件不是基于字符的文本文件。它是一个二进制文件。 - BalusC
显示剩余12条评论

26

如果您恰好使用Spring MVC,请按照以下步骤操作(我将其保留在这里以便有人找到它时有用):

使用具有 enctype 属性设置为 "multipart/form-data" 的表单(与BalusC的回答相同):

<form action="upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="Upload"/>
</form>

在您的控制器中,将请求参数file映射到MultipartFile类型,方法如下:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public void handleUpload(@RequestParam("file") MultipartFile file) throws IOException {
    if (!file.isEmpty()) {
            byte[] bytes = file.getBytes(); // alternatively, file.getInputStream();
            // application logic
    }
}

使用MultipartFilegetOriginalFilename()getSize()方法可以获取文件名和大小。

我已经在Spring版本4.1.1.RELEASE中进行了测试。


如果我没记错的话,这需要在你服务器的应用配置中配置一个bean... - Kenny Worden

12

在Tomcat 6或Tomcat 7中没有组件或外部库

web.xml文件中启用上传:

手动安装PHP、Tomcat和Httpd Lounge.

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <multipart-config>
      <max-file-size>3145728</max-file-size>
      <max-request-size>5242880</max-request-size>
    </multipart-config>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>

正如您所看到的

<multipart-config>
  <max-file-size>3145728</max-file-size>
  <max-request-size>5242880</max-request-size>
</multipart-config>

使用JSP上传文件。文件:

在HTML文件中:

<form method="post" enctype="multipart/form-data" name="Form" >

  <input type="file" name="fFoto" id="fFoto" value="" /></td>
  <input type="file" name="fResumen" id="fResumen" value=""/>

在JSP文件或者Servlet中

InputStream isFoto = request.getPart("fFoto").getInputStream();
InputStream isResu = request.getPart("fResumen").getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[8192];
int qt = 0;
while ((qt = isResu.read(buf)) != -1) {
  baos.write(buf, 0, qt);
}
String sResumen = baos.toString();

将您的代码编辑为Servlet要求的格式,例如max-file-sizemax-request-size和其他选项,您可以进行设置...


11
您需要将common-io.1.4.jar文件包含在您的lib目录中,或者如果您正在使用像NetBeans这样的编辑器,则需要转到项目属性并添加JAR文件即可完成。
要获取common.io.jar文件,请搜索谷歌或只需访问Apache Tomcat网站,在那里您可以免费下载该文件。但请注意一件事:如果您是Windows用户,则下载二进制ZIP文件。

找不到.jar文件,但找到了.zip文件。你是不是要找.zip文件? - Malwinder Singh

9
我正在使用一个普通的Servlet,用于处理每个HTML表单,无论是否包含附件。
这个Servlet返回一个TreeMap,其中键是JSP名称参数,值是用户输入,并将所有附件保存在一个固定的目录中,稍后您可以重新命名所选目录的名称。这里Connections是我们自定义的接口,具有连接对象。
public class ServletCommonfunctions extends HttpServlet implements
        Connections {

    private static final long serialVersionUID = 1L;

    public ServletCommonfunctions() {}

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException,
                          IOException {}

    public SortedMap<String, String> savefilesindirectory(
            HttpServletRequest request, HttpServletResponse response)
            throws IOException {

        // Map<String, String> key_values = Collections.synchronizedMap(new
        // TreeMap<String, String>());
        SortedMap<String, String> key_values = new TreeMap<String, String>();
        String dist = null, fact = null;
        PrintWriter out = response.getWriter();
        File file;
        String filePath = "E:\\FSPATH1\\2KL06CS048\\";
        System.out.println("Directory Created   ????????????"
            + new File(filePath).mkdir());
        int maxFileSize = 5000 * 1024;
        int maxMemSize = 5000 * 1024;

        // Verify the content type
        String contentType = request.getContentType();
        if ((contentType.indexOf("multipart/form-data") >= 0)) {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // Maximum size that will be stored in memory
            factory.setSizeThreshold(maxMemSize);
            // Location to save data that is larger than maxMemSize.
            factory.setRepository(new File(filePath));
            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);
            // maximum file size to be uploaded.
            upload.setSizeMax(maxFileSize);
            try {
                // Parse the request to get file items.
                @SuppressWarnings("unchecked")
                List<FileItem> fileItems = upload.parseRequest(request);
                // Process the uploaded file items
                Iterator<FileItem> i = fileItems.iterator();
                while (i.hasNext()) {
                    FileItem fi = (FileItem) i.next();
                    if (!fi.isFormField()) {
                        // Get the uploaded file parameters
                        String fileName = fi.getName();
                        // Write the file
                        if (fileName.lastIndexOf("\\") >= 0) {
                            file = new File(filePath
                                + fileName.substring(fileName
                                        .lastIndexOf("\\")));
                        } else {
                            file = new File(filePath
                                + fileName.substring(fileName
                                        .lastIndexOf("\\") + 1));
                        }
                        fi.write(file);
                    } else {
                        key_values.put(fi.getFieldName(), fi.getString());
                    }
                }
            } catch (Exception ex) {
                System.out.println(ex);
            }
        }
        return key_values;
    }
}

@buhake sindi嗨,如果我使用实时服务器或通过上传文件到服务器来运行项目,文件路径应该是什么? - AmanS
2
如果您在实时服务器中编写一个创建目录的Servlet代码,则该目录将被创建在实时服务器上的任何目录中。 - Nagappa L M

7

对于Spring MVC

我成功地实现了一个更简单的版本,它能够处理表单输入,包括数据和图片。

<form action="/handleform" method="post" enctype="multipart/form-data">
    <input type="text" name="name" />
    <input type="text" name="age" />
    <input type="file" name="file" />
    <input type="submit" />
</form>

处理控制器

@Controller
public class FormController {
    @RequestMapping(value="/handleform",method= RequestMethod.POST)
    ModelAndView register(@RequestParam String name, @RequestParam int age, @RequestParam MultipartFile file)
            throws ServletException, IOException {

        System.out.println(name);
        System.out.println(age);
        if(!file.isEmpty()){
            byte[] bytes = file.getBytes();
            String filename = file.getOriginalFilename();
            BufferedOutputStream stream =new BufferedOutputStream(new FileOutputStream(new File("D:/" + filename)));
            stream.write(bytes);
            stream.flush();
            stream.close();
        }
        return new ModelAndView("index");
    }
}

请问您能否从MySQL数据库中选择图像并在JSP/HTML上显示它? - Onic Team

6

如果你正在使用内嵌Tomcat的Geronimo,这个问题的另一个来源是出现了。在这种情况下,在多次测试Commons IO和commons-fileupload之后,问题来自于处理commons-xxx JAR文件的父类加载器。这必须被防止。崩溃总是发生在:

fileItems = uploader.parseRequest(request);

请注意,当前版本的commons-fileupload中fileItems的List类型已更改为特定类型List<FileItem>,而以前的版本中它是通用类型List
我将commons-fileupload和Commons IO的源代码添加到我的Eclipse项目中,以跟踪实际错误并最终获得了一些见解。首先,抛出的异常类型为Throwable,而不是所述的FileIOException甚至Exception(这些都不会被捕获)。其次,错误消息是模糊的,因为它声明找不到类,因为轴2找不到commons-io。我的项目根本没有使用Axis2,但它作为标准安装的Geronimo存储库子目录中的文件夹存在。
最后,我发现一个提供有效解决方案的地方,成功解决了我的问题。您必须在部署计划中隐藏父加载程序中的JAR文件。这被放入我的完整文件如下的geronimo-web.xml文件中。

http://osdir.com/ml/user-geronimo-apache/2011-03/msg00026.html粘贴:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web:web-app xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
    <dep:environment>
        <dep:moduleId>
            <dep:groupId>DataStar</dep:groupId>
            <dep:artifactId>DataStar</dep:artifactId>
            <dep:version>1.0</dep:version>
            <dep:type>car</dep:type>
        </dep:moduleId>

        <!-- Don't load commons-io or fileupload from parent classloaders -->
        <dep:hidden-classes>
            <dep:filter>org.apache.commons.io</dep:filter>
            <dep:filter>org.apache.commons.fileupload</dep:filter>
        </dep:hidden-classes>
        <dep:inverse-classloading/>

    </dep:environment>
    <web:context-root>/DataStar</web:context-root>
</web:web-app>

链接(实际上)已经损坏(重定向到 https://osdir.com/)- HTTPS 版本也是如此。 - Peter Mortensen

0

这里是一个使用Apache Commons-FileUpload的示例:

// apache commons-fileupload to handle file upload
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File(DataSources.TORRENTS_DIR()));
ServletFileUpload fileUpload = new ServletFileUpload(factory);

List<FileItem> items = fileUpload.parseRequest(req.raw());
FileItem item = items.stream()
  .filter(e ->
  "the_upload_name".equals(e.getFieldName()))
  .findFirst().get();
String fileName = item.getName();

item.write(new File(dir, fileName));
log.info(fileName);

0

首先,您必须将表单的enctype属性设置为"multipart/form-data"

如下所示。

<form action="Controller" method="post" enctype="multipart/form-data">
     <label class="file-upload"> Click here to upload an Image </label>
     <input type="file" name="file" id="file" required>
</form>

然后,在Servlet“Controller”中添加一个多部分注释,以指示在servlet中处理多部分数据。
完成此操作后,检索通过表单发送的部分,然后检索提交文件的文件名(带路径)。使用此信息在所需路径中创建新文件,并将文件的各个部分写入新创建的文件中以重新创建文件。
如下所示:
@MultipartConfig

public class Controller extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        insertImage(request, response);
    }

    private void addProduct(HttpServletRequest request, HttpServletResponse response) {
        Part filePart = request.getPart("file");
        String imageName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();

        String imageSavePath = "specify image path to save image"; //path to save image
        FileOutputStream outputStream = null;
        InputStream fileContent = null;

        try {
            outputStream = new FileOutputStream(new File(imageSavePath + File.separator + imageName));
            // Creating a new file with file path and the file name
            fileContent = filePart.getInputStream();
            // Getting the input stream
            int readBytes = 0;
            byte[] readArray = new byte[1024];
            // Initializing a byte array with size 1024

            while ((readBytes = fileContent.read(readArray)) != -1) {
                outputStream.write(readArray, 0, readBytes);
            } // This loop will write the contents of the byte array unitl the end to the output stream
        } catch (Exception ex) {
            System.out.println("Error Writing File: " + ex);
        } finally {
            if (outputStream != null) {
                outputStream.close();
                // Closing the output stream
            }
            if (fileContent != null) {
                fileContent.close();
                // Closing the input stream
            }
        }
    }
}

1
这个解决方案与其他解决方案不同。其他解决方案使用库来处理文件,而这个解决方案则不需要第三方的jar文件。 - Lakindu Hewawasam
1
这个问题已经被当前接受的答案解决了。你读过它吗?本地API自2009年12月就已经存在了。顺便说一下,你关闭流的方式也是遗留的。自2011年7月推出的Java 7中,你可以使用try-with-resources语句来代替在finally中进行null检查。 - BalusC

-1

您可以使用JSP / Servlet上传文件。

<form action="UploadFileServlet" method="post">
    <input type="text" name="description" />
    <input type="file" name="file" />
    <input type="submit" />
</form>

另一方面,在服务器端,请使用以下代码。

package com.abc..servlet;

import java.io.File;
---------
--------


/**
 * Servlet implementation class UploadFileServlet
 */
public class UploadFileServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public UploadFileServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.sendRedirect("../jsp/ErrorPage.jsp");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        PrintWriter out = response.getWriter();
        HttpSession httpSession = request.getSession();
        String filePathUpload = (String) httpSession.getAttribute("path") != null ? httpSession.getAttribute("path").toString() : "" ;

        String path1 = filePathUpload;
        String filename = null;
        File path = null;
        FileItem item = null;


        boolean isMultipart = ServletFileUpload.isMultipartContent(request);

        if (isMultipart) {
            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            String FieldName = "";
            try {
                List items = upload.parseRequest(request);
                Iterator iterator = items.iterator();
                while (iterator.hasNext()) {
                     item = (FileItem) iterator.next();

                        if (fieldname.equals("description")) {
                            description = item.getString();
                        }
                    }
                    if (!item.isFormField()) {
                        filename = item.getName();
                        path = new File(path1 + File.separator);
                        if (!path.exists()) {
                            boolean status = path.mkdirs();
                        }
                        /* Start of code fro privilege */

                        File uploadedFile = new File(path + Filename);  // for copy file
                        item.write(uploadedFile);
                        }
                    } else {
                        f1 = item.getName();
                    }

                } // END OF WHILE
                response.sendRedirect("welcome.jsp");
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Start of code for privilege”是什么意思(似乎无法理解)?请通过编辑(更改)您的答案来回应,而不是在评论中回复(不包括“Edit:”,“Update:”或类似内容 - 答案应该看起来像是今天写的)。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接