当前位置: 首页 > 知识库问答 >
问题:

使用commons fileupload(空列表)通过JSP解析本地驱动器中的文件

司徒元明
2023-03-14

我正在尝试将文件从本地驱动器(Windows 10)解析到Linux机器上运行的服务器。servlet的版本低于3.0,所以我使用的是Apache FileUpload和IO jar。我在解析文件时遇到了两个问题。

使用提交

第二个更严重的问题是我无法将解析的数据上传到List。提交表单后,列表为空。我已经注释掉了jsp形式的每个方法,所以我不应该在Apache上传之前读取和解析请求正文(但我不确定如何在尝试读取文件之前验证正文是否为空)。我也尝试上传文本而不是文件(检查是否有问题尝试访问Windows文件系统),但没有成功。

也许我错过了一些明显的东西。你能给我一些提示如何解决这个问题。谢谢

JSP(旧文件)

<%@ page language="java" %>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ include file="upload_function.jspf" %>
<%String pageLanguage=getLanguage(request);%>
<%@ MultipartConfig%>
<%@WebServlet("/upload")%>

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="upload.css"></link>
    </head>
    <body>
        <form action="" method="post" enctype="multipart/form-data" ></form>
            <div>
                <tr>
                    <h4>Uploaded File:</h4>
                    <%=getLocalImage(request)%>
                </tr>
            </div>

<div>
                <tr>
                    <label for=""><h4>File Upload:</h4></label>
                    <input type="file" id="image" name="image" accept="image/png, image/jpeg"  >                    
                    <input type = "submit" value = "Upload File" >          
                </tr>
            </div>

            <div>
                <tr>
                    <p>
                        <button id="ok" onclick="document.forms[0].submit();return false;">Submit</button>
                        <button id="cancel" onclick="javascript:window.close();return false;">Ok</button>
                    </p>
                </tr>
            </div>
        </form>
    </body>
</html>

JSPF(旧文件)

<%@ page import="java.io.*" %>
<%@ page import="java.util.*" %>
<%@ page import="javax.servlet.*" %>
<%@ page import="org.apache.commons.fileupload.disk.*" %>
<%@ page import="org.apache.commons.fileupload.servlet.*" %>
<%@ page import="org.apache.commons.fileupload.*" %>
<%@ page import="org.apache.commons.io.*" %>

<%!

public String getLocalImage(HttpServletRequest request) throws ServletException, IOException 
    {
        String result = "null";
        String UPLOAD_DIRECTORY = "/final/directory/for/file/upload/";

        // Check the content
        if(ServletFileUpload.isMultipartContent(request)){
            try {
                // Create a factory for disk-based file items
                DiskFileItemFactory factory = new DiskFileItemFactory();

                // Configure a repository (to ensure a secure temp location is used)
                ServletContext servletContext = this.getServletConfig().getServletContext();
                File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
                factory.setSizeThreshold(40960);
                factory.setRepository(repository);

                // Create a new file upload handler
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setSizeMax(2000000);

                // Parse the request
                try {
                    List<FileItem> items = upload.parseRequest(request);
                }
                catch(Exception ex){
                    ex.printStackTrace();
                }

                // Process the uploaded items
                Iterator<FileItem> iter = items.iterator();

                File uploadedFile = new File(UPLOAD_DIRECTORY,"picture.png");

                // List<FileItem> items is empty - error trying to use the iterator
                FileItem item = iter.next();

                item.write(uploadedFile);
                result = "file upload successful";
            }
            catch (Exception t) {
                t.printStackTrace();
                return result;
            }     
            return result;
        }
        else {
            return "not multipart";
        }
    }

%>

编辑:所以我认为主要问题是,我没有通过表单中的action属性将jsp文件与servlet连接起来。我已经创建了上传servlet的功能示例,但我需要将UploadServlet类导入JSP文件,而无需实际使用. java项目文件。我已经创建了UploadServlet类的jar文件,并将jar文件添加到Web应用程序的WEB-INF/lib文件夹中。但是当我尝试创建UploadServlet类的实例时,IDE告诉我它无法解析为该类型。

是否可以像这样将用户定义的类导入JSP?我是否需要更多的依赖项?我不确定tomcatservlet-api.jar,UploadServlet jar可能正在尝试使用它,但servlet-api类在Web应用程序之外。但是,不可能将servlet-api.jar直接包含在WEB-INF/lib Web应用程序下。

UploadServlet.java---

package test.pkg;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    public UploadServlet() {
        super();
        // constructor
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // doPost implementation
    }
}
        

带有UploadServlet的JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="test.pkg.UploadServlet" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>File Upload</title>
</head>
<body>
        <form method="post" action="UploadServlet" enctype="multipart/form-data">
            Select file to upload: <input type="file" name="uploadFile" />
            <input type="submit" value="Upload" />
            <%
                UploadServlet servletUp = new UploadServlet();
                servletUp.doPost(request, response);
            %>
        </form>
</body>
</html>

共有1个答案

郭元明
2023-03-14
匿名用户

我回答你之前的评论,你问Servlet是否可以在JSP中定义,因为你不确定在这个项目中是否可以访问Java类。

您可以像访问任何其他 servlet(JSP 是一个 servlet)一样,访问任何 JSP 内部的请求和响应。也就是说,您应该将表单与其值的处理分开。通常可以使用的一种很好的模式是重定向后获取。

我用JSTL的形式,因为这是更好的做法。

为了处理另一个JSP中的请求,我被迫求助于脚本,这通常是设计不好的标志,但考虑到你不能编辑Java源代码,没有其他选择......

包含表单的页面:fileUploadForm.jsp

将表单设置为POST到另一个页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8">
        <title>My upload file test form</title>
    </head>
    <body>
        <h1>My upload file test form</h1>
        
        <!-- Display messages -->
        <div class="messages">
            <c:if test="${not empty sessionScope.uploadErrors}">
                <c:forEach items="${sessionScope.uploadErrors}" var="err">
                    <p class="error"><c:out value="${err}" /></p>
                </c:forEach>
            </c:if>
            <c:if test="${not empty sessionScope.uploadSuccess}">
                <p class="success">File uploaded successfully: <c:out value="${sessionScope.uploadSuccess}" /></p>
            </c:if>
        </div>
        
        <!-- Form with POST action pointing to uploadFormAction.jsp -->
        <form name="upload-test" action="./uploadFormAction.jsp" method="POST" enctype="multipart/form-data">
            <label for="upload">Upload file:</label>
            <input type="file" name="uploaded" id="upload" accept="image/png" />
            <div class="submits">
                <input type="submit" value="Send" />
            </div>
        </form>
    </body>
</html>

带有数据处理代码的JSP:< code > file upload action . JSP

处理 POST 请求,记录结果(错误或成功),然后重定向回窗体以显示它们

<%@page import="org.apache.commons.fileupload.FileItem"%>
<%@page import="java.io.File"%>
<%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    //Storage for error messages
    List<String> errors = new ArrayList<>();
    session.setAttribute("uploadErrors", errors);
    session.setAttribute("uploadSuccess", null);

    //Check for correct form encoding
    if (!"POST".equalsIgnoreCase(request.getMethod())) {
        errors.add("Form must have method=\"POST\"");
    }
    if (!ServletFileUpload.isMultipartContent(request)) {
        errors.add("Form has no multipart data to read from");
    }
    
    if (errors.size() < 1) {
        
        try {
        
            // Create a factory for disk-based file items
            DiskFileItemFactory factory = new DiskFileItemFactory();
    
            // Configure a repository (to ensure a secure temp location is used)
            ServletContext servletContext = this.getServletConfig().getServletContext();
            File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
            factory.setRepository(repository);
    
            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setSizeMax(4L * 1024 * 1024);
    
            // Parse the request
            List<FileItem> items = upload.parseRequest(request);
            String found = null;
            
            for (FileItem item : items) {
                if (item.isFormField()) {
                    //Process other fields in form
                } else if ("uploaded".equals(item.getFieldName())) {
                    if (item.getSize() > 0) {
                        if (found != null) {
                            errors.add("Only one file allowed");
                        } else {
                            found = item.getName();
                            File uploadedFile = new File("./uploads/","picture.png");
                            if (uploadedFile.exists()) uploadedFile.delete();
                            item.write(uploadedFile);
                        }
                    }
                } else { //Other file field
                    //Ignore it ? error ?
                }
            }
            if (found == null) {
                errors.add("No uploaded file !");
            }
            session.setAttribute("uploadSuccess", found);
        } catch (Exception e) {
            e.printStackTrace();
            //Should log it and return it in a more readable form
            errors.add(e.getMessage());
        }
        
    }
        
    response.sendRedirect("uploadFormPage.jsp");

%>

现在考虑您的问题编辑,如果您已经定义了< code>servlet类,并希望从JSP中调用它,那么我认为您可以使用这里描述的相同原则,创建一个新的Servlet实例来调用它的< code>doPost方法,在那里您可以获得Post请求,但是这是假设您的Servlet是无状态的,并且不使用来自web.xml的init参数...

如果您可以编写一个 Servlet,您应该如何做

  1. 保持相同的表单代码,只需更改您的的目的地。
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/uploadFile")
public class FileUploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        //Storage for error messages
        List<String> errors = new ArrayList<>();
        session.setAttribute("uploadErrors", errors);
        session.setAttribute("uploadSuccess", null);

        //Check for correct form encoding
        if (!"POST".equalsIgnoreCase(request.getMethod())) {
            errors.add("Form must have method=\"POST\"");
        }
        if (!ServletFileUpload.isMultipartContent(request)) {
            errors.add("Form has no multipart data to read from");
        }
        
        if (errors.size() < 1) {
            
            try {
            
                // Create a factory for disk-based file items
                DiskFileItemFactory factory = new DiskFileItemFactory();
        
                // Configure a repository (to ensure a secure temp location is used)
                ServletContext servletContext = this.getServletConfig().getServletContext();
                File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
                factory.setRepository(repository);
        
                // Create a new file upload handler
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setSizeMax(4L * 1024 * 1024);
        
                // Parse the request
                List<FileItem> items = upload.parseRequest(request);
                String found = null;
                
                for (FileItem item : items) {
                    if (item.isFormField()) {
                        //Process other fields in form
                    } else if ("uploaded".equals(item.getFieldName())) {
                        if (item.getSize() > 0) {
                            if (found != null) {
                                errors.add("Only one file allowed");
                            } else {
                                found = item.getName();
                                File uploadedFile = new File("./uploads/","picture.png");
                                if (uploadedFile.exists()) uploadedFile.delete();
                                item.write(uploadedFile);
                            }
                        }
                    } else { //Other file field
                        //Ignore it ? error ?
                    }
                }
                if (found == null) {
                    errors.add("No uploaded file !");
                }
                session.setAttribute("uploadSuccess", found);
            } catch (Exception e) {
                e.printStackTrace();
                //Should log it and return it in a more readable form
                errors.add(e.getMessage());
            }
            
        }
        
        response.sendRedirect("uploadFormPage.jsp");
    }

}

 类似资料:
  • 我正在使用Drive api从Google Drive检索文件列表,使用以下Java代码: 使用getAlternateLink方法,我得到了这个URL。 我的问题是如何编写一个代码来获取'/spreadsheet'位置,而不是URL中的'/file'。即-

  • 问题内容: 如何解析一个JSON文件以检索其所有数据并在我的代码中使用它? 我试过导入文件,只是尝试控制台记录它,但是它所做的只是打印对象{}: 这是我的file.json的样子: 我希望能够访问每个组件的名字和姓氏并将其打印在网站上。 问题答案: https://jsfiddle.net/c9wupvo6/

  • 我试图使用Apache FOP为我正在开发的应用程序创建PDF文档。 这需要我创建一个有效的XSL-FO文件,然后FOP引擎解析该文件以格式化它创建的文档样式。 XSL文件具有自定义命名空间,这使得FOP引擎在尝试解析文件时抛出错误。我得到的错误是, XSL/XML文件中的命名空间示例: 通过XSL解析的FOP JSP文件代码: 现在,将命名空间添加到已经创建的 XML 文档涉及的内容与我需要添加

  • 我使用以下JCIFS代码将文件从本地磁盘复制到共享驱动器 复制10 mb文件需要10分钟以上。而当我直接复制同一个文件时,大约需要1分钟。我尝试了3种方法来复制文件(请参阅代码的注释部分),但没有一种方法显示出任何显著的差异。 是否有任何方法可以提高JCIFS的性能?

  • 我为任何不清晰的地方提前道歉(我是编程新手)。我正在尝试用lxml解析一组本地文件。埃特里。我使用lxml(和xpath)编写了一个解析脚本,该脚本从SEC网页中查找相关数据并导出到。csv文件。该脚本适用于单个url,但我想将其推广到数千个html页面。我已经在本地下载了所有的html文件(我使用curl获取链接,wget下载)——但是我没有成功地替换我的解析器。有效的旧版本是: 我试着用etr

  • 介绍 首先让我介绍一下我要做的事情的目标。 > 之前我把一个文件分成两部分 这两个文件的大小加在一起可能超过50 MB(作为一个长期目标)。由于UrlFetchApp.fetch()对请求的大小有限制,我想单独上传它们,其中每个文件将小于50 MB,并因此合并它们。现在(尝试驱动器API),我使用小文件。 第一个文件是 (是 ) 。我意识到我之前犯了一个错误,即我使用的文件大小是256的倍数,但它