java.io.FileNotFoundException при записи загруженного файла на диск через getRealPath()
Glassfish, кажется, добавляет дополнительный путь к пути, который я хочу сохранить и в свой файл изображения, есть ли способ использовать только абсолютный путь, по которому мой сервлет получает
String appPath = request.getServletContext().getRealPath("");
?
Я потратил несколько дней, пытаясь различными способами загрузить файл изображения и сервлет сохранить его на диск.
Я использовал этот пример: http://www.codejava.net/java-ee/servlet/how-to-write-upload-file-servlet-with-servlet-30-api
Используя debug, я вижу, что имя файла и информация о пути собраны правильно, но код завершается с ошибкой в `part.write(savePath + File.separator + fileName);``
И отчет об исключениях Glassfish:
exception
java.io.FileNotFoundException: C:\Program Files\glassfish-3.1.2.2\glassfish\domains\domain1\generated\jsp\com.onemore_onemore-web_war_1.0-SNAPSHOT\D:\Dropbox\Git\Brian_JEE\onemore\onemore\onemore-web\target\onemore-web-1.0-SNAPSHOT\image\screengrab_all_products.jpg (The filename, directory name, or volume label syntax is incorrect)
Я вижу правильный путь как часть этого исключения D:\Dropbox\Git\Brian_JEE\onemore\onemore\onemore-web\target\onemore-web-1.0-SNAPSHOT\image\screengrab_all_products.jpg
JSP
<form action="${pageContext.request.contextPath}/imageupload" method="post" enctype="multipart/form-data" name="productForm" id="productForm">
<input type="file" name="file" id="file">
<input type="submit" name="Submit" value="Submit"></td>
</form>
Servlet
@WebServlet(name = "UploadImageServlet", urlPatterns = {"/imageupload"})
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
maxFileSize = 1024 * 1024 * 10, // 10MB
maxRequestSize = 1024 * 1024 * 50) // 50MB
public class UploadImageServlet extends HttpServlet {
/**
* Name of the directory where uploaded files will be saved, relative to the
* web application directory.
*/
private static final String SAVE_DIR = "image";
/**
* handles file upload
*/
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// gets absolute path of the web application
String appPath = request.getServletContext().getRealPath("");
// constructs path of the directory to save uploaded file
String savePath = appPath + File.separator + SAVE_DIR;
// creates the save directory if it does not exists
File fileSaveDir = new File(savePath);
if (!fileSaveDir.exists()) {
fileSaveDir.mkdir();
}
for (Part part : request.getParts()) {
String fileName = extractFileName(part);
part.write(savePath + File.separator + fileName);
}
request.setAttribute("message", "Upload has been done successfully!");
getServletContext().getRequestDispatcher("/WEB-INF/jsp/newproduct.jsp").forward(
request, response);
}
/**
* Extracts file name from HTTP header content-disposition
*/
private String extractFileName(Part part) {
String contentDisp = part.getHeader("content-disposition");
String[] items = contentDisp.split(";");
for (String s : items) {
if (s.trim().startsWith("filename")) {
return s.substring(s.indexOf("=") + 2, s.length() - 1);
}
}
return "";
}
}
2 ответа
Никогда не используйте getRealPath()
Вы не должны сохранять загруженные файлы в папке развертывания. Я объяснял это много раз раньше. Одно из этих объяснений можно найти в этом ответе: загруженное изображение доступно только после обновления страницы.
Любой фрагмент кода JSP/Servlet, найденный в блоге / статье, который когда-либо использует getRealPath()
Метод следует принимать с огромным мешком соли. Его качество и знания автора должны быть поставлены под сомнение. Именно для этого метода не существует разумного варианта использования в реальном мире.
Сохраняйте загруженные файлы по фиксированному пути вне папки развертывания. См. Также Как настроить папку для хранения загрузок файлов с помощью Commons FileUpload.
Используйте следующий код. Я решил эту ошибку с помощью этих кодов. Запишите ее в свой метод doPost.
Part filePart = request.getPart("file");
String fileName =
Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
InputStream inputStream = filePart.getInputStream();
String uploadPath = getServletContext().getRealPath("") + File.separator + "uploaded_file";
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
FileOutputStream outputStream = new FileOutputStream(uploadPath +
File.separator + fileName);
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
\\