I've developed a web application using jsp that has a list of contents which are placed in an ArrayList. I've tried various methods to implement this, tried the AsynchronousFillHandle , AJAX , Scriptlet. But I just can't get it done properly.
What I'm trying to achieve here is, while the JasperExportManager is filling records row by row, I want to display the number of rows that have been printed (say Live status of number of records printed) in the webpage.
For Example
267 out of 645588 records printed
5692 out of 645588 records printed
34677 out of 645588 records printed
After two days of unsuccessful attempts, I decided to use a shortcut, I wrote a scriptlet file, which will print the count of records being printed to a txt file in the same directory,
Scriptlet code:
public void afterDetailEval() throws JRScriptletException{
count = (Integer) this.getVariableValue("count");
BufferedWriter br = null;
try {
br = new BufferedWriter(new FileWriter(new File("C:/jasperreports-5.6.0/test/viewTasks/WebContent/value.txt")));
br.write(new String(""+count));
br.close();
Thread.sleep(200);
}catch (Exception e) {
e.printStackTrace();
}
}
and then used another ajax request to read data from the text file and display it in the browser, which was again unsuccessful as the ajax request returned only the previously stored value (i.e. Although the changes take place in the .txt file, AJAX request returned only the value which was there before the program execution took place. I guess it is because, the changes happen in the local directory and doesn't get reflected in the server). The AJAX code is as follows,
Webpage code:
<script>
function startPrinting() {
xhttp1 = new XMLHttpRequest();
xhttp1.onreadystatechange = function() {
if (this.readyState >= 1) {
document.getElementById('total')style.display = "";
setTimeout(function() { getStat(); }, 6000); //calls the function to start updating status
}
};
xhttp1.open("POST", "statusServlet", true);
xhttp1.send();
} //This function is to start the printing processes
function getStat(){
myvar=setInterval(function() {reval()}, 3000);
function reval(){
if(xhttp1.readyState>2){
xhttp1.abort();
}
var rawFile = new XMLHttpRequest();
var prev = "";
rawFile.open("GET","value.txt" , true);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
allText = rawFile.responseText;
if(prev===allText){
document.getElementById("status").innerHTML = allText;
return;
}
prev = allText;
document.getElementById("status").innerHTML = allText;
}
}
}
rawFile.send();
}
}
</script>
While using this code, If the file .txt is kept active inside the eclipse IDE, the values get reflected in the webpage, I really don't know why or how, but when the text file is kept active (I know it's weird), somehow the AJAX request returns the values correctly. Is there anyway to get this code to work without having to keep the .txt file active? Is there any other way to achieve the live row status of Jasper export other than writing and reading from a file?
NOTE: I'm using JAVA EE IDE from Eclipse with Tomcat 7.0 as server
Thanks in advance!
Related
I am writing a javascript code wherein a alert is to be provided when a condition gets executed
I referred some youtube videos on ajax and json and wrote a code wherein i successfully log data from a website and send an automated alert message. My issue is that whenever I add the same alert message in the if statement the alert does not get executed.
I tried using the developer tools for f12 and debugged the code it seems the data does not enter the loop.
Please help me on this
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'https://learnwebcode.github.io/json-example/animals-1.json');
ourRequest.onload = function() {
var ourData = JSON.parse(ourRequest.responseText);
console.log(ourData);
if (ourData = "cat") {
alert(" take action");
};
ourRequest.send();
}
The alert should be generated as cat is found in the json file located at the link https://learnwebcode.github.io/json-example/animals-1.json
I'm posting my answer there instead of comment because it's too long.
Your if is not well formatted it should use the comparison operator == or === (which is "better"). Correct your if with the right operator because you used = which is the affectation operator.
By the way I checked the data and you should iterate over the object list and check the "species" attribute. Like this if(ourData.species == "cat").
Your code should look like :
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'https://learnwebcode.github.io/json-example/animals-1.json', true);
ourRequest.onload = function () {
// Request finished. Do processing here.
var ourData = JSON.parse(ourRequest.responseText);
console.log(ourData);
// loop over each "animal" element
ourData.forEach(function (element) {
if (element.species === "cat") {
alert(" take action");
};
});
};
ourRequest.send();
Hope it helps.
The background is, frontend passed an id back to backend and backend uses the id to extract information from database. The extracted data need further processing at backend and then gets sent back to frontend.
Here is the front end code:
html:
<!DOCTYPE html>
<html>
<head>
<title>Test!</title>
<meta charset="utf-8">
<script src="loadPage.js">
</script>
</head>
<body onload = "loadPage()">
<div id="stack"><p>test part</p>
</div>
</body>
</html>
js:
function __getParameters() {
var parm = {};
var url = window.location.href;
var pairs = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i].split('=');
parm[pair[0]] = pair[1];
}
return parm;
}
function __loadData(star) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// var data = JSON.parse(xmlhttp.responseText);
console.log(xmlhttp.responseText);
if (xmlhttp.responseText == "") {
document.getElementById("stack").innerHTML = "f*ck";
} else {
document.getElementById("stack").innerHTML = xmlhttp.responseText;
}
}
}
var url = "getXML.pl";
url = url + "?STAR=" + star;
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function loadPage() {
var parm = __getParameters();
// document.getElementById("stack").innerHTML = parm["STAR"];
if (parm == undefined) {
// wrong url error page
} else if (parm['STAR'] == undefined) {
// missing star error page
} else if (parm['user' == undefined]) {
// missing user id error page
} else {
var star = parm["STAR"];
var user = parm["user"];
__loadData(star);
}
}
The backend uses perl to extract data from database, and it will print the output to stdout. The output is a XML in string form. Then I must use an existed python script to process the extracted data.
However, the server seems not support python (But the server can run python if I directly run python scripts on it. The reason for my statement is that I wrote a python cgi and I got a 500 error, while the perl cgi is ok. I'm sure the python script is correct since it can run directly on the server. I have no access to error log and I cannot modify the config file of the server).
So I piped the output of the perl script to python, and run it using 'system()'. The python script will output a processed string to stdout.
Here is the backend scripts:
perl script:
#!/depot/perl-5.14.2/bin/perl
# extract posted data
local ($buffer, #pairs, $pair, $name, $value, %FORM);
$ENV{"REQUEST__METHOD"} =~ tr/a-z/A-Z/;
if ($ENV{"REQUEST_METHOD"} eq "POST") {
read(STDIN, $buffer, $ENV{"CONTENT_LENGTH"});
} else {
$buffer = $ENV{"QUERY_STRING"};
}
#pairs = split(/&/, $buffer);
foreach $pair (#pairs) {
($name, $value) = split(/=/, $buffer);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$star = $FORM{STAR};
print "Content-type:text/html\n\n";
my $cmd = "***/sq_star.pl --xml --star_id " . $star;
$cmd = $cmd . " | ***/python parseXML.py";
system($cmd);
the sq_star.pl (I just remove the path here and replace it with ***) near the end of perl script is just an existed script that will extract data from database. And parseXML.py is an existed script which does a lot to the input string.
The strange thing is, the responseText is always an empty string. I tried to run the perl script directly on the server, it can print expected results. And if I remove $cmd = $cmd . " | ***/python parseXML.py";, the responseText will be the data extracted from the database.
What I have tried for now:
1. I wrote a simple test python with just one line of print. Still empty response
2. I tried to store the output as $output =`$cmd`; and print $output; in the perl script, still empty.
3. I tried to store the original data in a txt and let the python read from the txt. Still empty
It seems that that data processed by python just cannot be sent back .....
-------------------update----------------
It seems to be the problem of the server. I guess the server is not set to support python so if I directly send requests to a python script on backend, there will be 500 error. But somehow my way, i.e., calling python in perl, gets around the error, but still the python just doesn't work... Just my guess
I found the problem. It is because the interpreter I specified cannot be found by the server. system(...) line actually doesn't run at all. The reason that I didn' t see any error is because system() hides the error for me. Actually the return value of system() is -1, which means something wrong. I should have checked the return value
I am trying to write a javascript function that tries reading text files from the server until it finds one that doesn't exist.
On the server there are text files numbered 1 to n (1.txt, 2.txt, 3.txt etc.), so it should read all the files (sequentially or asynchronously) until it tries to read "4.txt" and it throws an error.
The following code works on my local machine (with no server running), but fails on a remote server saying the "No such file" error is uncaught.
I am trying to understand why the error is handled differently in the two cases, if there is anything I can do to make it work for a remote server as well, and if there is any other approach I can take for this?
The minimal code I have is:
var files=[];
function readTextFile(file)
{
var request = new XMLHttpRequest();
request.open("GET", file, false);
request.onreadystatechange = function ()
{
if(request.readyState === 4)
{
if(request.status === 200)
{
var allText = request.responseText;
files.push(allText);
} else {
throw "No such file";
}
}
}
request.send();
}
function readFiles(){
try {
var i =1;
while (true) {
readTextFile(i+".txt");
i+=1;
}
}
catch (e) {
console.log("finished reading files")
}
console.log(files)
}
readFiles();
I'm using XMLHttpRequest to read a text file (on local) after a period of time (after 10s).
After 10s, XMLHttpRequest retrieves the text file but the content (responseText) does not changed even though I have changed it.
Here is my code:
var list = [];
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (xhr.responseText.length == 0) {
undef();
}
else {
def();
}
}
}
getFile();
function getFile() {
list = [];
xhr.open("GET", chrome.extension.getURL('text/list.txt'), true);
xhr.send(null);
}
var myVar = setInterval(function(){getFile()}, 10 * 1000);
function def() {
// do something
}
function undef() {
// do something
}
I don' know why and how to fix it, please help.
The fast/lazy solution is to change your link address without changing the file it's accessing.
Modify your link with LinkToFile+"?="+Math.random()
It won't match anything in the cache but it will fetch the same file.
I found the problem, it is that the folder containing the file that I use when coding is different from the folder containing the extension when added to Chrome.
I just modified the wrong file.
Thank you everyone for your help.
I'm creating a simple WebGL project and need a way to load in models. I decided to use OBJ format so I need a way to load it in. The file is (going to be) stored on the server and my question is: how does one in JS load in a text file and scan it line by line, token by token (like with streams in C++)? I'm new to JS, hence my question. The easier way, the better.
UPDATE: I used your solution, broofa, but I'm not sure if I did it right. I load the data from a file in forEach loop you wrote but outside of it (i.e. after all your code) the object I've been filling data with is "undefined". What am I doing wrong? Here's the code:
var materialFilename;
function loadOBJModel(filename)
{
// ...
var req = new XMLHttpRequest();
req.open('GET', filename);
req.responseType = 'text';
req.onreadystatechange = function()
{
if (req.readyState == 4)
{
var lines = req.responseText.split(/\n/g);
lines.forEach(function(line)
{
readLine(line);
});
}
}
req.send();
alert(materialFilename);
// ...
}
function readLine(line)
{
// ...
else if (tokens[0] == "mtllib")
{
materialFilename = tokens[1];
}
// ...
}
You can use XMLHttpRequest to fetch the file, assuming it's coming from the same domain as your main web page. If not, and you have control over the server hosting your file, you can enable CORS without too much trouble. E.g.
To scan line-by-line, you can use split(). E.g. Something like this ...
var req = new XMLHttpRequest();
req.open('GET', '/your/url/goes/here');
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
var lines = req.responseText.split(/\n/g);
lines.forEach(function(line, i) {
// 'line' is a line of your file, 'i' is the line number (starting at 0)
});
} else {
// (something went wrong with the request)
}
}
}
req.send();
If you can't simply load the data with XHR or CORS, you could always use the JSON-P method by wrapping it with a JavaScript function and dynamically attaching the script tag to your page.
You would have a server-side script that would accept a callback parameter, and return something like callback1234(/* file data here */);.
Once you have the data, parsing should be trivial, but you will have to write your own parsing functions. Nothing exists for that out of the box.