我向servlet发送$.post
请求,发送一些需要保存在文件中的数据。 servlet保存数据,然后将路径发送回文件。我试图在方法的回调中导航到response
所持有的路径,但是这是正在发生的事情:
function saveData(){
var path;
$.post("SaveFileServlet", {data : JSON.stringify(jsonPieces)}, function(response) {
path = response; // setting the path like this does NOT WORK - nothing happens
//path="storing/csv_uploads/test.csv"; // setting the path like this WORKS
alert (path); // shows: storing/csv_uploads/filename.csv - e.g. WHAT IT SHOULD
$("body").append("<iframe src='" + path + "' style='display: none;' ></iframe>");
});
}
如何使其工作,为什么它不起作用? 感谢。
甚至更新的编辑
GOT IT !!!!! ...这是servlet:它可能没有创建文件:真正的路径不是filename.csv
而是System.currentTimeMillis()+".csv"
然后我把它写到服务器上。但我只是在创建文件后发送响应(或者我?)......
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
String filename = "storing/csv_uploads/"+System.currentTimeMillis()+".csv";
//String filename = "storing/csv_uploads/filename.csv"; //this works since it was previously there
PrintWriter out = response.getWriter();
try {
Type type = new TypeToken<List<PieceFeeder>>(){}.getType();
ArrayList<PieceFeeder> pieceFeeders = new Gson().fromJson(request.getParameter("data"), type);
DataManager dm = new DataManager();
if (dm.exportPieces(pieceFeeders, filename)) {
System.out.println("in SaveFileServlet: after exportPieces");
File f = new File(filename);
while (!f.exists()) {
//waiting...I NEVER GET IN HERE
System.out.println("in SaveFileServlet: waiting for file to exist");
}
out.write(filename);
} else {
out.write("error at creating file");
}
}...
}
和DataManager.exportPieces
:
public void exportPieces(ArrayList<PieceFeeder> pieceFeeders, String filename) {
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new FileWriter(filename));
//write first line without "\n"
if (pieceFeeders.size() > 0) {
PieceFeeder pf = pieceFeeders.get(0);
Piece p = pf.getPiece();
bufferedWriter.write(p.getDescription() + ","
+ pf.getStock() + ","
+ p.getLength() + ","
+ p.getWidth() + ","
+ p.getLengthEdges() + ","
+ p.getWidthEdges());
}
for (int i = 1; i < pieceFeeders.size(); i++) {
PieceFeeder pf = pieceFeeders.get(i);
Piece p = pf.getPiece();
bufferedWriter.write("\n" + p.getDescription() + ","
+ pf.getStock() + ","
+ p.getLength() + ","
+ p.getWidth() + ","
+ p.getLengthEdges() + ","
+ p.getWidthEdges());
}
return true;
} catch (Exception ex) {
Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
return false;
} finally {
//Close the BufferedWriter
try {
if (bufferedWriter != null) {
bufferedWriter.flush();
bufferedWriter.close();
System.out.println("in exportPieces: finally");
}
} catch (IOException ex) {
Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
我总是得到
"in exportPieces: finally"
"in SaveFileServlet: after exportPieces"
并且永远不会调用"in SaveFileServlet: waiting for file to exist"
所以在发送响应之前文件存在
但如果我发送一个旧文件*一个尚未创建的文件,则可以正常工作
较新的修改
只是为了说清楚:如果我这样做:
window.location = path
$("body").append("<iframe src='" + path + "' ></iframe>");
删除了display:none
它会显示404 error
:The requested resource () is not available.
,但标题显示我正在尝试访问:http://localhost:8080/optimizerwithservlet/storing/csv_uploads/filename.csv
所以它就在那里修改
当用户sugeested我安装了Firebug,这就是我得到的:
<iframe style="display: none;" src="storing/csv_uploads/filename.csv">
意思是它有效!但为什么不显示......?
旧编辑:
如果这可能很重要,虽然我对此表示怀疑:这是来自servlet的相关代码片段:
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
String filename = "storing/csv_uploads/filename.csv";
PrintWriter out = response.getWriter();
out.write(filename);
答案 0 :(得分:3)
$.post
是异步的。您试图在值存在之前提醒该值,即所有。
Ajax中的第一个字母代表“异步”,意思是 操作并行发生,完成顺序不是 保证。 $ .ajax()的async选项默认为true,表示 在发出请求后代码执行可以继续。设置 此选项为false(从而使调用不再异步) 强烈劝阻,因为它可能导致浏览器成为 不响应。
答案 1 :(得分:0)
编辑:您可能需要将dataType指定为“text”以确保字符串返回。
在回调中,假设response
是一个字符串,您只需执行:
window.location = response;
这会将浏览器重定向到响应指示的路径,假设它是绝对URL或root-relative(即以/)开头。
答案 2 :(得分:0)
和Claudia:
您是否绝对确定您从servlet获得的响应是一个简单的字符串与您的路径?周围没有任何空白或类似的东西吗?如果不确定,请尝试将dataType
设置为text
。
我的建议是,在您的页面中添加<iframe>
,并将src
属性设置为您的文件下载路径。确保您甚至能够访问该文件。这至少会排除它是否是相对路径问题。
不使用alert()
,而是使用console.log()
- 因为console.log()
会保留数据结构并让您正确查看。
修改强>
function saveData(){
var path;
$.post("SaveFileServlet", {dataType: 'text', data : JSON.stringify(jsonPieces)}, function(response) {
path = response; // setting the path like this does NOT WORK - nothing happens
console.log (path);
$("body").append("<iframe src='" + path + "' style='display: none;' ></iframe>");
});
}
答案 3 :(得分:-1)
问题是执行顺序。正如登录指出的那样,ajax调用是异步的,因此浏览器会在等待结果时继续执行操作。
这是最基本的:
function doSomething() {
$.post("SaveFileServlet", {data : JSON.stringify(jsonPieces)}, function(response) {
alert('post done');
}
alert('doSomething done');
}
几乎100%的时间,您将获得的第一个警报将是“完成任务”而不是“完成后”。
这是因为JavaScript没有等待ajax调用完成以继续下一步。