我正在jsp中进行简单的文件上传。我似乎被这个简单的路径问题所阻止了。我正在开发Windows,但可以在Linux机器上部署。所以我在mywebsite / tempfiledir和mywebsite / finalfiledir下有tmpdir和finaldir
所以我使用这段代码(servlet的代码片段)
public class SyncManagerServlet extends HttpServlet {
private static final String TMP_DIR_PATH = "/tempfiledir";
private File tempDir;
private static final String DESTINATION = "/finalfiledir";
private File destinationDir;
public void init(ServletConfig config){
try {
super.init(config);
tempDir = new File(getAbsolute(TMP_DIR_PATH));
if(!tempDir.isDirectory()){
throw new ServletException(TMP_DIR_PATH + " is not a Directory");
}
destinationDir = new File(getAbsolute(DESTINATION));
if(!destinationDir.isDirectory()){
throw new ServletException(DESTINATION + " is not a Directory");
}
} catch (ServletException ex) {
Logger.getLogger(OrliteSyncManagerServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String email = request.getParameter("email");
String path = request.getContextPath();
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
fileItemFactory.setRepository(tempDir);
ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
try {
List items = uploadHandler.parseRequest(request);
Iterator itr = items.iterator();
while(itr.hasNext()){
FileItem item = (FileItem) itr.next();
if( item.isFormField() && item != null ){
out.println("<html>");
out.println("<head>");
out.println("<body>");
out.println("your email: " + item.getString() + " has been submited and context path is "+ request.getContextPath() );
out.println("</body>");
out.println("</head>");
out.println("</html>");
} else {
out.println("the uploaded file name is : " + item.getName());
out.println("content type is : " + item.getContentType());
out.println("Size is : " + item.getSize());
File file = new File(destinationDir, FilenameUtils.getName(item.getName()));
item.write(file);
}
public String getAbsolute(String relativepath){
return getServletContext().getRealPath(relativepath);
}
//......
}
我有这个例外
java.io.FileNotFoundException:D:\ WORK \ java \ netbeansProject \ Projects \ mywebsite-webapp \ target \ mywebsite \ finalfiledir(访问被拒绝)
我无法弄清楚相对路径失败的原因。 我已经注意到很多样本在线人们使用tempdir的完整路径。 所以在我的情况下,我不得不担心Linux的部署,解决方法是什么?但首先我想了解为什么我给出的路径是错误的。
感谢您阅读本文! 这里有2个问题
1 如何解决这条路径的问题?
2 如何以更便携的方式做到这一点(考虑到linux权限)?
谢谢!
答案 0 :(得分:1)
1如何解决这条路径的直接问题?
以前导斜杠开头的路径与当前工作目录无关。它们是绝对的,只有在Windows中指向当前工作的磁盘(运行服务器的位置,并且取决于服务器的启动方式)。
在您的情况下,当"/tempfiledir"
上安装Windows和服务器时,Windows中的C:\tempfiledir
会指向C:\
,而/tempfiledir
中会安装init()
。您需要在File#exists()
方法中添加另一项检查,该方法还会执行C:\
检查,以便及时发现文件夹的缺失。
2如何以更便携的方式做到这一点(考虑到linux权限)?
只要您不使用/
等特定于Windows的磁盘标签并使用File
作为路径分隔符,您就不必担心这一点。
如果你真的坚持将文件写入webcontent,那么你需要记住两件事:1)当部署为WAR时,它只有在servletcontainer扩展WAR时才有效。 2)重新部署WAR时,所有内容(所有上传的文件)都将被删除。
这是您可以将相对Web路径转换为绝对磁盘文件系统路径的方法,以便您可以在String relativeWebPath = "/tempfiledir";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
File file = new File(absoluteDiskPath, filename);
中进一步使用它并配合:
item.getName()
与问题无关:FilenameUtils#getName()
将在某些Web浏览器(特别是:MSIE系列)中返回完整的客户端路径。根据{{3}},您需要在new File()
中使用{{1}}作为文件名之前调用{{1}},否则也会造成严重破坏。
答案 1 :(得分:0)
我认为保存临时文件的最佳位置是系统临时目录,可以从系统属性java.io.tmpdir中检索。我从未见过用户无法写入此目录的环境。