最近看了一本書上的代碼,代碼的主要功能是實作檔案的上傳。但是,當我運作代碼的時候竟然報錯了。(我用的IDEA)。有錯就解決吧。以下是我遇到的幾個錯誤。
廢話不多說先附上源代碼。
UploadServlet.java
package com;
import java.io.File;
import java.io.IOException;
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.Part;
import java.lang.String;
import java.io.PrintWriter;
import javax.servlet.annotation.MultipartConfig;
import org.apache.catalina.core.ApplicationPart;
@WebServlet("/UploadServlet")
@MultipartConfig(location = "d:/temp") //D盤手動建立temp檔案夾
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String path = this.getServletContext().getRealPath("/"); //擷取伺服器位址
Part p = request.getPart("file1"); //擷取使用者上傳的檔案
if (p.getContentType().contains("image")){ //僅處理上傳的圖檔檔案
ApplicationPart ap =(ApplicationPart)p;
String fname1 = ap.getFilename(); //擷取上傳檔案名
int path_idx = fname1.lastIndexOf("\\") + 1; //對上傳檔案名進行截取
String fname2 = fname1.substring(path_idx, fname1.length());
File file = new File(path + "/upload/" + fname2); //寫入web根目錄下的upload檔案夾中
out.write("檔案上傳成功");
}
else{
out.write("請選擇圖檔檔案!!!");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
index.jsp
Created by IntelliJ IDEA.
User: Chenaniah Gu
Date: 2019/5/11
Time: 21:55
To change this template use File | Settings | File Templates.
--%>
檔案上傳
選擇檔案
這是某本書的代碼,可能環境配置和書上的一樣,不會出錯,但是往往都是環境不一樣。下面來看幾個錯誤。
1. import org.apache.catalina.core.ApplicationPart;報錯
很明顯,這個報錯就是因為找不到這個包,那麼這個包在哪呢?其實它就在Tomcat根目錄中的lib檔案夾中,這個包名叫做catalina.jar。導入這個封包件就OK啦,若導入後不行,那就重新開機IDEA。
2. getFilename()方法找不到
分析一下,這個getFilename()方法是哪的?java自帶包定義的?,抱歉沒搜到。既然不是自帶包,你也沒定義,那就很有可能是引入包中的方法,再細細分析,可以發現是ap調用了它,ap的類型是什麼呢?ApplicationPart。打開ApplicationPart方法,如下圖所示。

1.JPG
我用的是Tomcat9.0,打開ApplicationPart.class
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.apache.catalina.core;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.Part;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.ParameterParser;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItem;
import org.apache.tomcat.util.http.parser.HttpParser;
public class ApplicationPart implements Part {
private final FileItem fileItem;
private final File location;
public ApplicationPart(FileItem fileItem, File location) {
this.fileItem = fileItem;
this.location = location;
}
public void delete() throws IOException {
this.fileItem.delete();
}
public String getContentType() {
return this.fileItem.getContentType();
}
public String getHeader(String name) {
return this.fileItem instanceof DiskFileItem ? this.fileItem.getHeaders().getHeader(name) : null;
}
public Collection getHeaderNames() {
if (!(this.fileItem instanceof DiskFileItem)) {
return Collections.emptyList();
} else {
LinkedHashSet headerNames = new LinkedHashSet();
Iterator iter = this.fileItem.getHeaders().getHeaderNames();
while(iter.hasNext()) {
headerNames.add(iter.next());
}
return headerNames;
}
}
public Collection getHeaders(String name) {
if (!(this.fileItem instanceof DiskFileItem)) {
return Collections.emptyList();
} else {
LinkedHashSet headers = new LinkedHashSet();
Iterator iter = this.fileItem.getHeaders().getHeaders(name);
while(iter.hasNext()) {
headers.add(iter.next());
}
return headers;
}
}
public InputStream getInputStream() throws IOException {
return this.fileItem.getInputStream();
}
public String getName() {
return this.fileItem.getFieldName();
}
public long getSize() {
return this.fileItem.getSize();
}
public void write(String fileName) throws IOException {
File file = new File(fileName);
if (!file.isAbsolute()) {
file = new File(this.location, fileName);
}
try {
this.fileItem.write(file);
} catch (Exception var4) {
throw new IOException(var4);
}
}
public String getString(String encoding) throws UnsupportedEncodingException {
return this.fileItem.getString(encoding);
}
public String getSubmittedFileName() {
String fileName = null;
String cd = this.getHeader("Content-Disposition");
if (cd != null) {
String cdl = cd.toLowerCase(Locale.ENGLISH);
if (cdl.startsWith("form-data") || cdl.startsWith("attachment")) {
ParameterParser paramParser = new ParameterParser();
paramParser.setLowerCaseNames(true);
Map params = paramParser.parse(cd, ';');
if (params.containsKey("filename")) {
fileName = (String)params.get("filename");
if (fileName != null) {
if (fileName.indexOf(92) > -1) {
fileName = HttpParser.unquote(fileName.trim());
} else {
fileName = fileName.trim();
}
} else {
fileName = "";
}
}
}
}
return fileName;
}
}
你會發現根本沒有getFilename()這個方法。是不是有一種被騙的感覺?
怎麼解決呢?兩種方法,首先你可以自己寫一個這樣的方法,其次就是用java中的File類。
修改後的代碼如下 UploadServlet.java
package com;
import java.io.File;
import java.io.IOException;
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.Part;
import java.lang.String;
import java.io.PrintWriter;
import javax.servlet.annotation.MultipartConfig;
import org.apache.catalina.core.ApplicationPart;
@WebServlet("/UploadServlet")
@MultipartConfig(location = "d:/temp") //D盤手動建立temp檔案夾
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String path = this.getServletContext().getRealPath("/"); //擷取伺服器位址
System.out.println("伺服器位址是"+path);
Part p = request.getPart("file1"); //擷取使用者上傳的檔案
if (p.getContentType().contains("image")){ //僅處理上傳的圖檔檔案
ApplicationPart ap =(ApplicationPart)p;
String filename = ap.getSubmittedFileName(); //擷取檔案名
System.out.println(filename);
File file = new File(path + "/upload/" + filename);
System.out.println("file.getPath()的值是"+file.getPath());
p.write(file.getPath()); //寫入web根目錄下的upload檔案夾中
out.write("檔案上傳成功");
}
else{
out.write("請選擇圖檔檔案!!!");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
最後附上一張成功運作的截圖

2.JPG