我正在学习java servlet编程,我编写了一个上传文件的程序,我对程序有一个奇怪的问题。当它说它完成上传文件时,当我点击链接看到它我得到一个404错误,当我检查目录(文件应该保存在哪里)时它是空的。我检查了日志并且没有错误消息。我从一本书中获取了代码,用于学习servlet和jsp。
这是我的java代码
import java.io.*;
import java.util.*;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FileUpload
*/
@WebServlet("/FileUpload")
public class FileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public FileUpload() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.print("File upload success. <a href=\"/Project_One/files");
out.print("\">Click here to browse through all uploaded ");
out.println("files.</a><br>");
ServletInputStream sis = request.getInputStream();
StringWriter sw = new StringWriter();
int i = sis.read();
for(;i!=-1 && i!= '\r';i=sis.read())
{
sw.write(i);
}
sis.read(); //ditch \'n'
String delimiter = sw.toString();
while(true)
{
StringWriter h = new StringWriter();
int[] temp = new int[4];
temp[0] = (byte)sis.read();
temp[1] = (byte)sis.read();
temp[2] = (byte)sis.read();
h.write(temp[0]);
h.write(temp[1]);
h.write(temp[2]);
//read header
for(temp[3]=sis.read();temp[3]!=-1;temp[3]=sis.read())
{
if(temp[0] == '\r' &&
temp[1] == '\n' &&
temp[2] == 'r' &&
temp[3] == '\n')
{
break;
}
h.write(temp[3]);
temp[0]= temp[1];
temp[1]= temp[2];
temp[2]= temp[3];
}
String header = h.toString();
int StartName = header.indexOf("name=\"");
int endName = header.indexOf("\"",StartName+6);
if(StartName == -1|| endName == -1)
{
break;
}
String name = header.substring(StartName+6,endName);
if(name.equals("file"))
{
StartName = header.indexOf("filename=\"");
endName = header.indexOf("\"",StartName+10);
String filename = header.substring(StartName+10,endName);
ServletConfig config = getServletConfig();
ServletContext sc = config.getServletContext();
//File file = new File(sc.getRealPath("/files"));
//file.mkdirs();
FileOutputStream fos = new FileOutputStream(sc.getRealPath("/")+"/"+filename);
//write the file to disk
int length = delimiter.length();
//delimiter ="\r\n"+delimiter;
byte[] body = new byte[delimiter.length()];
for(int j=0;j<body.length-1;j++)
{
body[j]=(byte)sis.read();
fos.write(body[j]);
}
//check it wasn't a 0 length file
//if(!delimiter.equals(new String (body)))
//{
int e = body.length-1;
i=sis.read();
for(;i!=-1;i=sis.read())
{
body[e]=(byte)i;
/*fos.write(body[0]);
for(int l=0;l<body.length-1;l++)
{
body[l]=body[l+1];
}*/
//body[e]=(byte)i;
if(delimiter.equals(new String (body)))
{
break;
}
//length++;
fos.write(body[e]);
for(int k=0;k<body.length-1;k++)
{
body[k]=body[k+1];
}
length++;
}
fos.flush();
fos.close();
out.println("<p><b>Saved File:</b>"+filename+"</p>");
out.println("<p><b>Length:</b>"+ length+"</p>");
}
if(sis.read() == '-' && sis.read()=='-')
{
break;
}
}
out.println("</html>");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
代码中的更改很少,更改在本书中给出。 这是我的HTML代码
<html>
<head>
<title>Test HTML Form</title>
</head>
<body>
<p>Select a file to upload or <a href="/Project_One/files/">browse currently uploaded files.</a></p>
<form action="http://127.0.0.1/Project_One/FileUpload"
method="post" enctype="multipart/form-data">
File:<input type="file" name:"file"><br>
<input value="Upload File" type="submit">
</form>
</body>
</html>
我正在使用TomCat服务器。
答案 0 :(得分:1)
我觉得这段代码读起来有点复杂,但错误可能有几点,首先是这部分:
out.println("<html>");
out.print("File upload success. <a href=\"/Project_One/files");
out.print("\">Click here to browse through all uploaded ");
out.println("files.</a><br>");
在此部分中,您的链接指向Project_One / files,但是当您编写文件时:
FileOutputStream fos = new FileOutputStream(sc.getRealPath("/")+"/"+filename);
您直接在Project_One文件夹中写入文件(而不是在html点的文件夹中),因此您可以尝试查看文件是否写在工作区的主文件夹中。
无论如何,我认为你可以更好地理解这样的代码:
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;
MultipartFile multipartFile = multipartRequest.getFile("file");
byte[] content =multipartFile.getBytes();
File archivoParaGuardar= new File("/your_directory/"+multipartFile.getOriginalFilename());
try {
baos.write(content);
FileOutputStream fos = new FileOutputStream(archivoParaGuardar);
baos.writeTo(fos);
fos.close();
} catch (Exception e) {
logger.error("Error saving file ", e);
}
希望这会对你有所帮助。
答案 1 :(得分:1)
您从哪里获得此代码?从十年前的servlet教程/书?这一切都不必要地过于复杂。请确保您正在阅读不超过一年的最新教程/书籍。
以下是使用标准servlet 3.0 API完成文件上传的方法:
@MultipartConfig
@WebServlet("/FileUpload")
public class FileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part filePart = request.getPart("file"); // Retrieves <input type="file" name="file">
String filename = getFilename(filePart);
InputStream filecontent = filePart.getInputStream();
// ... (do your job here)
}
private static String getFilename(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;
}
}
这就是全部。它还考虑到返回正确的文件名。某些浏览器(如MSIE)错误地包含文件名中的完整客户端路径。这可能是导致问题的原因。
此外,还有其他2个问题没有直接关系:
您不应将上传的文件存储在deploy文件夹中。重新部署webapp时,它会丢失。将文件存储在deploy文件夹之外的某个固定路径中。另请参阅示例How I save and retrieve an image on my server in a java webapp。
您应该将生成HTML的工作委托给JSP。在doPost()
的末尾,将请求转发给JSP:
request.getRequestDispatcher("/WEB-INF/uploadresult.jsp").forward(request, response);