时,request.getParameter() 返回 null。在研究过程中,我偶然发现了 Apache Common FileUpload。我试过这个:不幸的是,servlet 在没有明确消......" /> 时,request.getParameter() 返回 null。在研究过程中,我偶然发现了 Apache Common FileUpload。我试过这个:不幸的是,servlet 在没有明确消......"> 时,request.getParameter() 返回 null。在研究过程中,我偶然发现了 Apache Common FileUpload。我试过这个:不幸的是,servlet 在没有明确消......" />
ChatGPT解决这个技术问题 Extra ChatGPT

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

如何使用 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" 添加到 <form> 时,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)
也许这篇文章会有所帮助:baeldung.com/upload-file-servlet
@Adam:他们抄袭了我的回答,并在上面添加了一些广告侦探,试图用它来赚钱。是的,很棒的文章..
不,实际上没有复制任何内容。我写了那篇文章的初稿以及补充代码。核心参考文档可在此处找到:commons.apache.org/proper/commons-fileupload/using.html(链接到文章并在文章中引用)。示例部分来自核心参考文档(这是参考文档的点 - 即作为参考点),但不是全部(请注意,参考文档没有详细说明)。谢谢!

B
BalusC

介绍

要浏览并选择要上传的文件,您需要表单中的 HTML <input type="file"> 字段。如 HTML specification 中所述,您必须使用 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 时相比,二进制多部分表单数据在 a different format 的请求正文中可用。

在 Servlet 3.0(2009 年 12 月)之前,Servlet API 本身并不支持 multipart/form-data。它仅支持 application/x-www-form-urlencoded 的默认表单编码类型。使用多部分表单数据时,request.getParameter() 及其关联都将返回 null。这就是众所周知的 Apache Commons FileUpload 出现的地方。

不要手动解析它!

理论上,您可以根据 ServletRequest#getInputStream() 自己解析请求正文。然而,这是一项精确而乏味的工作,需要精确的RFC2388知识。您不应该尝试自己执行此操作或复制粘贴在 Internet 上其他地方找到的一些本地开发的无库代码。许多在线资源在这方面都失败了,例如roseindia.net。另见uploading of pdf file。您应该使用数百万用户多年来使用(并经过隐式测试!)的真实库。这样的库已经证明了它的健壮性。

如果您已经使用 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() 可以按通常的方式使用普通表单字段。

首先使用 @MultipartConfig 注释您的 servlet,以使其识别和支持 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 时,手动获取提交的文件名

请注意,在 Servlet 3.1 中引入了 Part#getSubmittedFileName()(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 来解析多部分表单数据请求。它具有出色的 User GuideFAQ(仔细检查两者)。还有 O'Reilly ("cos") MultipartRequest,但它有一些(小)错误,并且多年来不再积极维护。我不建议使用它。 Apache Commons FileUpload 仍在积极维护中,目前非常成熟。

为了使用 Apache Commons FileUpload,您的 web 应用程序的 /WEB-INF/lib 中至少需要有以下文件:

commons-fileupload.jar

commons-io.jar

您最初的尝试很可能失败了,因为您忘记了公共 IO。

以下是使用 Apache Commons FileUpload 时您的 UploadServletdoPost() 的启动示例:

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 将获得一个空的请求正文。另请参见 ServletFileUpload#parseRequest(request) returns an empty list

请注意 FilenameUtils#getName()。这是关于获取文件名的 MSIE 修复。此浏览器错误地沿名称发送完整文件路径,而不仅仅是文件名。

或者,您也可以将这一切包装在一个 Filter 中,它会自动解析所有内容并将这些内容放回请求的参数映射中,以便您可以继续使用 request.getParameter() 并通过 request.getAttribute() 检索上传的文件。 You can find an example in this blog article

getParameter() 的 GlassFish3 错误的解决方法仍然返回 null

请注意,早于 3.1.2 的 Glassfish 版本具有 a 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 变量)正确保存到磁盘或数据库的详细信息,请参阅以下答案:

在 servlet 应用程序中保存上传文件的推荐方法

如何上传图像并将其保存在数据库中?

如何将 Part 转换为 Blob,以便将其存储在 MySQL 中?

提供上传的文件

前往以下答案以获取有关将保存的文件从磁盘或数据库正确提供回客户端的详细信息:

使用 标签从 webapps / webcontext / deploy 文件夹外部加载图像

如何在 JSP 页面中从数据库中检索和显示图像?

在 Java Web 应用程序中从应用程序服务器外部提供静态数据的最简单方法

支持 HTTP 缓存的静态资源 servlet 的抽象模板

Ajaxifying 表单

前往以下答案如何使用 Ajax(和 jQuery)上传。请注意,不需要为此更改收集表单数据的 servlet 代码!只有您的响应方式可能会改变,但这相当简单(即,不是转发到 JSP,而是打印一些 JSON 或 XML,甚至是纯文本,具体取决于负责 Ajax 调用的脚本所期望的内容)。

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

通过 XMLHttpRequest 将文件作为多部分发送

HTML5 拖放文件上传到 Java Servlet

希望这一切都有帮助:)


啊抱歉,我看到 request.getParts("file") 很困惑 x_x
对于 Servlet 3.0,如果违反了 MultipartConfig 条件(例如:maxFileSize),则调用 request.getParameter() 将返回 null。这是故意的吗?如果我在调用 getPart(并检查 IllegalStateException)之前得到一些常规(文本)参数怎么办?这会导致在我有机会检查 IllegalStateException 之前抛出 NullPointerException
@BalusC 我创建了一个与此相关的帖子,你知道我如何从 File API webKitDirectory 中检索额外的信息。在此处了解更多详情stackoverflow.com/questions/45419598/…
是的,如果有人尝试将 3.0 部分中的代码与 tomcat 7 一起使用,他们可能会遇到与我类似的String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.部分问题
@aaa:当您出于不清楚的原因使用 Reader 和/或 Writer 将字节转换为字符时,可能会发生这种情况。不要那样做。在读取和写入上传的文件期间,在所有位置使用 InputStream/OutputStream,而不将字节转换为字符。 PDF 文件不是基于字符的文本文件。它是一个二进制文件。
P
Peter Mortensen

如果您碰巧使用 Spring MVC,这就是如何(我把它留在这里以防有人发现它有用):

使用将 enctype 属性设置为“multipart/form-data”(与 BalusC's answer 相同)的表单:

<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...
j
joseluisbz

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

在 web.xml 文件中启用上传:

Manually Installing PHP, Tomcat and 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-size、max-request-size 和其他您可以设置的选项...


P
Peter Mortensen

您需要将 common-io.1.4.jar 文件包含在您的 lib 目录中,或者如果您正在使用任何编辑器(如 NetBeans),那么您需要转到项目属性并添加 JAR 文件即可。

要获取 common.io.jar 文件,只需通过 google 搜索或访问 Apache Tomcat 网站,您可以在其中选择免费下载此文件。但请记住一件事:如果您是 Windows 用户,请下载二进制 ZIP 文件。


找不到 .jar.zip。你是说.zip吗?
P
Peter Mortensen

我为每个 HTML 表单使用一个通用的 Servlet,无论它是否有附件。

此 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 嘿,如果我使用实时服务器或者我通过将文件上传到服务器来实现我的项目,那么文件路径应该是什么
实时服务器中的任何目录。如果您编写代码在 servlet 中创建目录,则将在实时服务器中创建目录
P
Peter Mortensen

对于 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");
    }
}

你能分享选择图像表格db mysql并在jsp/html上显示吗?
P
Peter Mortensen

如果您将 Geronimo 与它的嵌入式 Tomcat 一起使用,则会出现此问题的另一个来源。在这种情况下,在测试 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(这些不会被捕获)。其次,错误消息很容易混淆,因为它声明类未找到,因为axis2 找不到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 版本也是如此。
t
thouliha

这是一个使用 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);

P
Peter Mortensen

您首先必须将表单的 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“控制器”中为 Multi-part 添加 Annotation,以指示在 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
            }
        }
    }
}

这个解决方案是不同的。其他解决方案使用一个库来处理文件,因为这没有第三方 jar 文件。
当前接受的答案已经涵盖了这一点。你读过吗?自 2009 年 12 月以来,本机 API 已经存在。顺便说一下,您关闭流的方式也是遗留的。从 2011 年 7 月推出的 Java 7 开始,您可以使用 try-with-resources 语句而不是在 finally 中摆弄 nullchecks。
P
Peter Mortensen

在没有十亿个库的情况下,我可以为文件和输入控件提出最简单的方法:

  <%
      if (request.getContentType() == null)
          return;
      // For input type=text controls
      String v_Text =
          (new BufferedReader(new InputStreamReader(request.getPart("Text1").getInputStream()))).readLine();

      // For input type=file controls
      InputStream inStr = request.getPart("File1").getInputStream();
      char charArray[] = new char[inStr.available()];
      new InputStreamReader(inStr).read(charArray);
      String contents = new String(charArray);
  %>

<% 是做什么用的? ASP.NET (C#)?你能澄清一下吗?请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的)。
P
Peter Mortensen

利用:

DiskFileUpload upload = new DiskFileUpload();

你必须从这个对象中获取文件项和字段,然后你可以像下面这样存储到服务器中:

String loc = "./webapps/prjct name/server folder/" + contentid + extension;
File uploadFile = new File(loc);
item.write(uploadFile);

P
Peter Mortensen

您可以使用 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 fro privilege" 是什么意思(似乎难以理解)?请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似内容 - 答案应该看起来好像是今天写的)。
P
Peter Mortensen

网页

<html>
    <head>
        <title>File Uploading Form</title>
    </head>

    <body>
        <h3>File Upload:</h3>
        Select a file to upload: <br />
        <form action="UploadServlet" method="post"
              enctype="multipart/form-data">

            <input type="file" name="file" size="50" />
            <br />
            <input type="submit" value="Upload File" />
        </form>
    </body>
</html>

小服务程序文件

// Import required java libraries
import java.io.*;
import java.util.*;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.output.*;

public class UploadServlet extends HttpServlet {

    private boolean isMultipart;
    private String filePath;
    private int maxFileSize = 50 * 1024;
    private int maxMemSize = 4 * 1024;
    private File file;

    public void init() {
        // Get the file location where it would be stored.
        filePath =
               getServletContext().getInitParameter("file-upload");
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
               throws ServletException, java.io.IOException {

        // Check that we have a file upload request
        isMultipart = ServletFileUpload.isMultipartContent(request);
        response.setContentType("text/html");
        java.io.PrintWriter out = response.getWriter();
        if (!isMultipart) {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet upload</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<p>No file uploaded</p>");
            out.println("</body>");
            out.println("</html>");
            return;
        }

        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("c:\\temp"));

        // 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.
            List fileItems = upload.parseRequest(request);

            // Process the uploaded file items
            Iterator i = fileItems.iterator();

            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet upload</title>");
            out.println("</head>");
            out.println("<body>");
            while (i.hasNext())
            {
                FileItem fi = (FileItem)i.next();
                if (!fi.isFormField())
                {
                     // Get the uploaded file parameters
                     String fieldName = fi.getFieldName();
                     String fileName = fi.getName();
                     String contentType = fi.getContentType();
                     boolean isInMemory = fi.isInMemory();
                     long sizeInBytes = fi.getSize();

                     // 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);
                     out.println("Uploaded Filename: " + fileName + "<br>");
                }
            }
            out.println("</body>");
            out.println("</html>");
        }
        catch(Exception ex) {
            System.out.println(ex);
        }
    }

    public void doGet(HttpServletRequest request,
                        HttpServletResponse response)
            throws ServletException, java.io.IOException {

        throw new ServletException("GET method used with " +
                 getClass().getName() + ": POST method required.");
    }
}

文件 web.xml

编译上面的 servlet UploadServlet 并在 web.xml 文件中创建所需的条目,如下所示。

<servlet>
   <servlet-name>UploadServlet</servlet-name>
   <servlet-class>UploadServlet</servlet-class>
</servlet>

<servlet-mapping>
   <servlet-name>UploadServlet</servlet-name>
   <url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>

P
Peter Mortensen

为文件发送多个文件,我们必须使用 enctype="multipart/form-data"

要发送多个文件,请在 input 标记中使用 multiple="multiple"

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

我们将如何做 getPart("fileattachments") 以便我们得到一个 Parts 数组?我不认为多个文件的 getPart 会起作用吗?
“为文件发送多个文件” 是什么意思(似乎难以理解)?请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似内容 - 问题/答案应该显示为今天写的)。