问题需求大致如下:
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.有个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天了,求教大家!
你看一下ajax的知识就是了,very easy!good luck!
方法(1) 第一个你可以在服务器端判断以后,如果发现有同名文件,把文件路径放到response中返回给用户, 这样如果用户点击yes,你可以继续用那路径重新发送一个request.
方法(2) 你可以先在服务器端放一个临时文件名,然后询问用户, 如果用户点击yes, 则覆盖文件(删除,重命名),如果用户点否直接把临时文件删除.
方法(3) 你可以先不上传, 直接在服务器端检查. 只需要保存客户端路径名.点yes,真正开始传.
主页面(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>
你在(2)中的想法是我没想到的,
可是1,3中只保存路径是无法再次上传的,因为需要用<input type="file">提交文件阿,无法从程序中改变这个元素的值。
session? 我原来想直接 session.setAttribute("request",request);
可是这样不行,为什么?
现在的IE和firefox都支持地很好呀,没听说啥不支持的呀,除非是比较老的浏览器吧个人感觉比较通用,现在很流行,是web的一个发展方向像往session存入文件这样的大对象,实在不是个好主意
"另外我们也不会浪费时间来讨论如何构建企业级应用,这样的应用很少使用Ajax."
这话啥意思呢?项目大了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>
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呢?
这个地方要改一下 var hasFile = XMLHttpReq.responseTEXT; 改成var hasFile = XMLHttpReq.responseText;
有些教程只是个人写的,不一定有代表意义,
可能是一方面ajax(算是出现地晚)的应用并不是非常得广,另一方面它只是陪衬,并不是主要的,比如你这里的项目,文件上传才是你真正的功能,像用ajax来检查文件名重复,只是文件上传功能的一个小陪衬,就算是大的应用,你也不会所有功能都用ajax的,不是么,呵呵部分辅助的小功能用ajax用它还是非常不错的,有些大网站都已经开始应用了,不过记不清有哪些,你注意一下可能就会注意到了
太感谢tavor了,还有感谢提供代码的andycpp和hongke1490,感谢CCTV....
结贴了!