JSP programming progress bar design example

xiaoxiao2021-03-14  186

Many web applications, corporate applications involve long-term operations, such as complex database query or heavy XML processing, etc., although these tasks are mainly completed by database systems or middleware, but the results of the task are still to be sent to users . This article describes a method of improving the user's feeling by improving the front-end performance layer and reducing the server load.

When the JSP calls an operation that must run for a long time, and the result of the operation cannot be buffered (on the server side), the user must wait for a long time. Many times, the user will lose patient, then try to click on the browser's refresh button, and finally leave.

The technique described herein is to separate the heavy computing tasks, and operate from a separate thread to solve the above problems. When the user calls the JSP page, the JSP page will return immediately and prompt the user task to be started and executing; the JSP page automatically refreshes yourself, report the current progress of the heavy computing task running in the standalone thread until the task is completed.

First, the simulation task

First we design a Taskbean class, which implements a java.lang.Runnable interface, which runs in a stand-alone thread started by the JSP page (start.jsp). Termination The Run () method is responsible for the STOP.JSP of another JSP page. The TaskBean class also implements the java.io.serializable interface, so the JSP page can be called as a JavaBean:

Package test.barbean;

Import java.io.serializable;

Public Class Taskbean Implements Runnable, SerializAble {

PRIVATE INT Counter;

Private int sum;

Private boolean start;

Private boolean running;

Private int SLEP;

Public taskbean () {

COUNTER = 0;

SUM = 0;

Started = false;

Running = false;

Sleep = 100;

}

}

The "heavy task" containing the taskbean is the value of 1 2 3 ... 100, but it does not calculate the 100 * (100 1) / 2 = 5050 formula, but is called the Work () method by the RUN () method. 100 times completed the calculation. The code for the Work () method is as follows, where Thread.Sleep () is to ensure that the task is always about 10 seconds.

protected void work () {

Try {

Thread.sleep (SLEEP);

Counter ;

SUM = Counter;

} catch (interruptedexception e) {

Strunning (False);

}

}

The Status.jsp page obtains the task's completion status by calling the following getpercent () method:

Public synchronized int getpercent () {

Return Counter;

}

If the task has been started, the isstarted () method will return true:

Public synchronized boolean isstarted () {

Return Started;

}

If the task has been completed, the iScompleted () method will return True:

Public synchronized boolean iscompleted () {

Return counter == 100;

}

If the task is running, the isrunning () method will return True: public synchronized boolean isrunning () {

RETURN Running;

}

The setRunning () method is called by start.jsp or stop.jsp, when the Running parameter is TRUE. The setRunning () method also wants to mark the task as "already started". Calling setNing (false) means that the RUN () method is required to stop execution.

Public synchronized void setning (Boolean Running) {

THIS.RUNNING = Running;

IF (Running)

Started = true;

}

After the task is executed, call the getResult () method to return to the calculation result; if the task has not been executed, it returns NULL:

Public synchronized Object getResult () {

IF (iScompleted ())

Return New Integer (SUM);

Else

Return NULL;

}

When Running is marked as true, the Completed is marked as false, the run () method calls work (). In practical applications, the Run () method may perform a complex SQL query, parse large XML documents, or call the EJB method that consumes a lot of CPU time. Note that "heavy tasks" may be executed on the remote server. There are two options for the JSP page of the report results: or wait for the task to end, or use a progress bar.

Public void run () {

Try {

Strunning (TRUE);

While (isrunning () &&! iScompleted ())

Work ();

} finally {

Strunning (False);

}

}

Second, start the task

Start.jsp is the welcome page declared in the Web.xml deployment descriptor, the content of web.xml is:

Public "- // Sun microsystems, Inc.//dtd Web Application 2.3 // en"

"http://java.sun.com/dtd/web-app_2_3.dtd">

Start.jsp

Start.jsp starts a dedicated thread to run "heavy tasks" and then pass the HTTP request to status.jsp.

The Start.jsp page creates a TaskBean instance using the tag, and defines the scope attribute as session makes it possible to extract the same bean object for HTTP requests from the same browser. Start.jsp ensures a new bean object by calling session.removeattribute ("task"), not extracting an old object (for example, Bean created earlier in the same user session Object).

The following is the code list of the Start.jsp page:

<% session.removeattribute ("task");%>

<% task.setrunning (TRUE);%>

<% new thread (task) .Start ();%>

START.JSP creates and sets the TaskBean object, then create a THREAD and incorporate the bean object as a runnable instance. The newly created thread when calling the start () method will perform the Run () method of the taskbean object.

There are now two threads in concurrent execution: the thread of the JSP page (called "JSP thread"), the thread created by the JSP page (called "task thread"). Next, Start.jsp uses the call status.jsp, Status.jsp displays the progress bar and the implementation of the task. Note status.jsp and Start.jsp run in the same JSP thread.

Start.jsp sets the task's Running tag to True before creating a thread so that even when the JSP thread has begun to execute STATUS.JSP, the run () method of the task thread has not started, and it is also possible to ensure that the user will get "the task has Start the status report that starts ".

Set the Running tag to True, starting the task threads These two lines of lines can be moved into the TaskBean to form a new method and then call this new method by the JSP page. In general, the JSP page should try to use Java code as little as possible, ie we should put Java code as much as possible in the Java class. However, in this example we don't follow this rule, put New Thread (task) .Start () directly into Start.jsp Highlight the JSP thread to create and launch the task thread.

Multithreading in the JSP page must be cautious, note that the JSP thread and other thread are actually executed, just in the desktop application, we use a thread to handle the GUI event, and use one or more threads to process Backstage task. However, in the JSP environment, considering the situation of multiple users to request a page, the same JSP page may run simultaneously in multiple threads; in addition, sometimes the same user may send multiple requests to the same page, Although these requests come from the same user, they also cause the server to run multiple threads of a JSP page at the same time.

Third, task progress

The Status.jsp page uses an HTML schedule to display the task's execution. First, status.jsp uses the tag to get the bean object created by the Start.jsp page:

Class = "Test.barbean.taskbean" />

In order to reflect the progress of the task in time, Status.jsp automatically refreshes. JavaScript code setTimeout ("Location = 'status.jsp'", 1000) Refresh the page every 1000 milliseconds, reclaiming Status.jsp, does not require user intervention.

JSP progress bar </ title></p> <p><% IF (Task.IsRunning ()) {%></p> <p><Script language = "javascript"></p> <p>SetTimeout ("Location = 'status.jsp', 1000); </ script></p> <p><%}%></p> <p></ HEAD></p> <p><ODY></p> <p>The progress bar is actually an HTML form that contains 10 units - that is, each unit represents 10% of the total task.</p> <p><H1 align = "center"> JSP progress bar </ h1></p> <p><H2 align = "center"></p> <p>Result: <% = task.getResult ()%> <br></p> <p><% int percent = task.getPercent ();%></p> <p><% = percent%>%</p> <p></ H2></p> <p><Table Width = "60%" align = "center"</p> <p>Border = 1 Cellpadding = 0 Cellspacing = 2></p> <p><Tr></p> <p><% for (int i = 10; i <= percent; i = 10) {%></p> <p><Td width = "10%" bgcolor = "# 000080"> </ td></p> <p><%}%></p> <p><% for (int i = 100; I> percent; i - = 10) {%></p> <p><TD Width = "10%"> </ TD></p> <p><%}%></p> <p></ TR></p> <p></ TABLE></p> <p>The task execution is divided into several states: is executing, completed, has not started, stopped:</p> <p><Table width = "100%" border = 0 cellpadding = 0 Cellspacing = 0></p> <p><Tr></p> <p><TD align = "center"></p> <p><% IF (Task.IsRunning ()) {%></p> <p>Be executing</p> <p><%} else {%></p> <p><% IF (Task.iscompleted ()) {%></p> <p>carry out</p> <p><%} else if (! task.isstarted ()) {%></p> <p>Not started</p> <p><%} else {%></p> <p>stopped</p> <p><%}%></p> <p><%}%></p> <p></ Td></p> <p></ TR></p> <p>A button is provided at the bottom of the page, and the user can use it to stop or restart the task:</p> <p><Tr></p> <p><TD align = "center"></p> <p><br></p> <p><% IF (Task.IsRunning ()) {%></p> <p><Form method = "get" action = "stop.jsp"></p> <p><Input Type = "Submit" value = "Stop"></p> <p></ Form></p> <p><%} else {%></p> <p><Form method = "get" Action = "start.jsp"></p> <p><Input Type = "Submit" value = "Start"> </ form></p> <p><%}%></p> <p></ Td></p> <p></ TR></p> <p></ TABLE></p> <p></ Body> </ html></p> <p>As long as the task is not stopped, the browser will display the calculation result 5050 after about 10 seconds:</p> <p>Fourth, stop the task</p> <p>The Stop.jsp page sets the Running tag to false to stop the current computing task:</p> <p><JSP: Usebean ID = "Task" Scope = "Session"</p> <p>Class = "Test.barbean.taskbean" /></p> <p><% task.setrunning (false);%></p> <p><jsp: forward page = "status.jsp" /></p> <p>Note The earliest Java version provides the thread.stop method, but JDK has not approved the Thread.stop method from the 1.2 version, so we can't call Thread.Stop ().</p> <p>When you run this article, you will see a little delay in the startup of the task; in the same manner, you can also see the task when you click the "Stop" button. If you stop running immediately (especially if the machine is relatively low) The delay is more obvious), which are caused by the compilation JSP page. After compiling the JSP page, the response speed is much faster.</p> <p>V. actual application</p> <p>The progress bar not only makes the user interface more friendly, but also the performance of the server, because the progress bar will constantly tell the user The current implementation progress, the user will stop frequently and restart (refresh) the current task again. On the other hand, creating a separate thread to perform a background task will also consume many resources. If necessary, consider the reuse of the Thread object if necessary. In addition, frequent refresh schedules also increase the network communication overhead, so be sure to keep the progress page is simple and short.</p> <p>In practical applications, the heavy tasks performed in the background may not be stopped, or it cannot provide detailed progress data. For example, when looking up or updating a relational database, the SQL command is not allowed to stop midway during execution - but if the user said he wants to stop or suspend the task, the program can return the transaction after the SQL command is completed.</p> <p>When analyzing the XML document, we have no way to know the percentage of exact content that has parsed. If you parse the XML document with a DOM until the parsing is complete, you can get the entire document tree; if you use SAX, although you can know the content of the current resolution, it is usually not determined that there are many content needs to be parsed. In these occasions, the implementation progress of the task can only be estimated.</p> <p>It is estimated that a task requires how much execution time is often difficult because it involves many factors, that is, the method of actual testing cannot obtain a reliable conclusion because the load is changed at any time. A simple approach is to measure the time required for the task, and then estimate according to the average time execution of the last few times. If you want to improve the accuracy of the estimation time, you should consider an algorithm for the application characteristics. Comprehensively consider a variety of factors, such as the SQL statement type to be executed, the complexity of the XML mode to be parsed, and so on.</p> <p>Conclusion: This example shows how it is quite easy to use JSP, Java, HTML, and JavaScript constructive schedule, how truly, how to use it in practical applications, especially the progress information of the background task, but this problem is not universal The answer, each of the tasks performed in the background has its own characteristics, and must be specifically analyzed according to the specific situation.</p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-129473.html</div><div class="plugin d-flex justify-content-center mt-3"></div><hr><div class="row"><div class="col-lg-12 text-muted mt-2"><i class="icon-tags mr-2"></i><span class="badge border border-secondary mr-2"><h2 class="h6 mb-0 small"><a class="text-secondary" href="tag-2.html">9cbs</a></h2></span></div></div></div></div><div class="card card-postlist border-white shadow"><div class="card-body"><div class="card-title"><div class="d-flex justify-content-between"><div><b>New Post</b>(<span class="posts">0</span>) </div><div></div></div></div><ul class="postlist list-unstyled"> </ul></div></div><div class="d-none threadlist"><input type="checkbox" name="modtid" value="129473" checked /></div></div></div></div></div><footer class="text-muted small bg-dark py-4 mt-3" id="footer"><div class="container"><div class="row"><div class="col">CopyRight © 2020 All Rights Reserved </div><div class="col text-right">Processed: <b>0.046</b>, SQL: <b>9</b></div></div></div></footer><script src="./lang/en-us/lang.js?2.2.0"></script><script src="view/js/jquery.min.js?2.2.0"></script><script src="view/js/popper.min.js?2.2.0"></script><script src="view/js/bootstrap.min.js?2.2.0"></script><script src="view/js/xiuno.js?2.2.0"></script><script src="view/js/bootstrap-plugin.js?2.2.0"></script><script src="view/js/async.min.js?2.2.0"></script><script src="view/js/form.js?2.2.0"></script><script> var debug = DEBUG = 0; var url_rewrite_on = 1; var url_path = './'; var forumarr = {"1":"Tech"}; var fid = 1; var uid = 0; var gid = 0; xn.options.water_image_url = 'view/img/water-small.png'; </script><script src="view/js/wellcms.js?2.2.0"></script><a class="scroll-to-top rounded" href="javascript:void(0);"><i class="icon-angle-up"></i></a><a class="scroll-to-bottom rounded" href="javascript:void(0);" style="display: inline;"><i class="icon-angle-down"></i></a></body></html><script> var forum_url = 'list-1.html'; var safe_token = 'ij_2FJ2oWNangg6xFJdlCfI7VZTSCCZrZH9VMAbTb_2Bf7WIE7RlF1bvU8A_2BvqczaHMz4ESjguOcab5LDGEj_2BpZj0A_3D_3D'; var body = $('body'); body.on('submit', '#form', function() { var jthis = $(this); var jsubmit = jthis.find('#submit'); jthis.reset(); jsubmit.button('loading'); var postdata = jthis.serializeObject(); $.xpost(jthis.attr('action'), postdata, function(code, message) { if(code == 0) { location.reload(); } else { $.alert(message); jsubmit.button('reset'); } }); return false; }); function resize_image() { var jmessagelist = $('div.message'); var first_width = jmessagelist.width(); jmessagelist.each(function() { var jdiv = $(this); var maxwidth = jdiv.attr('isfirst') ? first_width : jdiv.width(); var jmessage_width = Math.min(jdiv.width(), maxwidth); jdiv.find('img, embed, iframe, video').each(function() { var jimg = $(this); var img_width = this.org_width; var img_height = this.org_height; if(!img_width) { var img_width = jimg.attr('width'); var img_height = jimg.attr('height'); this.org_width = img_width; this.org_height = img_height; } if(img_width > jmessage_width) { if(this.tagName == 'IMG') { jimg.width(jmessage_width); jimg.css('height', 'auto'); jimg.css('cursor', 'pointer'); jimg.on('click', function() { }); } else { jimg.width(jmessage_width); var height = (img_height / img_width) * jimg.width(); jimg.height(height); } } }); }); } function resize_table() { $('div.message').each(function() { var jdiv = $(this); jdiv.find('table').addClass('table').wrap('<div class="table-responsive"></div>'); }); } $(function() { resize_image(); resize_table(); $(window).on('resize', resize_image); }); var jmessage = $('#message'); jmessage.on('focus', function() {if(jmessage.t) { clearTimeout(jmessage.t); jmessage.t = null; } jmessage.css('height', '6rem'); }); jmessage.on('blur', function() {jmessage.t = setTimeout(function() { jmessage.css('height', '2.5rem');}, 1000); }); $('#nav li[data-active="fid-1"]').addClass('active'); </script>