问题需求大致如下:
1.有个form表单,点按钮上传一个文件。
2.需要在数据库检索是否有同名文件,如果有同名文件,跳到3,如果没有跳到4
3.在页面提示用户,已有同名文件,是否覆盖,如果用户点是,跳到4,点否,跳到5
4.上传步骤1中的文件
5.返回初始页面上传过程本身很简单:步骤1中点了上传之后,需要到服务器端检索同名文件,如果没有同名则直接上传,在一个servlet中处理提交的form就行了,(我用的组件是commons fileupload,实际处理的是request对象)。
难点是:如果步骤2中有同名文件,需要返回客户端询问用户,当用户在步骤3中点了“是”之后,需要再回到服务器端进行上传文件
可是这时候传到服务器端的request已经是步骤3中发出的了,也就是说步骤1中含有文件信息的request已经没有!我考虑了几种方法,都没有解决,目前有希望的方法是:
1.在步骤1上传的同时,记录下<input type="file">这个元素的value,一起上传,当步骤3之后,真正上传的时候把这个value付值给一个<input type="file">,将其上传。但是经测试付值之后并不能有效上传,网上查了一下似乎无法用javascript对
<input type="file">类型的东西付值。
2.在步骤1上传之后的servlet中保存request的副本,供后面使用,但是我用 session.setAttribute("request",request)
转到别的页面之后还是不能得到上传文件信息。:(
3.在步骤1上传之前,激活一个javascipt脚本,该脚本调用一个servlet查询同名文件,并且返回一个确认信息,js脚本再进行
步骤3中的用户确认,一系列都通过之后,才返回一个true,让form提交。
  前2种方法都失败了,第三种还没想好怎么写脚本。这个问题难我2天了,求教大家!

解决方案 »

  1.   

    3个比较好呀,就是用ajax呀,比较简单,在用户选择文件的时侯,你就可以通过ajax调用一个servlet处理,
    你看一下ajax的知识就是了,very easy!good luck!
      

  2.   

    我只是说一下我的看法:
    方法(1) 第一个你可以在服务器端判断以后,如果发现有同名文件,把文件路径放到response中返回给用户, 这样如果用户点击yes,你可以继续用那路径重新发送一个request.
    方法(2) 你可以先在服务器端放一个临时文件名,然后询问用户, 如果用户点击yes, 则覆盖文件(删除,重命名),如果用户点否直接把临时文件删除.
    方法(3) 你可以先不上传, 直接在服务器端检查. 只需要保存客户端路径名.点yes,真正开始传.
      

  3.   

    思路:在commons fileupload中,真正负责上传文件的对象是FileItem,因此,只要将这个对象保存到session中,任何时刻你都可以上传,呵呵。下面是示例代码:
    主页面(html格式),让用户选择上传的文件:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    </head><body>
    <form action="test.do" method="post" enctype="multipart/form-data" name="form1" id="form1">
      <label>
      <input type="file" name="file1" id="file1" />
      </label>
      <input type="submit" name="button" id="button" value="提交" />
    </form>
    </body>
    </html>主要servlet代码,有2种可能得到FileItem对象,得到该对象之后,上传即可
    //在下面的代码中,我选择的路径是D盘,可以自己修改
    HttpSession session = req.getSession();
    //如果能够得到FileItem,就证明是用户选择了“同意覆盖”,直接上传即可
    FileItem i = (FileItem)session.getAttribute("file");
    if(i != null) {
    String s = i.getName();
    int pos = s.lastIndexOf('\\');
    s = s.substring(pos+1);
    File f = new File("D:\\"+s);
    try {
    i.write(f);
    session.removeAttribute("file");
    } catch (Exception e) {
    e.printStackTrace();
    }
    return;
    }


    //能够执行到此,意味着session中没有FileItem,则解析request
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
    List<FileItem> l = null;
    try {
    l = upload.parseRequest(req);
    } catch (FileUploadException e) {
    e.printStackTrace();
    } for(FileItem item:l) {
    if(!item.isFormField()) {
    String s = item.getName();
    int pos = s.lastIndexOf('\\');
    s = s.substring(pos+1);
    File f = new File("D:\\"+s);
    if(!f.exists()) {
    try {
    item.write(f);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }else {
    session.setAttribute("file", item);
    resp.sendRedirect("eee.html");
    }
    }
    }
    提示用户“有重复文件”的html页面:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    </head><body>
    有同名文件,是否覆盖?
    <input type="submit" name="button" id="button" value="是"  onclick="location.href='test.do'"/>
    <input type="submit" name="button" id="button" value="否" />
    </body>
    </html>
      

  4.   

    ajax是要web2.0支持的巴,一般的浏览器似乎都不支持,所以我就没学那个。请问ajax会比较通用么?
      

  5.   

    "
    你在(2)中的想法是我没想到的,
    可是1,3中只保存路径是无法再次上传的,因为需要用<input type="file">提交文件阿,无法从程序中改变这个元素的值。
      

  6.   

    多谢写了这么多,这似乎是最可行的了,可是有一点我不明白,为什么必须把request解析了,把里面对象一个一个放入
    session? 我原来想直接 session.setAttribute("request",request);
    可是这样不行,为什么?
      

  7.   


    现在的IE和firefox都支持地很好呀,没听说啥不支持的呀,除非是比较老的浏览器吧个人感觉比较通用,现在很流行,是web的一个发展方向像往session存入文件这样的大对象,实在不是个好主意
      

  8.   

    多谢你给我又指出一条路,我刚下了个ajax基础教程看看,看了没几页发现一句话:
    "另外我们也不会浪费时间来讨论如何构建企业级应用,这样的应用很少使用Ajax."
    这话啥意思呢?项目大了ajax就不好使了么?让人担忧啊!
      

  9.   

    用ajax实现方法.
    1。生成检查文件是否存在的servlet
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;import javax.servlet.*;
    import javax.servlet.http.*;public class CheckFileServlet extends HttpServlet {
        
        protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
            
            String path = request.getParameter("filename");
            String t_name = path.substring(path.lastIndexOf("\\") + 1);
            System.out.println("filename="+t_name);
            OutputStream responseOutput = response.getOutputStream();
            if(new File("d:\\temp\\"+t_name).exists())
                responseOutput.write("true".getBytes());
            else
                responseOutput.write("false".getBytes());
            responseOutput.close();    }
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
            processRequest(request, response);
        }
    }2。html文件中,点击upload时,调用servlet,判断文件是否存在,代码如下<%@ page contentType="text/html; charset=UTF-8" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <html>
    <head>
    <title>文件上传</title>
    </head>
    <script language="javascript">
    var XMLHttpReq;
    var PREFIX = "Sort";
      //创建XMLHttpRequest对象       
        function createXMLHttpRequest() {
    if(window.XMLHttpRequest) { //Mozilla 浏览器
    XMLHttpReq = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) { // IE浏览器
    try {
    XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
    try {
    XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
    }
    }
    }

    function checkFile() {
           filename = document.getElementById("file").value;
       if(filename == "" ) 
       {
            return;
        }
        var url = "CheckFile?filename="+ filename +"&id="+new Date().getTime();
        window.alert(url);
        createXMLHttpRequest();
        XMLHttpReq.onreadystatechange = uploadFile;
        XMLHttpReq.open("GET", url, true);
        XMLHttpReq.send(null);
    }

    function uploadFile() {
         if (XMLHttpReq.readyState == 4) // 判断对象状态
         { 
             if (XMLHttpReq.status == 200) // 信息已经成功返回,开始处理信息
             { 
                var hasFile = XMLHttpReq.responseTEXT;
                window.alert(hasFile);
                if(hasFile == "true") //服务器上有同名文件
                {
                if(window.confirm("您要上传的文件在服务器上已经存在,是否需要覆盖服务器上的文件?"))  //确认对话框
                document.getElementById("fileForm").submit();
                }
                else //服务器没有同名文件
                {
                document.getElementById("fileForm").submit();
                }
                } else { //页面不正常
                    window.alert("您所请求的页面有异常。");
                }
            }
        }
    </script>
    <body bgcolor="#ffffff">
    <H1>文件上传</H1>
    <br><br>
    <form NAME="fileForm"
     action="saveFile.do" ENCTYPE="multipart/form-data" method="post">
    <INPUT TYPE="file" NAME="file"/><br>
    <input type="button"  value="upload" name="Upload" onclick="checkFile();">
    </form>
    </body>
    </html>3。保存文件的action一定先删除文件再保存。
    4。在web.xml中配置好servlet和action就可以了。  <servlet>
        <servlet-name>checkFile</servlet-name>
        <servlet-class>cn.svs.action.CheckFileServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>checkFile</servlet-name>
        <url-pattern>/CheckFile</url-pattern>
      </servlet-mapping>
      

  10.   

    多谢!这正是我想要的,终于有了!可是你的代码经测试,还有个问题没解决:function uploadFile() {
            if (XMLHttpReq.readyState == 4) // 判断对象状态
            { 
                if (XMLHttpReq.status == 200) // 信息已经成功返回,开始处理信息
                { 
                       var hasFile = XMLHttpReq.responseTEXT;    
                       window.alert(hasFile);
                       if(hasFile == "true") //服务器上有同名文件
                       {
    红色那行,就是得到的response内容,经测试总是undefined,所以后面的判断都无法做了;
    继续测试发现servlet里的语句都没有被执行,似乎没有找到,可是返回的是status 是200,
    为什么XMLHttpReq.responseTEXT总是 undefined呢?
      

  11.   

    问题挨个回答吧
    这个地方要改一下 var hasFile = XMLHttpReq.responseTEXT;  改成var hasFile = XMLHttpReq.responseText; 
      

  12.   


    有些教程只是个人写的,不一定有代表意义,
    可能是一方面ajax(算是出现地晚)的应用并不是非常得广,另一方面它只是陪衬,并不是主要的,比如你这里的项目,文件上传才是你真正的功能,像用ajax来检查文件名重复,只是文件上传功能的一个小陪衬,就算是大的应用,你也不会所有功能都用ajax的,不是么,呵呵部分辅助的小功能用ajax用它还是非常不错的,有些大网站都已经开始应用了,不过记不清有哪些,你注意一下可能就会注意到了
      

  13.   

    终于解决了! 一个Text大小写啊!花了我一个下午都没查出来
    太感谢tavor了,还有感谢提供代码的andycpp和hongke1490,感谢CCTV....
    结贴了!