使用共享文件上传(空列表)通过JSP从本地驱动器解析文件<FileItem>



我正试图从本地驱动器(Windows 10)解析文件到运行在Linux盒子上的服务器。servlet小于3.0版本,所以我使用Apache FileUpload和IO jar。我有两个问题试图解析文件。

使用<input type = "submit" value = "Upload File" >的提交目前不会提交数据,所以我使用<button id="ok" onclick="document.forms[0].submit();return false;">Submit</button>

第二个更严重的问题是,我不能上传解析过的数据到List。提交表单后,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吗?例如,我是否需要更多的依赖项?我不确定tomcat servlet-api.jar是什么,UploadServlet jar可能试图使用它,但servlet-api类在web应用程序之外。然而,不可能直接在web - inf/lib web应用程序下包含servlet-api.jar。

UploadServlet.java——比;UploadServlet.jar

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
}
}

JSP with UploadServlet

<%@ 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>

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

您可以访问任何JSP中的请求和响应,就像访问任何其他servlet一样(JSP是servlet)。也就是说,应该将表单与其值的处理分离开来。一般来说,使用POST-REDIRECT-GET模式比较好。

我使用JSTL的形式,因为这是更好的实践。

要处理另一个JSP中的请求,我不得不求助于scriptlet,这通常是糟糕设计的标志,但考虑到您不能编辑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与数据处理代码:fileUploadAction.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");
%>

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

如果你可以写一个Servlet你应该怎么做呢?

  1. 保持相同的表单代码,只是将<form>的目的地更改为action="<c:url value ="/uploadFile" />"
  2. 创建url模式设置为"/uploadFile"处理POST(例如使用@WebServlet注释),和fileUploadAction.jsp相同的代码
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");
}
}

相关内容

最新更新