My question consists of two parts on interrupting requests:
I'm using a dynamic Java Web Application (Tomcat 8.0.15, Java EE 7 Web) with a SQL Server 2008 and JavaScript/jQuery (3.1.1).
Apparently some variants of that problem have been posted on Stackoverflow already a few years ago.
I'm having an input/textarea-field with an onkeyup-event that sends a request to a Servlet and gets a response with some kind of google-like suggestion-drop-down.
I had in my mind whenever I fire another jQuery-Ajax-Request the old on is aborted. Yesterday I realized that's not the case (any more?) and I get the dropdown several times instead of just once. If you happen to know whether or not jQuery changed something in a new version, please let me know how and if I am able to revert that.
The second part is on the server-side: I'm firing a quite heavy query to the database and would like that to be interrupted as the Ajax-Request is aborted. That seems to be quite a problem. There's a discussion here already about the same issue in PHP/MySQL (Stop mysql query when press stop button). Back in 2009 there was "no simple way": How to cancel ajax request that has run (on server side) - I wonder whether or not something changed and meanwhile I can do something about it.
There are several approaches on how the Ajax-query can be interrupted. I chose Abort Ajax requests using jQuery and my code looks like that:
Main-File:
<html>
<head>
<script>
var xhr; //global variable for the Ajax-Object
</script>
<meta ... />
The field is also pretty straightforward:
<textarea id="field_106" onkeyup="sendInfo(/*Some parameters*/)"></textarea>
The code:
function sendInfo(/*All the Params*/) {
//That's new
if(xhr!=null){
xhr.abort();
}
//Before I haven't had that xhr-val too
xhr=$.ajax({
url: jsp,
data: {
input: document.getElementById(input).value,
/*
* Lots
* of
* other
* parameters
*/
},
type: 'GET',
success: function (result) {
document.getElementById(output).innerHTML = result;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
document.getElementById(output).innerHTML = "err--" + XMLHttpRequest.status + " -- " + XMLHttpRequest.statusText;
}
});
}
}
Before on the Firebug-Console I had the the issue every single keyup-event is firing its own Request which results - depending on quite a few requests, depending on how much is sent:
After the changes it looks like it used to:
Apparently I'm not so wrong, Google seems to use the very same method of interrupting Requests (just their servers are faster than I can type):
The Servlet puts together two Queries. The first four entries are the "Top Results" depending on usage, the second fetches the rest:
private final String sql = "SELECT TOP 5 "
// ALL THE VALS
" FROM TopResults "
+ " WHERE Description like ? order by CNT desc";
private final String sql2 = "SELECT "
// SAME VALS
+ "FROM Articles art "
+ "LEFT OUTER JOIN "
+ "TopResults ON ArtikelNr=Artikelnumber "
+ "WHERE art.Artikelbezeichnung1 like ? "
+ ""
+ "EXCEPT "
+ ""
+ sql;
public String getInfo() {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
StringBuilder ret = new StringBuilder();
try {
c = BaseConnection.getConnection();
ret.append(getTableStart());
ps = c.prepareStatement(sql);
ps.setString(1, "%" + query + "%");
rs = ps.executeQuery();
ret.append(appendX("", rs));
BaseConnection.disconnect(rs, ps);
ps = c.prepareStatement(sql2);
ps.setString(1, "%" + query + "%");
ps.setString(2, "%" + query + "%");
rs = ps.executeQuery();
ret.append(appendX("topTR", rs));
ret.append(getTableEnd());
return ret.toString();
} catch (SQLException | NamingException ex) {
Logger.getLogger(GetInfo.class.getName()).log(Level.SEVERE, null, ex);
return ex.getLocalizedMessage() + "<br/>" + ((ex instanceof SQLException) ? ((SQLException) ex).getSQLState() : "Naming Exception");
} finally {
BaseConnection.disconnect(rs, ps, c);
}
}
Here I was wondering about my style of sending both Statements, but it's just a style: Executing two Java PreparedStatements with one connection - style choice
I wonder if there are better methods than mine to shoot too many queries into the database. Thank you