Delphi Clinic | C++Builder Gate | Training & Consultancy | Delphi Notes Weblog | Dr.Bob's Webshop |
|
InternetBeans Express
When Java servlets were introduced Java developers could start developing web applications, with all the power of the Java environment.
But we had to write our HTML in the servlet source.
So if the user interface of our web application changed, we had to go into the servlet source file, make the changes and then recompile (and deploy) the servlet.
This approach is not useful, because our presentation logic and business logic were interconnected.
Then Sun released Java Server Pages (JSP) to solve this problem.
Now we could define the HTML outside our servlet source files.
Web designers can work on the Java Server Pages like they are normal HTML files and design the look-and-feel of the web application.
We developers can write our business logic in the servlets and then connect to a Java Server Page to display data.
And if this paradigm is applied correctly we get web applications which are easy to maintain and extend.
But JSP gives a lot of options and features among which the inclusion of Java source code in the page.
But this Java code is only executed when the page is requested by a user from a web browser.
So if the code contains errors, we will only notice this at run-time and not a compile time, like a normal Java class.
Of course we can pre-compile the JSP to overcome this problem, but that involves an extra process, which probably must be started outside our IDE (in our case JBuilder).
Also including Java source code in a JSP decreases maintainability of the web application.
Suppose we have built a web application and we wants to brand the web site so a different customer can define her own look-and-feel.
We make a copy of the JSP files and the web designers change the look-and-feel of the pages.
We develop a new release of our web application and must change the Java source in the Java Server Pages.
We have to make changes in two sets of JSP, which leaves room for errors.
It would be better if we could simply make the change at one point (in a regular Java class), which is re-used by both JSP sets.
So in a perfect world we would have Java Server Pages functioning as HTML templates, with placeholders or tags (and no Java source), which will be replaced with dynamic data from a servlet.
Well JBuilder 4's InternetBeans Express provides this functionality.
We can use static HTML template files (no JSP files), which are processed by a PageProducer
to insert dynamic data.
Or we can use the JSP 1.1 tag library extension to build Java Server Pages without Java code, but with custom tags.
These custom tags are really components, with functionality to replace such a tag with dynamic information.
The InternetBeans Express library contains custom tags we can use.
In this article we will look at the InternetBeans Express library and learn how to use it when developing web applications.
First we focus on the PageProducer
and static HTML template architecture.
In a future article we will see how we can use the custom tags from the InternetBeans Express library in our web application (and how to get some interaction).
Let's get started
We begin with a simple web application to see how the InternetBeans Express components work.
We create a new project (File | New project...) and then create a new Java servlet (File | New..., select the Servlet icon) with the Servlet wizard.
We fill in a package name, for example com.drbob42.ibeans
, and a class name, for example PageProducerServlet
.
The content type to be generated we leave to HTML.
The rest of the options we can leave as is.
Make sure the doGet() option is checked, because that is the method in which we are going to write our implementation.
When we press the Next button we go to the second page of the wizard.
We can create a SHTML file to start our servlet.
Because this is useful when developing the servlet we check the option Generate Link here.
On the final page of the wizard we can assign parameters for the servlet, but for now we don't use any parameters, so we can leave the table empty.
We press the Finish button and JBuilder generates the SHTML file and servlet source file.
To check if everything works we right-click with our mouse on the generated SHTML file and select Web Run.
JBuilder will start Tomcat and the SHTML page with the link is shown in the Web View tab page of the Content pane.
We can click on the link and the PageProducerServlet
is executed.
If everything goes well we get the following output:
The servlet has received a GET. This is the reply.
Well nothing special here, but now we are going to add a static HTML template file, with special placeholders, which will be replaced by the PageProducer
component.
Select Project | Add Files / Packages..., go to the project directory and fill in a filename for the static HTML template file, for example template.html
.
We can now write HTML code in the file:
<html> <head> <title>PageProducer template</title> </head> <body> <h2>InternetBeans Express Example</h2> <p>This page contains static HTML content, like what you read now, but also contains some dynamic content: <span id="time">here goes the dynamic content</span>. </p> </body> </html>
This looks like a normal HTML file, the only special thing is the <span> tag with the id attribute.
This tag (and the body of the tag) will be replaced with dynamic generated data from the servlet.
The body of the tag is only a dummy to get an impression of the content, but remember it will be completely deleted when the tag is replaced.
We open the servlet source file and click on the Design tab to open the Visual Designer.
Normally we would open the Visual Designer when designing applications with a normal user interface, but we can also add non-visual components to classes with the Visual Designer.
And that is what we are going to do in our web application.
We select the InternetBeans page of the Component Palette.
This page contains all the InternetBeans Express components.
We will look at each of these components in more detail later, but for now we only need to select the IxPageProducer
component () and drop it somewhere in the Visual Designer.
When we look at the Structure pane we notice an extra component in the Other node: ixPageProducer1.
We select the component and in the Object Inspector we can see the properties of the IxPageProducer
component:
ixPageProducer1
to page
for better readability.
And we assign our template file, we have created earlier, to the htmlFile
property.
Notice we must use the absolute filename here.
We return to our source code to make some changes.
We want to use the output of the IxPageProducer
component to sent back to the web browser.
The IxPageProducer
component has got a render()
method to get the generated content.
All tags which need to be replaced with dynamic content are handled and the complete generated HTML page is available.
So we change the doGet()
method and remove the generated lines, which start with out.println(...
.
Then we add the following line:
page.render(OutputWrapper.newWrapper(out));
render()
method, which takes a single argument of type OutputWrapper
.
We can wrap our out
object and use it as an argument.
So the rendered HTML is sent to the out
object and the out
object is responsible for sending the data to the web browser of the user.
The complete doGet()
method now looks like this:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); page.render(OutputWrapper.newWrapper(out)); }
Save and compile the servlet and test it using the Web Run option.
We should see the contents of the template file unmodified.
We haven't written any logic yet which will replace the <span> tag with dynamic content.
But before we do that we will look at a different method to return the output of the IxPageProducer
component.
We have used the render()
method, but the IxPageProducer
component contains another useful method to render the contents of a IxPageProducer
component: servletGet()
.
When we invoke this method in the doGet()
method of our servlet, all session handling and more housekeeping is done by the IxPageProducer
component.
So let's go back to our servlet and delete the body of the doGet()
method and replace it with the following line:
page.servletGet(this, request, response);
Run the application again to see the result is the same as with the previous statements.
Okay, now we know how to render a IxPageProducer
component.
Let's start writing code to replace the tags with dynamic data.
Our template file contained the following text:
<span id="time">here goes the dynamic content</span>
The id attribute is used by the IxPageProducer
component to identify the tag on the page and uses the attribute to assign it to a InternetBeans component.
The IxPageProducer
component will parse the template file for tags and tries to assign a tag to a InternetBeans component.
For the different types of tags, we have different types of InternetBeans components.
For example the <span> tag is coupled with the IxSpan
component.
Let's see how this work.
Go to the Design tab of the servlet and locate the IxSpan
component () and drop it in the Designer.
Rename the component to spanTime
.
Now we must tell the IxSpan
object, which IxPageProducer
component it belongs to using the pageProducer
property.
The property shows a combobox with the available IxPageProducer
components in our servlet.
In our case we only have one: page
.
We select the page
component.
JBuilder now parses the template file associated with the page
component and will populate the elementId
property combobox.
Here we select time
, because that is the value of the id attribute of our <span> tag, which need to be replaced.
So now our spanTime
object is connected to the <span> tag on our template page.
We only have to set the value for this component, which will used to replace the tag.
Go back to the servlet source and add the following line at the beginning of the doGet()
method:
spanTime.setValue(new Date().toString());
The complete doGet()
method is:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { spanTime.setValue(new Date().toString()); page.servletGet(this, request, response); }
When the IxPageProducer
component is rendering the page it will use the value to replace the tag, which is associated with the spanTime
object.
Save and compile the servlet and run the web application again.
If everything goes well we should see the following output:
InternetBeans Express ExampleThis page contains static HTML content, like what you read now, but also contains some dynamic content: Sun Dec 17 12:49:20 CET 2000. |
And the HTML source:
<html> <head> <title>PageProducer template</title> </head> <body> <h2>InternetBeans Express Example</h2> <p>This page contains static HTML content, like what you read now, but also contains some dynamic content: <span id="time">Sun Dec 17 12:49:20 CET 2000</span>. </p> </body> </html>
We notice how the body of the <span> tag is replaced with the current date and time!
So now we get a more clearly view on how the IxPageProducer
component works.
The component will parse the static HTML template file for any elements with an id attribute or name attribute for HTML Form elements.
For every element on the template page we want to replace we add a InternetBeans component in our servlet.
We connect the InternetBeans component to the IxPageProducer
object and the elementId on the template page.
When the IxPageProducer
component renders the page, it will invoke the render() methods of each of the InternetBeans components we have added to the servlet.
The render() method prints the dynamic content of the tag.
A step further
We extend our web application a bit further.
We want to add an extra attribute to the <span> tag and use the value of this attribute to set a different value for the IxSpan
component.
Let's add two attributes to the <span> tag:
If we set the language and country to values for the Netherlands locale we get the following line in our template file:
<span id="time" language="nl" country="NL">here goes the dynamic content</span>.
We want to use the values for the extra attributes to construct a localized DateFormat
object, which will display the current date and time using the format for the specified locale.
We open our servlet source file again and place the cursor at the beginning of the doGet()
method and change the body of this method to:
1: // Go through template and populate objects 2: page.getObjects(); 3: 4: // Get language attribute and country attribute 5: String language = spanTime.getAttribute("language"); 6: String country = spanTime.getAttribute("country"); 7: 8: // Construct Locale object and display object 9: Locale locale = new Locale(language, country); 10: DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, 11: DateFormat.FULL, locale); 12: 13: // Set value for "time" tag 14: spanTime.setValue(df.format(new Date())); 15: 16: // Send output to browser 17: page.servletGet(this, request, response); 18: }
In line 2 we invoke the getObjects()
method on our page
object.
This will merge the template file and populate all internal objects.
So all tags are parsed and the tags which associated InternetBeans objects are instantiated.
The IxComponent
class contains the
getAttribute()
method.
We invoke this method to get attribute values from a HTML tag, which is connected to an InternetBeans component.
In lines 5 and 6 we get the values for the language and country attributes we have just added to our template file.
In lines 9-11 we create the Locale
object with the attribute values and create a DateFormat
object.
Line 14 sets the value for the spanTime
object, which will be used to replace the <span> in the template file.
complete source of servlet)
When we run the servlet we get the following output:
InternetBeans Express ExampleThis page contains static HTML content, like what you read now, but also contains some dynamic content: zondag 17 december 2000 16:05:52 uur CET. |
And if we change the value of language to en
and country to UK
we get the following output:
InternetBeans Express ExampleThis page contains static HTML content, like what you read now, but also contains some dynamic content: Sunday, December 17, 2000 4:11:38 PM CET. |
Create our own InternetBean
Almost all of the InternetBeans components will replace the body of a HTML tag with the dynamic content we define in our servlet.
For example the text between the <span> tags is completely replaced with the date value.
But what if we want to keep the body of a tag and use it ourselves? Then we must create our own InternetBeans component.
We must subclass the correct classes and override certain methods.
We will built a new component which will have a condition property.
If the condition is true
the body of the tag is displayed.
Otherwise if the condition property is false the body of the tag is not displayed.
We go to File | New and select the Class icon to create a new class.
In the New Class wizard we must fill in a package name, for example com.drbob42.ibeans
, and a class name, for example IxConditional
.
We extend our class from com.borland.internetbeans.IxSpan
, because we can inherit a lot of the functionality from this class.
Our tag will also be connected to a HTML tag with id attribute like the IxSpan
class.
We click the Finish button so JBuilder can generate the source for the class.
We must add a property to this class, condition of type boolean
.
The user can set a condition for an instance of the IxConditional
class and we will use this value to determine if the tag's body needs to be displayed or not.
Click on the Bean tab page and then the Properties tab page.
Select the Add property... button and add a property with the name condition and type is boolean.
We click the OK button to close this dialog and we return to the source code.
We want to access the tag's body text and therefore we must override the mergeBody()
method.
When the PageProducer
component builds a list of components found on the template page, it will skip a tag's body text.
In this method we can access the body text ourselves and manipulate it.
Go to Wizards | Override Methods... and select the mergeBody()
method from the IxComponent
class.
JBuilder now inserts the method with a dummy implementation.
The method has three arguments:
ParseUnit[] units
.
Array with elements the PageProducer
is working on.
An element can be for example a HTML begin tag, end tag, or HTML tag body.
And this body element is what we want here.
int beginIndex
.
The array index of the element after the start tag.
In our case this will be the body of the tag.
If the body is empty, the index will point to the end tag and be equal to the endIndex
argument.
int endIndex
.
The array index of the element after the body.
In our case that will be the end </span> tag.
Well, all ingredients are there.
Now we must get the body from the units
array and assign it to the component's value property and we are done.
The following piece of code shows the mergeBody()
method (complete source of component):
public void mergeBody(ParseUnit[] units, int begin, int end) { // See if any body text is available by looking if the // begin index is less than end index. if (begin < end) { // if condition is true we assign the tag body to the value if (condition) { StringBuffer body = new StringBuffer(); // A body can contain other HTML tags, like <b>...</b>, // so we go through all unit elements until we are // at the end element for (; begin < end; begin++) { body.append(units[begin].tostring()); } value = body.tostring(); // if condition is false we assign empty string to value } else { value = new String(""); } } }
We can add new <span> tags to our template file:
<h2>Conditional tag</h2> <p> <span id="loggedin">Welcome user. You are logged in.</span> <span id="notloggedin">You are <b>not</b> logged in.</span> </p>
So if the condition for the tag is true, then the body of the tag will be shown.
Now we must connect these tags with our created components in the servlet source file.
We open the servlet source file and select the Design tab.
We can add our newly created InternetBean to the Component Palette, but we use a shortcut here: the BeanChooser.
At the left of the Component Palette we have a button, which is the BeanChooser.
Here we select our IxConditional
class and then we drop the class twice in the UI designer.
We need two IxConditional
objects, because we have the conditional tag for the condition when the user is logged in or when the user isn't logged in.
Change the names of the added components to conditionLoggedIn
and conditionNotLoggedIn
.
Now we can set the property pageProducer to our page
object and then we can select the correct elemenId property value: conditionLoggedIn
points to loggedIn and condtionNotLoggedIn
points to notLoggedIn.
Finally we must assign the condition to the IxConditional
objects.
We go back to the source of the servlet and place the cursor at the beginning of the doGet()
method.
Here we add the following lines (complete source code of servlet):
conditionLoggedIn.setCondition(request.getRemoteUser() != null); conditionNotLoggedIn.setCondition(request.getRemoteUser() == null);
We test if the request.getRemoteUser()
method returns null
or not.
If null
is returned the body of the <span> tag with id value notloggedin is displayed.
If not null
is returned the body of the <span> tag with id value loggedin is displayed.
Suppose the method returns null
we get the following output in our web browser:
Conditional tagYou are not logged in. |
And suppose the user has logged in and the method request.getRemoteUser()
doesn't return null
we have the following output:
Conditional tagWelcome user. You are logged in. |
In this article we have learned about the InternetBeans Express library found in JBuilder 4.
We used the IxPageProducer
component and a simple replacement component: IxSpan
.
We have learned how to access attributes from a tag.
And finally have created our own InternetBeans component, IxConditional
, by extending an existing component.
But this is just scratching the surface of the InternetBeans Express library.
The library contains many more components like lists, comboboxes, HTML form element, tables.
These components have a model associated with them for the data, but can also be connected to the DataSet
components found in the DataExpress library.
And finally we can use the InternetBeans library as a JSP 1.1 tag library.
These topics will be covered in future articles.