Replace JSP new technology - Tapestry !!!

zhaozj2021-02-12  151

Replace JSP new technology - Tapestry !!!

(This article has been read 3466 times) Time: 2003/10/07 04:55 PM Source: SMLTIGER

In today's Web development, Java-based applications are increasing. In this, servlet played a very important role. This series of articles is to introduce some of the tools for servlet development, and there are a variety of technologies to choose from when developing. Servlet technology is undoubtedly an excellent technology, and the Java server-side technology is mostly based on servlet technology. However, this technique also has its own insufficient, for example, indicating that the layer (HTML code) is mixed with the code, and the reusability is not high. SUN then proposed JSP technology, JSP is also a technology-based technology, using it you can embed Java code in HTML. JSP moves a big step on the basis of servlet, but simple JSP has the shortcomings of the servlet mentioned above. However, using JSP JavaBean Taglib This development mode can solve the shortcomings mentioned above. But JSP itself has some other shortcomings, and details will be referred to the article of Problems with JSP. So people have developed some other servlet-based technologies. Let's first introduce TapeStry.

Introduction

Tapestry is an open source-based Servlet-based application framework that uses component object models to create dynamic, interactive web applications. One component is any HTML tag with JWCID attribute. Where JWC means Java Web Component. Tapestry makes Java code to completely separated from HTML, using this framework to develop large applications becomes lighter. And the application developed is easy to maintain and upgrade. TapeStry supports localization, and its error report is also very detailed. Tapestry is mainly developed by JavaBean and XML technology.

First application

Let's introduce TapeStry installation before introducing the first application. After downloading its latest version from SourceForge, place the JAR file in the lib directory in the classpath, put the WAR file in the Tomcat's WebApp directory. The TUTORIAL application can then be accessed by http: // localhost: 8080 / tutorial. One of the following components in TapeStry, we use their own HelloWorld program as an example:

Servlet: This is a part of an application: servlet class, this class must be the subclass of ApplicationServlet, and must implement the getApplicationsPecificationPath () method. Examples are as follows:

Import com.primix.tapestry. *; public class helloworldServlet Extends ApplicationServlet {protected string getApplicationspecificationPath () {return "/TUTORAL/HELLO/HelloWorld.Application";}

/Tutorial/hello/helloWorld.Application is an application's instruction file. Application Specification: It is actually describing an XML file for this app. There are many parameters in this app to set, Engine-Class will introduce, the name attribute in the page specifies the HTML file name, specification-pats specifies the description of this page. file. There are many Page in an app, but you must have a page of Name as "HOME", because when you access your app, the first display is this Page.

Application Engine:

When the customer is connected to the Tapestry app, TapeStry will create an Engine object (similar to session). Usually Application Engine in our program is generally an instance of the SimpleEngine class, of course, the subclass of this class can also be.

Page Spectation: Similar to the application, page description is also an XML description file:

Because this application is static, use com.primix.tapestry.baSepage, if it is a dynamic application, you need to define some Component in this file, of course, the use of BasePage is a class class class. HTML page: The HTML page of this app is very simple:

Hello World </ title> </ head> <body> <b> HelloWorld </ b> </ body> </ html></p> <p>Note that the various files mentioned above must be placed in a WAR's web-inf / class content.</p> <p>A complex application</p> <p>In this application, we will introduce Tapestry's common functions with a simple student management system. We have to achieve students' increase and display, so we need two HTML pages. As for the StudentServlet class and student.application, we will not describe, defined in Student.Application, two Page: Home and EditStudent, see attachments. Student Data is stored in the database, we use the Student class to indicate a record in the data, use the StudentFactory class to search for student data, these two classes use a JDBC wrapper, about this JDBC wrapper can see my other article < <Extension and application of a simple JDBC wrapper >>. First look at Home.html <html> <head> <title> Student Management </ Title> <meta http-equiv = "content-type" content = "text / html; charset = GB2312> </ head> <body BGColor = "# ffffff"> <p align = "center"> Student list </ p> <Table width = "100%" border = "1"> <tr> <td> study number </ td> <TD> Name </ TD> <TD> Gender </ TD> <TD> Class </ TD> <TD> <span jwcid = "liststudent> <Tr> <TD> <span jwcid =" id "> 20012400 </ Span> </ td> <td> <span jwcid = "sname"> Zongfeng </ span> </ td> <td> <span jwcid = "gender"> male </ span> </ td> <TD> <span jwcid = "department"> computer research one </ span> </ td> </ tr> <limited $ "> <td> 20011389 </ td> <td> Sang Yishan </ td> <TD> Male </ TD> <TD> Computer Research 1 </ TD> </ TR> </ Table> <a jwcid="add"> Add Student </a </ body> </ html ></p> <p>Unlike the previous simple applications, we define seven components in this page. Let's take a few home.jwc files, we will tell how to describe these components.</p> <p><Specification Class = "Test.ListStudent"> <component id = "liststudent" type = "foreach"> <binding name = "Source" Property-path = "student" /> <binding name = "value" property-path = "Eachstudent" /> </ component> <component id = "id" type = "insert"> <binding name = "value" protrudent.id "/> </ component> <component id =" Add "type =" page "> <static-binding name =" page "> editstudent </ static-binding> </ component> </ specification> Here, our Specification's class attribute value is no longer BasePage, but it Derive class liststudent. For each component, the id attribute specifies a unique identifier, this value corresponds to the JWCID value in the HTML file, TYPE specifies the component name, the binding specifies how the component gets the data, and Property-path is a collection of attributes, which is generally Define in the JavaBean, such as the above Property-path = "student", there should be a function GetStudent in the corresponding JavaBean class listStudent. ListStudent is a Foreach component, which is actually a for loop, which is read from the Source to the value specified by the value of the value parameter. ID, Name, Gnder, Department, the four is the INSERT component, this component is used to insert text data, the parameter value specifies the value to be inserted, and the Property-Path specifies how these values ​​are obtained, and Eachstudent.id is equivalent to calling JavaBean getStudent (). GetId (). Add is a PAGE component, and the page property specifies the page name (defined in the Application file), static-binding indicates that the data to be bound is unmodified. $ REMOVE $ component is not described in this file because this component is automatically deleted because TapeStry runtime. Let's take a look at the listStudent class:</p> <p>Package test; import com.primix.tapestry. *; import sun.jdbc.odbc.jdbcodbcdriver;</p> <p>/ *** Return to each student's data ** /</p> <p>Public class liststudent eachstudage {private;} () () () () () () () () () () ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,</p> <p>public Student getEachstudent () {return eachstudent;} public void setEachstudent (Student value) {eachstudent = value;} public Student [] getStudent () {try {Class.forName ( "sun.jdbc.odbc.JdbcOdbcDriver"); student = StudentFactory.FindallStudAntents ();} catch (exception e) {E.PrintStackTrace ();} returnit;</p> <p>}</p> <p>This class has four functions, where the DETACH function is the action that is performed when the page is placed in the buffer pool, and the getStudent function returns all student records, which is assigned to the source parameter of the ListStudent component in the JWC file, getEachstudent gives this component Value parameter Assignment, because Source is an array, each loop needs to be taken from the record assignment to Eachstudent, so there is a function to setEachstudent, you will notice this function is very simple, actually TapeStry helps you do most of the work. At this point, it shows that the part of the student has been completed, let's take a look at EditStudent.html</p> <p><html> <head> <title> Increase students </ title> <meta http-equiv = "content-type" content = "text / html; charSet = GB2312"> </ head> <body> <p> <img SRC = "student.gif" width = "32" height = "32" /> student management system </ p> <form jwcid = "form"> <span jwcid = "iferror"> <font size = 2 color = Red> <span jwcid = "inserterror" /> </ font> </ span> <p> student number: <input jwcid = "id" /> </ p> <p> Name: <input jwcid = "name" /> </ p> <span jwcid = "gender"> <p> gender: <input jwcid = "male" /> male <input jwcid = "female" /> female </ p> </ span> <p> Class: <input jwcid = "divartment" /> </ p> <p> <input type = "submit" value = "OK"> </ p> </ form> </ body> </ html></p> <p>In this document, some commonly used components are used, first look at the description of these components in EditStudent.jwc:</p> <p><specification class = "test.editstudent"> <component id = "form" type = "form"> <binding name = "listener" proty = "listener.formmit" /> </ component> <component id = " Gnder "type =" radiogroup "> <binding name =" success "property-path =" gender "/> </ component> <component id =" ifError "type =" conditional "> <binding name =" condition "Property- PATH = "error" /> </ component> <component id = "inserterror" type = "insert"> <binding name = "value" property-path = "error" /> <component> <component id = "ID "Type =" textfield "> <binding name =" value "proty =" id "/> </ component> <component id =" MALE "type =" radio> <field-binding name = "Value" field -Name = "Test.editStudent.Male" /> </ component> </ specification> form is an FORM component, and its parameter listener specifies that function processing when SUBMIT is form. IfError is a Conditional component, this component specifies that it will only be displayed when Condition is satisfied, in this case, if Error is not empty, then Condition is satisfied. In this component, there are components nested in the INSERT type to display errors. This is how often the handling errors often used in Tapestry. Gender is a Radiogroup component that binds the gender attribute in javabean, and the Selected parameter specifies that Radio is selected. In this component, two Radio components are nested, which are used to represent men, women. Radio's Value parameter specifies that when the user selects this RADIO, the attribute value of the RadioGroup bound will be equal to the value specified in Field-name (this value must be static), in this example, gender = test.editstudent.Male . ID is a TextField component whose parameter value is bound to the ID attribute in JavaBean. Below is the corresponding EditStudent class:</p> <p>Package test; import com.primix.tapestry. *;</p> <p>public class EditStudent extends BasePage {public static final int MALE = 1; public static final int FEMALE = 2; private int gender; private String error; private String id; private String sname; private String department;</p> <p>Public void detach () {error = null; id = null; sname = null; gender = 0; department = null; super.detach ();</p> <p>Public int getgender () {return gender;} public string getsname () {return getDepartment () {return sname</p> <p>public void setGender (int value) {gender = value; fireObservedChange ( "gender", value);} public void setId (String value) {id = value; fireObservedChange ( "id", value);} public String getError () { return error;} public void setSname (String value) {sname = value; fireObservedChange ( "sname", value);} public void setDepartment (String value) {department = value; fireObservedChange ( "department", value);} public void FormSubmit (IRequestcycle Cycle) {// Determines if the user has finished all data IF (Gnder == 0 || ID == null || id.equals (") || sname == null || sname.equals (" " ) || DEPARTMENT == null || Department.equals (")) {Error =" Please fill all the options "; return;} // save the student Try {student Student = new Student (); student.setID ID); Student.setName (SNAME); if (Gnder == 1) Student.setgender ("Men"); ElseStudent.setgender ("Female"); Student.SetDepartment; Student.Save (null); Catch (Exception E) {E.PrintStackTrace (); // Clear the current attributes to avoid reserving the original value setsname (null) when entering this page again, SETDEPARTMENT (NULL); setID SetGender (0); // Redirect to Home Page Cycle.SETPAGE ("HOME");</p> <p>}</p> <p>The FireObserveDChange this function is used in some of these setting properties of this class. This function is stimulated to change the event, and the value of notifying the current attribute has changed.</p> <p>other apps</p> <p>The localization example in Workbench in TapeStry demonstrates how to use localization, you only need to create HTML templates for different languages, as well as other HTMLs such as graphics. For example, create a French version of EditStudent.html, the corresponding HTML file is called EditStudent_fr.html, while the description of the components defined in the JWC does not have multiple versions. Here you will introduce a concept that TapeStry is often used in localization: assets. Assets is some resources used in Web applications, such as images, videos. There are three kinds of Assets: External, Internal and Private. The EXTERNAL type ASSETS is derived from any URL. The INTERNAL type Assets comes from the URL of the Tapestry to the same server. The Private type assets allows deployment in the WAR's web-inf / class directory (like the above HTML template, JWC files), this directory is invisible for the web server. Look at the piece of localization.jwc file in the localization.jwc file in Workbench: <component id = "changebutton" type = "imageSubmit"> <binding name = "image" proty = "assets.change-button" /> </ Component></p> <p><private-asset name = "change-button" resource-path = "/ tutorial / workbench / localization / change.gif" /></p> <p>In the ChangeButton component, use private assets, and these image files are placed under WAR's Web-INF / CLASSES, pay attention to the image of multiple languages ​​as the image is the same as HTML. Note that the INPUTLOCALE in the JWC file is actually localized by this component. Please see its developer guide for specific parameters.</p> <p><component id = "infutlocale" type = "protyselection"> <binding name = "value" property-path = "Page.Engine.locale" /> <binding name = "model" property-path = "localemodel" /> < / Component></p> <p>TapeStry also supports creation of its own reusable components, which brought one such example: border. At the same time, there are other examples: Inspector shows how to monitor your app. VLIB is a J2EE application (using JBoss as an application server) with TapeStry.</p> <p>TapeStry is very powerful, this article is only a small part of its small part, and there are many aspects that are not involved, such as the application of JavaScript in Tapestry. Specifically, you can see your document, I believe that if you use this frame, you will be deeply attracted. Tapestry's documentation is not very full, but after constant exploration, I believe you will master it quickly.</p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-7128.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="7128" 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.161</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 = 'Pj7rplsdFZgdlt55XtPzIaPYCuVbDg1fr5E0MiC6cWbg_2BlTsUH0MwS4Htt4rhzCeTdIN_2BqmgrCu9xSubRdGPYg_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>