New technology-tapestry to replace JSP

Source: Internet
Author: User
Tags foreach array empty final functions odbc object model java web
JS in today's web development, Java-based applications more and more. In this, the servlet also plays a very important role. This series of articles is to introduce a number of tools to support the development of the servlet, so that when you develop, there are a variety of technologies to choose from.
Servlet technology is undoubtedly an excellent technology, Java server-side technology is mostly based on servlet technology. But this technology also has its own shortcomings, such as: the presentation layer (HTML code) and code mixed together, reusability is not high. Sun then put forward JSP technology, JSP is also based on a servlet technology, using it you can embed Java code in HTML. JSP has made a big step on the basis of the servlet, but the simple JSP has the disadvantage of the servlet mentioned above. However, using jsp+javabean+taglib this development model can solve the shortcomings mentioned above. But the JSP itself has some other deficiencies, specifically see the Problems with JSP this article. So people have developed some other servlet-based technologies. Let's first introduce tapestry.

Brief introduction

Tapestry is an open-source, servlet-based application framework that uses the Component Object model to create dynamic, interactive Web applications. One component is any HTML tag with the Jwcid attribute. Where JWC means the Java Web Component. Tapestry makes Java code completely separate from HTML, making it easy to develop large applications with this framework. and developed applications are easy to maintain and upgrade. Tapestry supports localization, and its error reporting is detailed. Tapestry mainly uses JavaBean and XML technology to develop.

First Application

Before introducing the first application, let's introduce the installation of tapestry. Download the latest version from SourceForge, after decompression, put the jar file in the Lib directory into the Classpath, and put the war file in the WebApp directory of Tomcat. You can then access its tutorial application via http://localhost:8080/tutorial.
An application in tapestry consists of the following parts, which we use as an example of its own HelloWorld program:

Servlet:
This is the main part of an application: The Servlet class, which must be a 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 "/tutorial/hello/helloworld.application";
}
}


/tutorial/hello/helloworld.application is an application of the documentation.
Application Specification:
In fact, an XML file that describes this application, there are many parameters to set in this application, Engine-class will be described below, the name attribute in page specifies the HTML filename, specification-path Specifies the description file for this page. There can be many page in an application, but you must have a page named "Home" because when you access your application, the page is displayed first.

<?xml version= "1.0" encoding= "UTF-8"?>
<! DOCTYPE application Public "-//howard ship//tapestry specification 1.1//en" "Http://tapestry.sf.net/dtd/Tapestry_1_1. DTD ">
<application name= "Hello World Tutorial" engine-class= "Com.primix.tapestry.engine.SimpleEngine" >
<page name= "Home" specification-path= "/TUTORIAL/HELLO/HOME.JWC"/>
</application>


Application Engine:

When a customer connects to the tapestry application, tapestry creates a engine object (similar to session). Usually the application engine in our program is an instance of the Simpleengine class, and of course the subclass of the class is OK.

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


<?xml version= "1.0" encoding= "UTF-8"?>
<! DOCTYPE specification Public "-//howard ship//tapestry specification 1.1//en" "http://tapestry.sf.net/dtd/Tapestry_1_ 1.dtd ">
<specification class= "Com.primix.tapestry.BasePage"/>


Because this application is static, so use Com.primix.tapestry.BasePage, if it is a dynamic application, you need to define some component in this file, of course, use BasePage as a base class derived classes can also.
HTML page:
The HTML page for this application is very simple:


<title>hello world</title>
<body>
<b>HelloWorld</b>
</body>


Note that the various documents mentioned above should be placed in the Web-inf/classes directory of the war.

A complex application

In this application, we take a simple student management system as an example to introduce the common functions of tapestry. We want to achieve the increase and display of students, so we need two HTML pages. As for the Studentservlet class and student.application We do not describe, in the student.application definition of two page:home and editstudent, specifically look at the attachment. Student data is stored in the database, we use the student class to represent a record in the data, the Studentfactory class to retrieve student data, these two classes use a JDBC wrapper, about this JDBC wrapper can see my another article << to a simple The extension and application of JDBC wrapper >>.
First, take a look at home.html.


<title> Student Management </title>
<meta http-equiv= "Content-type" content= "text/html; charset=gb2312 ">
<body bgcolor= "#FFFFFF" >
<p align= "center" > Student List </p>
<table width= "100%" border= "1" >
<tr>
&LT;TD > School Number </td>
&LT;TD > Name </td>
&LT;TD > Sex </td>
&LT;TD > class </td>
</tr>
<span jwcid= "Liststudent" >
<tr>
<td><span jwcid= "id" >20012400</span></td>
<td><span jwcid= "sname" > Zong Feng </span></td>
<td><span jwcid= "Gender" > Male </span></td>
<td><span jwcid= "Department" > Computer Research </span></td>
</tr>
</span>
<tr jwcid= "$remove $" >
<td>20011389</td>
<td> Sang Yisan </td>
<td> male </td>
<td> Computer Research </td>
</tr>
</table>
<a jwcid= "Add" > Add student </a>
</body>

Unlike the previous simple application, we've defined seven components in this page, and we'll look at some of the HOME.JWC files here, and we'll talk about how to describe them.


<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" property-path= "Eachstudent.id"/>
</component>
<component id= "Add" type= "Page" >
<static-binding name= "page" >EditStudent</static-binding>
</component>
</specification>

Here, our specification class attribute value is no longer basepage, but its derived liststudent. For each component, the id attribute specifies a unique identifier that corresponds to the JWCID value in the HTML file, type specifies the component name, binding specifies how the component gets the data, and Property-path is a collection of properties. These properties are generally defined in JavaBean, such as the property-path= "student" above, and there should be a function liststudent in the corresponding JavaBean class getstudent. Liststudent is a foreach component, which is actually a for loop that reads an array from source and assigns one of its assigned values to the properties specified by the value parameter. Id,name,gender,department Four is an insert component that is used to insert text data, parameter value specifies the value to insert, Property-path specifies how to get the values, Eachstudent.id is equivalent to calling the Geteachstudent () of JavaBean (). GetId (). Add is a page component that specifies the page name (defined in the application file), static-binding indicates that the data to bind is not modifiable. $remove $ component is not described in this file because the Tapestry runtime automatically deletes this component.
Here's a look at the Liststudent class:

Package test;
Import com.primix.tapestry.*;
Import Sun.jdbc.odbc.JdbcOdbcDriver;


/**
* Return data for each student
*
*/

public class Liststudent extends BasePage
{
Private Student eachstudent;
Private student[] Student;
public void Detach ()
{
Eachstudent=null;
Student=null;
Super.detach ();
}

Public Student geteachstudent ()
{
return eachstudent;
}
public void Seteachstudent (Student value)
{
Eachstudent = value;
}
Public student[] Getstudent ()
{
try{
Class.forName ("Sun.jdbc.odbc.JdbcOdbcDriver");
Student=studentfactory.findallstudents ();
}catch (Exception e) {
E.printstacktrace ();
}
return student;

}

}


This class has four functions, where the detach function is the action that is performed when the page is put into the buffer pool, and the Getstudent function returns all student records, assigning values to the source parameter of the Liststudent component in the JWC file. Geteachstudent The value parameter of this component, because source is an array, each loop needs to take out a record assignment to eachstudent, so there is a function for seteachstudent, you will notice that this function is very simple, Actually, Tapestry helped you do most of the work.
At this point, show the student part has been completed, the following look editstudent.html

<title> Increase student </title>
<meta http-equiv= "Content-type" content= "text/html; charset=gb2312 ">
<body>
<p> Student management system </p>
<form jwcid= "Form" >
<span jwcid= "Iferror" >
<font size=+2 color=red><span jwcid= "Inserterror"/></font>
</span>
<p> School Number:
<input jwcid= "id"/>
</p>
<p> Name:
<input jwcid= "Name"/>
</p>
<span jwcid= "Gender" >
<p> Sex:
<input jwcid= "Male"/>
Man
<input jwcid= "female"/>
Woman
</p>
</span>
<p> class:
<input jwcid= "department"/>
</p>
<p>
<input type= "Submit" value= "OK" >
</p>
</form>
</body>


In this file, there are a few other common components to look at the descriptions of these components in EDITSTUDENT.JWC:


<specification class= "test. Editstudent ">
<component id= "form" type= "form" >
<binding name= "Listener" property-path= "Listeners.formsubmit"/>
</component>
<component id= "Gender" type= "Radiogroup" >
<binding name= "selected" 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" property-path= "id"/>
</component>
<component id= "male" type= "Radio" >
<field-binding name= "value" field-name= "test. Editstudent.male "/>
</component>
</specification>


The form is a form component whose parameter listener specifies that the function is processed when the form is submit. Iferror is a conditional component that specifies that it is displayed when condition is satisfied, and in this case condition satisfied if the error is not empty. In this component, there is a component nested with an insert type that is used to display the error. This is the way to handle errors that are often used in tapestry. Gender is a radiogroup component that binds the gender attribute in JavaBean, and the selected parameter specifies that the radio is selected, and in this component, two radio components are nested, respectively, to represent men and women. The Radio value parameter specifies that when the user selects this radio, the Radiogroup bound property value will be equal to the value specified in Field-name (this value must be static), in this case, gender=test. Editstudent.male. The ID is a TextField component whose parameter value is bound to the id attribute in JavaBean.
The following are the corresponding Editstudent classes:

Package test;
Import com.primix.tapestry.*;

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;

public void Detach ()
{
Error = NULL;
Id=null;
Sname=null;
gender=0;
Department=null;
Super.detach ();
}

public int Getgender ()
{
return gender;
}
Public String getId ()
{
return ID;
}
Public String Getsname ()
{
return sname;
}
Public String getdepartment ()
{
Return department;
}


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)
{
Determine if the user has finished adding all the data
if (gender== 0| | id==null| | Id.equals ("") | | sname==null| | Sname.equals ("") | |
department==null| | Department.equals (""))
{
Error = "Please fill out all options";
Return
}
Save the Student
try{
Student student=new Student ();
Student.setid (ID);
Student.setname (sname);
if (gender==1)
Student.setgender ("male");
Else
Student.setgender ("female");
Student.setdepartment (department);
Student.save (NULL);
}catch (Exception e) {
E.printstacktrace ();
}
Empty the current properties so that when you enter the page again, the properties still retain their original values
Setsname (NULL);
Setdepartment (NULL);
SetId (NULL);
Setgender (0);
Redirect to Home page
Cycle.setpage ("Home");
}

}


The function of Fireobservedchange is used in some of the settings properties of this class, which fires a change event that notifies the value of the current property to have changed.

Other applications

The localization example in Workbench in the example in tapestry shows how to use localization, you just need to create HTML templates in different languages, as well as other resources used in graphics and other HTML. For example, if you create a French version of editstudent.html, the corresponding HTML file name is editstudent_fr.html, and the description of the component defined in JWC does not have to be multiple versions. Here is an introduction to the concept that is often used in tapestry localization: assets. Assets is a resource used in some Web applications, such as images, videos. There are three kinds of assets: external, internal and private. The assets of the external type comes from any URL. The internal type of assets originates from the URL that tapestry applies to the same server. Private type assets are allowed to be deployed in the Web-inf/classes directory of the war (like the HTML template, JWC file above), which is not visible to Web servers.
Take a look at the fragment of the LOCALIZATION.JWC file in the localization example in Workbench:

<component id= "Changebutton" type= "Imagesubmit" >
<binding name= "image" Property-path= "Assets.change-button"/>
</component>

<private-asset name= "Change-button" resource-path= "/tutorial/workbench/localization/change.gif"/>

The private assets is used in the Changebutton component, and the image files are placed under the web-inf/classes of the war, noting that the image has more than one language version as well as HTML.
Note that the InputLocale component in the JWC file is actually localization application that is localized through this component. For specific parameters, please see their developer guide.

<component id= "InputLocale" type= "Propertyselection" >
<binding name= "value" property-path= "Page.engine.locale"/>
<binding name= "model" property-path= "Localemodel"/>
</component>

Tapestry also supports the creation of its own reusable component, which takes one such example: Border. It also has other examples: Inspector shows how to monitor your application. Vlib is a Java-ee application with tapestry as the presentation layer (using JBoss as an application server).

Tapestry is very powerful, this article only introduces a small part of it, there are many aspects not involved, such as JavaScript in the Tapestry application. You can look at its documentation and believe that if you use this frame, you will be attracted to it. Tapestry's document is not very complete, but after constant groping, I believe you will soon master it.





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.