Notes on using InternetBeans Express

By: ddddddddddddddddddddddddd ffffffffffffffffffffffffffffff

Abstract: Using InternetBeans Express, you can write servlets and JSPs to display and edit data from DataExpress data sets in web pages. These notes explain how.

by Rick Gretter, JBuilder QA

Overview
Design time
Notes on specific input controls
Runtime
JSPs

Overview

InternetBeans Express is a set of components and JSP tag extensions for generating and responding to the presentation layer of a web application. It takes a template page of static HTML, inserts dynamic content from a live data model, and presents it to the client. Then it writes any changes that are posted from the client back into the data model.

When using servlets, you bind an InternetBeans Express component to each control in a template page that will receive dynamic content and post values back. You also bind an InternetBeans Express component to each control that can cause the page to be submitted. You provide event handlers for these controls, to react to the SubmitEvent that InternetBeans Express will fire for the control that triggers the post.

At runtime, you call IxPageProducer's servletGet() method to render a page that contains dynamic content. When your servlet receives a post, you call IxPageProducer's servletPost() method. This posts the data in the InternetBeans Express-enabled page and calls the appropriate event handler. ("Post" here means that the data values from the web application's UI are written to DataExpress data sets.) At this point, you can work with your Data Express components in the usual way to validate input, save data set changes to a SQL server, handle resolution errors, etc.

Compared to earlier technologies, servlets simplify web application programming by providing access to form data thorough API calls. We might summarize the explanation above by saying that InternetBeans Express goes a step further, replacing code manipulation of form data with a component- and event-based model. In this model, working with a database in a web application is very much like working with it in a Java application: what you know about JBuilder data modules, DataExpress components, data set events, and UI Designer still applies. Differences include the fact that your overall application structure may be quite different, you display data in HTML controls and elements rather than dbSwing or other Java components, and you can't use the Designer visually.

These notes concentrate on differences that are directly related to InternetBeans Express. Most of this material deals with servlets. The last section contains material specific to JSPs.

Design time

The basic sequence of events for creating an InternetBeans Express application using servlets is:

  1. Create an HTML form. It will typically contain a <FORM> element, <TABLE> elements, and <INPUT> controls.
  2. Create a data module, or use an existing one.
  3. Create the skeleton of a servlet. You can do this with the Servlet Wizard, though you will have to delete some code that it generates.
  4. Add code to the servlet to use the data module.
  5. Design the servlet: Drop components from the InternetBeans tab from the Component Palette into the design. Begin with an IxPageProducer, and set its htmlFile property to your HTML file and its dataModule property to your data module. Use one InternetBeans Express component for each element in the HTML file that you want to make data-aware. Set properties to bind each component to its element and to a data set (and often a column as well) in the data module.
  6. Generate skeletons of event handlers in the Designer, then write code for them and for the servlet's doGet() and doPost() methods.
  7. Repeat for additional HTML pages and servlets to process them, assuming your application requires more than one HTML page.
  8. To run within JBuilder, right-click the file that starts the application, for example an SHTML file created by the wizard, and select Web Run. The application's servlets are run in the Tomcat servlet container and displayed in the editor pane. Two new tabs, Web View and Web View Source, show you the running application and the generated source for the current page.
For more detail, see the tutorial in the "Using InternetBeans Express" topic of the Web Application Developer's Guide.

Using existing HTML files: JBuilder and InternetBeans Express are intentionally not HTML designers. When InternetBeans Express adds data-awareness to elements in an existing HTML page it does not change their size or position. So when you bind InternetBeans Express components to a web page, the look of the page doesn't change, except that its elements are now data-aware. You should only have to make a few small changes to use an existing HTML page:

  • <TABLE>, <IMG>, <DIV>, and <SPAN> and other HTML tags can be made data-aware by binding them to InternetBeans Express components. When you do this, a tag's ID attribute, which is otherwise optional, must be defined.
  • You must give each submit button a different name. Servlets allow them to share a name and use the value of the VALUE attribute to know which button was selected. In InternetBeans Express, each button is bound by name to its own InternetBeans Express component.
Data Modules: An InternetBeans Express application should usually use a data module. If you're using only one data set, you can define the data set directly in the servlet or JSP instead. Even then, if several data-enabled pages in the application use the same data, its simpler and better to define all the Data Express components just once in a data module. When you want to bind InternetBeans Express components in a single servlet or JSP to more than one data set, you must use a data module.

Using the Designer: Use DataExpress components just as you would when designing a Java front end. If you are using a data module, the DataExpress components should already be available in the Designer. If you are not, define your database and query in the usual way.

These components are available on the InternetBeans Express tab of the Component Palette:

  • IxPageProducer establishes the link between your HTML file and your DataExpress components. Its lists of available HTML element and control names are created when you set the IxPageProducer's htmlFile property. If you change the HTML file afterwards, you should clear and reset this property so that InternetBeans Express can rebuild its lists.
  • IxControl matches any HTML control. (An HTML control is a read/write visual component that appears inside a <FORM> element and is identified by the NAME attribute.) Although InternetBeans Express has a component to match each HTML control type, you can always use an IxControl instead. It will figure out which specific InternetBeans Express component matches the HTML control it is bound to. To bind an IxControl to an HTML control, set its controlName property to the HTML control's NAME attribute.
  • Components for HTML elements: Four InternetBeans Express components are bound to HTML elements such as <TABLE> and <IMG>. In each case, set the component's elementId property to the HTML element's ID attribute. The components are:
    • IxImage makes an <IMG> element data-aware. Don't use it for an ImageButton (<INPUT TYPE="IMAGE">), which is a control and should be bound to an IxControl or IxImageButton.
    • IxLink lets you create a data-aware link. There's a little more detail below.
    • IxSpan inserts read-only data into HTML output. It is most often used with <DIV> and <SPAN> elements. You can also use it to insert data from a data set into a heading or even into a link (if you want a link with dynamic text but a static URL). Define the ID attribute of the element, and set the IxSpan's elementId property to it.
    • IxTable displays an entire DataExpress data set. You can also specify which columns and how many rows to display. There's more on tables below.
  • Components for HTML controls: As discussed above, you can usually substitute IxControl for all these components. In several cases, you may want to use IxCheckbox, IxRadioButton, etc. instead:
    • The Designer may be a little easier to use because the Inspector can fine-tune the set of properties displayed. For example, you won't see dataSet and columnName properties for an IxSubmitButton.
    • IxControl does not work when you don't use a data set or data module. If you create your own custom TupleModel, you must use the specific component types.
Basic code in an InternetBeans Express servlet
Before looking at typical code that you'd write in an InternetBeans Express servlet, you should know how InternetBeans Express deals with the fact that a servlet typically handles request from many users. In a database web application, different users will navigate to different rows in the servlet's data set(s), which should cause the application's InternetBeans Express components to display different values in their associated HTML elements. Each user's position must be maintained between the time a page is rendered and the time updates to the displayed row are submitted to be posted. To support this, InternetBeans Express gives each user session its own set of DataExpress and InternetBeans Express components. So when you write code:
  • Any work you do in the servlet's jbInit() and init() methods uses the instances of components that you created in the Designer. This code is executed before the servlet begins responding to user requests. We call these prototype instances, because they are not actively used at runtime.
  • Any work you do in the servlet's doGet(), doPost(), or event handler methods uses components that are specific to your session. We call these per-session instances. You obtain references to them from your IxPageProducer.
Basic code for servlet methods is:
  • init():
    • You may not need any code in init() other than the call to super. If you want to do additional setup work that will apply to all users, such as adding custom cell renderers to a table, this is the place to do it. In this case, you'll probably want to begin by calling your IxPageProducer's getObjects() method. This will open your data sets, bind InternetBeans Express components to their HTML elements, and determine the columns to be displayed in tables. ( IxPageProducer's getObjects() method was accidentally omitted from the documentation. Use CodeInsight as the final authority on the API of JBuilder packages.)
  • doGet():
    • Delete code written by the Servlet wizard that sets content type, gets a PrintWriter, and writes to the PrintWriter.
    • Call IxPageProducer's servletGet() method to render the page. Often this is all you need, though you may add custom code here too.
  • doPost():
    • Delete code written by the Servlet wizard that sets content type, gets a PrintWriter, and writes to the PrintWriter.
    • Call IxPageProducer's servletPost() method, which posts data in InternetBeans Express components to their data sets and invokes the appropriate event handler.
    • Call your doGet() method if you want to display the same page again. Other options would be to respond with a redirect or to forward the request to another servlet or JSP with a RequestDispatcher.
  • Event handlers for submit buttons and image buttons:
    • Respond to the submit or image button. In the event handler for a button labeled "Cancel", for example, you would probably call your data set's cancel() method. Remember to use the per-session instances of data sets and InternetBeans Express components. Use IxPageProducer's getSessionComponent(), getSessionDataSet(), getSessionDataModule(), and getSessionTupleModel() methods to get them.
This is discussed in more detail in the reference documentation for IxPageProducer.

Notes on specific input controls

Tables: With most HTML elements and controls, the HTML code that InternetBeans Express generates is a lot like the code in the template document, except of course that the literal value between the start and end tags is replaced with dynamic data. But tables are much more complex. The generated table may differ from the template both in the set of columns and in the number or rows displayed. The rules for columns are:

  • If an IxTable component finds at least one valid column name in the HTML source for the table's heading, it only displays columns that match names found in the source.
  • If IxTable doesn't find any valid column names, it displays all columns in its data set.
  • Column names in the HTML and the data set do not have to be identical to "match": spaces, underscores, and casing are ignored when comparing names.
  • Some columns, such as Row ID columns and master link columns in a detail data set, have their visible property set to false by default. You might set other columns not visible. These columns are not displayed.
IxTable's rowCount property tells how many data rows to display. The default value is 20. If you mean to display all rows, be sure to set rowCount very high. To page through a data set, increment the IxTable's startRow property by the value of rowCount each time a button is pressed. InternetBeans Express won't try to display a row less than 0 or greater than the number of rows in the data set, so you don't have to test for those cases.

In InternetBeans Express, tables are read-only. Also, you can't bind InternetBeans Express components to nested tables. This is not as restrictive as it seems: you can nest non-data-aware tables, and can bind InternetBeans Express components to controls in nested tables. But you can't bind an InternetBeans Express component to a control that is inside a table bound to an InternetBeans Express component.

Like other InternetBeans Express components, IxTable preserves the style of its HTML <TABLE> element. This includes cells that are more than one row high or one column wide. IxTable uses the arrangement of cells that it finds in the table's header for each row it generates. In this case, you must supply valid column names in the header, since table rows and columns may not span properly if the expected number of data set columns can't be displayed. You can also vary styles between the header and the template data rows, or from one row to another. If you include more than one row of template data and the rows have different styles, IxTable will follow their pattern, alternating two or more row styles for as many rows as it outputs.

Checkboxes: A checkbox can be bound to a boolean or String column. When rendering HTML, InternetBeans Express sets the checkbox's status to checked if the value in the column is true (boolean) or "true" (String), and unchecked if the value is anything else. When posting data, InternetBeans Express knows that the request will not contain a name/value pair for a checkbox control that is unchecked. It posts the value false (boolean) or "false" (String) in this case.

Radio buttons: A set of radio buttons in HTML is identified by the fact that they all share the same NAME attribute. One IxRadioButton or IxControl maps to all the radio buttons in the set.

Picklists in select controls: If an HTML select control is bound to a column whose picklist property is set, the control gets its dropdown list from the picklist data set. This will replace a list defined in the HTML source by means of option tags. If the column doesn't have a picklist, the option values in the HTML are used.

If the picklist definition calls for multiple columns in the dropdown list, only the first column will be displayed. Lookups are not supported. The picklist is only built once, when the per-session InternetBeans Express components are instantiated. It will not be rebuilt in situations where a dbSwing list would be; for instance, a picklist on a column in a detail data set will not be rebuilt as the master is navigated.

Images: The GIF, JPEG, and PNG formats are supported. BMP is not, although dbSwing does support it, because BMP is not a web format. InternetBeans Express respects an image element's HEIGHT and WIDTH attributes if you set them, so your page layout doesn't change as you navigate through a data set even if images in the data are different sizes.

Links: You can create a data-aware link with IxLink. Its dataSet and columnName properties specify the data to be displayed as a link. Set its link property, a string, to the static part of the URL to link to. This may be something like "detailServlet?LinkValue=". At runtime, the data value in the current row will be appended to the value of the link property to create the HREF attribute in the generated HTML.

One weakness of IxLink is that the value displayed in the link on-screen is the same as the value passed in the HREF. You might prefer, for example, to show a product's description on-screen but pass its product number in the link. To do this, you could override the getDescription method, which is not very useful as it stands, to get its value from another data set column.

Runtime

Running a web application: The last step of the design overview summarized the JBuilder runtime environment for servlets and JSP:

  • Tomcat, a servlet-enabled web server, is included with JBuilder.
  • To run a servlet or JSP, right-click the file in the project pane and choose Web Run. To debug, select Web Debug instead. You can also define the application's starting file from the Project Properties dialog, then run or debug from the JBuilder menus or toolbar. To do this, select the dialog's Run tab; on it, select the JSP/Servlet tab (not the Application tab); and specify the start file there.
  • Two new tabs, Web View and Web View Source, are added to the editor pane when you first run a servlet or JSP. Web View shows your application running in the IDE's integrated web browser. Web View Source shows the source that the servlet or JSP generated.
Once an application is launched via Web Run, you can copy and paste the URL from the Web View pane into another browser and run your application there. In this way, you can see how your pages look in other browsers, particularly if you're using HTML options that the browser built into JBuilder doesn't support, or verify that your servlets support multiple concurrent users. It's a good idea to look at your output in more than one browser before concluding that there's a bug in your code or in InternetBeans Express. The problem may well be in the browser. The generated code on the Web View Source tab is also helpful when debugging.

Multi-user issues: Isolation of two users of the same servlet depends on the way their data is defined to InternetBeans Express. If you use a data module, each session gets a new instance of the data module. This means that user1 will not see user2's changes to a data set until user2 calls saveChanges() and user1 calls refresh(). If you use a data set, each session gets a DataSetView based on the data set. This means that each can see the other's changes as soon as they're posted.

Using a data set instead of a data module places some restrictions on your servlet. You can't do anything in the doPost() method or in an event handler that would try to fill the data set differently for each user. For instance, you can't run a parameterized query based on values the user enters in HTML controls. If you try, you'll find that every user see the data from the last query run. When you define a data set in your servlet (instead of referencing a data module), do it in jbInit. The usual way to do this is by setting its query property and letting the query run when the data set is opened. Once the servlet is up and running, only do operations that DataSetView supports, such as:

  • Maintaining a different position in the data set for each user (to let several users edit concurrently, for example)
  • Sorting the data set differently for each user
  • Filtering the data set differently for each user
  • Inserting, deleting, and modifying rows.
If you need to do more, use a data module, even if it only contains one data set.

Options: The dialogs in which you set servlet and JSP runtime options have online help. Here we'll just tell what you can set in each dialog.

  • In the Project Properties dialog, available from Project | Project Properties, the Run tab has a tab for JSP/Servlet settings. All settings here apply to the entire project or web application. They include
    • Run configuration options, such as the file to run and VM parameters and query string to use
    • Context parameters tab: parameters available to all servlets in the application
    • Server options tab: general servlet container options and setup of the specific servlet container used. The only one supplied is Tomcat, but others can be added through OpenTools.
    • IDE options tab: display, file handling, and debugging options.
  • Servlet properties:
    • HTML, HTM, SHTML, and JSP files in a JBuilder project have Web Run and Web Debug selections on their context menus. You can launch a web application from here instead of specifying a file to run at the project level.
    • Java files in a JBuilder project have a Properties selection on their context menus. The properties dialog includes a Web Run tab. (The tab is displayed for all Java files but is only useful if the class extends HttpServlet.) You can define servlet parameters and assign an alias to the servlet here. You can't run two instances of a servlet with different parameters through JBuilder, so the alias isn't used to distinguish between instances. It's still useful though, because defining an alias also defines a mapping of that alias to the servlet class. That way, you can reference the servlet by a name instead of using the full class name with the servlet invoker. For example, with the servlet invoker, you would need to use a URL like myserver/servlet/some.package.MyServlet; with an alias it would simply be myserver/myalias. In addition to being more direct, the aliased URL makes the servlet appear to be in the web root directory, so relative URLs (like to an images subdirectory off the root) will work.
JSPs

One key difference between a servlet and a JSP is that a JSP does not have a separate Java file. For the InternetBeans Express users, this fact has several consequences. One is that you can't use the Designer to create InternetBeans Express components and bind them to HTML controls. You do this work in the editor instead, and it is not a matter of setting properties on a component but of setting attributes for a custom tag. Another is that you have to modify your existing, non-data-aware JSP, unlike the servlet case, where InternetBeans Express reads your HTML and Java files and generates data-aware HTML code from them. Finally, an InternetBeans Express tag in a JSP is associated with an HTML element not by name but by its location in the code. To use InternetBeans Express with a JSP, then, you surround the HTML elements will receive dynamic content with InternetBeans Express start and end tags. You also add tags for DataExpress components, set attributes to connect your tags, and define event handlers in scriptlets. The basic concept -- that the page's layout and style is retained, but the content in its controls and elements is replaced with database data -- is unchanged.

Steps: Follow these steps to use InternetBeans Express with a JSP. If you use JBuilder's JSP Wizard, it will do the first two steps for you.

  • Add internetbeans.tld as a node in your project. (In the wizard, check the "Declare InternetBeans tag library checkbox.) This is the file that defines InternetBeans Express's custom tag library. It's in <JBuilder4_Directory>libinternetbeans.jar. Don't add the jar; browse into the jar in the file chooser, drill down to /com/borland/internetbeans/taglib/internetbeans.tld, and select just this file.
  • Add the InternetBeans Express and dbSwing libraries to your project.
  • Add the library that contains your database driver to your project.
  • Add JSP tags, directives, and scriptlets to your JSPs to enable InternetBeans Express functionality. The only required directive is the taglib directive to point to the custom tag library's TLD file: <%@ taglib uri="/internetbeans.tld" prefix="ix" %>. (The JSP Wizard will add this for you.) Other optional tags include:
    • A page directive to import the necessary classes
    • A <jsp:useBean> tag to access a data module as a bean. This has some interesting possibilities; for example, if you have parameterized queries, you can make their parameters properties of the data module object and use JSP syntax to automatically set values
    • InternetBeans custom tags to define a database and query, if you don't use a data module
    • InternetBeans custom tags to tell which controls serve as templates for the dynamic data and where that data comes from and goes to
    • Event handler scriptlets
Custom tags and their attributes: Because internetbeans.tld is an XML file, it's fairly self-documenting. Since it's in your project, you can conveniently view it in JBuilder. It lists all the InternetBeans Express custom tags, their attributes, and whether or not an attribute is required. The set of custom tags bears some resemblance to the set of InternetBeans Express components, with a number of differences that make sense given the differences between servlets and JSPs.
  • There's no pageProducer tag because the template HTML and dynamic Java content are combined in JSPs.
  • There are database and query tags because this information can't be supplied through DataExpress components as it can in a servlet.
  • The control tag is analogous to the IxControl component. There are no tags corresponding to specific components like IxCheckBox and IxRadioButton, but the control tag can replace all of them.
  • The submit tag is like the IxSubmitButton component. It differs from the control tag in two major ways: it isn't bound to a data set column, but it has a required methodName. The method, supplied in a scriptlet, does the same work as an event handler in a servlet would. It receives a single parameter, the JSP's PageContext object, from which all relevant information about the request can be determined.
  • There's an image tag, comparable to an IxImage component.
  • There's a table tag, comparable to an IxTable component. The table tag usually encloses a static HTML <TABLE> element, which in turn serves as a template for the data-aware HTML generated by the application. All this works just as described for table elements in servlets. In some cases, you might want to use a scriptlet to generate the <TABLE> dynamically instead. For example, you could let the application user specify which columns to display and the order they should appear.

  • There's no equivalent to the IxSpan and IxLink components because you can use a JSP expression to write a dynamic value to the page in read-only form. This value can be inside an HTML tag such as a header, a link, a <DIV>, or a <SPAN>, or it can be regular text on the HTML page.

Server Response from: SC2