fn:substringAfter Returns a string value that follows a specified substring.string, substring Example, fn:substringAfter“peppermint”, ”pepper”returns mint.fn:substringBefore Returns a st
Trang 1Code Reuse with tag and tagx Files
The implementation of tag and tagx file syntax delivered with JSP 2.0 implementations allows for bettercode reuse by enabling developers to encapsulate common behavior that can be easily shared acrosscomponents Those familiar with older code conventions used to craft custom tag libraries should recog-nize this and embrace these amendments for defining reusable custom actions with great enthusiasm
The following code snippet demonstrates how tag files can be implemented for reuse by other webapplications In this example, a portlet-like visualization component is crafted using a tagged file namedportlet.tag Two parameters, titleand color, are passed into the portlet tag file to dynamicallyalter those properties in the component display:
<%@ taglib prefix=”tags” tagdir=”/WEB-INF/tags” %>
<%@ attribute name=”title” required=”true” %>
<%@ attribute name=”color” required=”true” %>
<table width=”250” border=”1” cellpadding=”2” cellspacing=”0”>
<tr bgcolor=”${color}” color=”#ffffff”>
361
Trang 2After this code is run, a simple portlet-like component is displayed with two test references embedded
in it What the reader should take away from this is how easily this syntax can be implemented to ate custom tags and share them across a project’s code base Consideration might be given for imple-menting tag files in header and footer implementations that contain common information that can beeasily propagated to the other web pages with their inclusion
gener-JSP Page Extensions (.jspx)
Java Server Page 2.0 syntax has included jspx extensions that are meant to advocate the use of XML tax to generate XML documents in JSP 2.0-compliant web containers The following code describes how.jspx files can be implemented when you develop web applications to generate user displays:
Please enter your name and address:<br/>
<input name=”name” size=”40”/><br/>
<input name=”address” size=”40”/><br/>
Trang 3<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML Basic 1.0//EN”
Simple Invocation Protocol
This API enhancement was developed to exploit the use of scriptless pages among web developers usingJSP libraries in their development activities for implementing tag files
In the following code example, the <lottery:picks/>tag file invocation demonstrates how simple it is
to incorporate logic into a web page using tag libraries:
<%@ taglib uri=”/WEB-INF/tlds/lottery.tld” prefix=”lottery” %>
Trang 4The LotteryPickTagapplication illustrates how the SimpleTagSupportclass can be extended toallow developers to craft tag handlers The doTag()method is invoked when the end element of the tag
is realized In the sample Lottery application, the getSixUniqueNumbers()method is called from thedoTag()method, which in turn displays the string output of six unique lottery numbers generated inrandom fashion:
public String getSixUniqueNumbers() {StringBuffer sb = new StringBuffer();
int count = 0, number = 0;
int numbers[] = {0,0,0,0,0,0,0};
boolean found;
while (count < 6) { number = (int)(Math.random()*59) + 1;
found = false;
for (int i=0; i < numbers.length; i++)
if (numbers[i] == number) found = true;
}}
JSP tag files are converted into Java code by the JSP container in the same fashion that JSP scripts aretranslated into servlets It should be fairly evident from this example how easily tag files can be con-structed for deployment in web components for enterprise systems because they hide the complexity ofbuilding custom JSP tag libraries, which makes them easier to maintain in the long run
Figure 7-2 outlines visually some of the enhancements of the JSP 2.0 specification along with some of thebackwards compatibility issues that are addressed in the JSP 2.0 specification
Certainly, the JSP 2.0 upgrade, with its ready-made Expression Language implementations, along withimprovements in Java Server Pages Standard Tag Libraries, will enhance developer’s abilities to buildcohesive and robust web components
Trang 5Figure 7-2
Integrated Expression Language (EL)
The following section concentrates on the Expression Language (EL) and its implementation in JSPapplications Certainly, there is ample content in the JSP 2.0 specification to discuss and demonstrate,especially some of the Servlet 2.4 features that were discussed briefly earlier, but this section concen-trates on EL implementations because they are exploited prominently in the Contact Management Tool.Some of the other aspects of that specification are fairly involved and extend beyond the scope of thischapter
EL expressions can be used with three different attribute values First, they can be applied when anattribute value has a single expression; second, they can be used when the attribute value contains one
or more expressions surrounded or separated by text; and lastly, they can be used when the attributevalue contains only text The following table shows how these operations can be implemented
Single expression <xyz.tag value=”${expression}”/>
One or more expressions <xyz.tag value=”abc${expression}text${expression}”/>Text only <xyz.tag value=”abc text”/>
JSP 2.0 scripts allow EL expressions to perform conditional operations on your web page variables Anexample of this follows:
<c:if test=”${param.Comments > 250}”>
</c:if>
Lack of EL support in JSP 1.2 pages
JSP interpretation
of *.jspx files by default
‘/$’ support no longer there, returns
‘$’
Tag Library Validation
Tag coercion rule adherence
Servlet 2.4 Specification support
*.tag and *.tagx support for reuse
Simple Invocation Protocol for script- less pages
JSP page extensions (*.jspx)
Expression Language (EL) Support
extends
I18N behavior differences
web.xml
365
Trang 6The parameter param.Commentsis checked to see if it is greater than 250; if so, the logic that liesbetween the ifstatement is executed.
The JSTL core tag libraries can also be used for variable output Here is an example of this:
<c:out value=”${testELexpression}”/>
JSP 2.0 pages implement several different implicit objects through EL expressions; the table that followslists some examples
pageContext Accesses the PageContextobject, which provides access to all the
namespaces associated with a JSP pagepageScope A Map that contains page-scoped attribute names and values
requestScope A Map that contains request-scoped attribute names and values
sessionScope A Map that contains session-scoped attribute names and values
applicationScope A Map that contains application-scoped attribute names and valuesparam A Map that correlates parameter names to single Stringparameter
valuesparamValues A Map that correlates parameter names to a String[]of all values of
that parameterheader A Map that contains header names in a String
headerValues A Map that contains header names in a Stringarray componentcookie A Map that contains web cookie objects
initParam A Map that holds context initialization parameter names and their values
Implicit objects (for example, objects that don’t need to be declared and are declared automatically)allow developers to access web container services and resources
JSTL 1.1 Overview
Capabilities of the Java Standard Template Library (JSTL 1.1) specification are too numerous to elaborate
in great depth, so this chapter concentrates on two tag library capabilities that are helpful in the sampleContact Management Tool (CMT) The CMT application persists data in a MySQL database during stor-age and retrieval operations so the SQL Actions libraries are implemented and the Function Tag Libraryoperations are used for string manipulation The latter is discussed as well
Function Tag Library
The Function Tag Library capabilities were introduced with the JSP 2.0 specification to allow developers
to extend EL functionalities with string manipulation libraries The JSTL 1.1 specification outlines thesefunctions as follows The following table demonstrates some of the new method functions available aspart of the expression language support in JSP 2.0
Trang 7Function [fn:] Description of Function
fn:contains If the substring exists in a specified string value, true(string, substring) will be returned to the user, otherwise false
Example, fn:contains(“independence”, “depend”)returns true
fn:containsIgnoreCase Ignoring case differences, if a substring exists in a (string, substring) specified string value, truewill be returned to the user,
otherwise false.Example, fn:containsIgnoreCase(“independence”,
“DEPEND”)returns true.fn:endsWith(string, suffix) Tests the end of a string with the suffix specified to
determine if there is a match
Example, fn:endsWith(“whirlyjig’, “jag”)returnsfalse
fn:escapeXml(string) Escape characters that might be XML
Example, fn.escapeXml(“<test>yea</test>”)returns converted string
fn:indexOf(string, substring) Returns integer value of the first occurrence of the
specified substring in a string
Example, fn:indexOf(“democratic”, “rat”)returns 6
fn:join(array, separator) Joins elements from an array into a string with a specified
separator
Example, array[0]=”X”, array[1]=”Y”
fn:join(array,”;”)returns String = “X;Y”
fn:length(item) Returns a collection count or the number of characters in
a string as an integer value
Example, fn.length(“architecture”)returns 12.fn:replace Returns a new string after replacing all occurrences of the (string, before, after) beforestring with the afterstring
Example, fn:replace(“downtown”, “down”, “up”)returns uptown
fn:split(string, separator) Returns an array where all the items of a string are added
based on a specified delimiter
Example, fn:split(“how now brown cow”,” “)returns array[0]=”how”, array[1]=”now”,array[2]=”brown”, array[3]=”cow”
fn:startsWith(string, prefix) Returns a Boolean value (true/false) depending on
whether or not a string contains a specified prefix value.Example, fn:startsWith(“predicament”, “pre”)returns true
Table continued on following page
367
Trang 8Function [fn:] Description of Function
fn:substring Returns a substring of a string based upon specified
Example, fn:substring(“practical”, 2,5)returnsact
fn:substringAfter Returns a string value that follows a specified substring.(string, substring) Example, fn:substringAfter(“peppermint”,
”pepper”)returns mint.fn:substringBefore Returns a string value that precedes a specified substring
SQL Actions
A general rule of thumb for SQL transactions on enterprise systems is to handle database operationswithin business logic operations (as demonstrated with the Add Contact web application in Figure 7-6,later in this chapter) But sometimes you might want to perform those activities with the SQL taglibraries that are part of the JSTL 1.1 libraries
JSTL SQL Actions allow developers to interact with databases on the presentation layer An overview ofits capabilities include the ability to perform queries through SELECTstatements, database updates withinsert, update, and delete operations, and transactional activities that allow the aggregation of databaseoperations
Trang 9The following table illustrates the SQL Action tags for establishing a data source.
<sql:setDataSource> This tag exports a data source
<sql:setDataSource{datasource=”dataSource” |url = “jdbcUrl”
[driver = “driverClassName”]
[user = “userName”]
[password = “password”] } [var=”varName”]
[scope=”{page|request|session|application}”]/>
The following table illustrates the SQL Action tags for query operations
<sql:query> This tag queries the database
Without body content
Trang 10The following table illustrates the SQL Action tags for update operations.
<sql:update> This tag executes an INSERT, UPDATE, or DELETEstatement
Without body content
Developing Your Web Application Visualizations
with JSTL 1.1
The following code example demonstrates the use of SQL actions mentioned previously The first course
of action in your code is to establish a data source object that will allow the application to connect to the
picture database so queries can collect data for visualization on your JSP page:
<%@ page language=”java”
contentType=”text/html”
import=”java.util.*,java.lang.*,java.io.*” %>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core_rt” %>
<%@ taglib prefix=”sql” uri=”http://java.sun.com/jstl/sql” %>
<link href=”CMT.css” rel=”stylesheet” type=”text/css”>
<sql:setDataSource
Trang 11After the data source has been established, a query is performed using the database reference
${pictures}where the result set is stored in the resultsvariable:
<sql:query var=”results” dataSource=”${pictures}”>
select * from picture
Trang 12Figure 7-3
The addProfile.jspapplication uses both the core tag libraries for logic operations and the SQLactions to perform form processing actions on the Add Profile page Once the form has been properlyfilled out, checks will be done to ensure that required fields have been entered Once those checks havebeen performed, and the application has determined that the form entries can be pushed to the back-enddatabase, the application will send the data to the registration database for storage and subsequentretrievals:
Trang 13<! addProfile.jsp >
<%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core” %>
<%@ taglib prefix=”fmt” uri=”http://java.sun.com/jstl/fmt” %>
<%@ taglib uri=”http://java.sun.com/jstl/sql_rt” prefix=”sql” %>
<script language=”JavaScript”>
function textCounter(field, countfield, maxlimit) {
if (field.value.length > maxlimit) {field.value = field.value.substring(0, maxlimit);
} else {countfield.value = maxlimit - field.value.length;
}}
</script>
The JSTL 1.1 core library tags are used in the following code to perform logic operations on the formentries specified by the user If either firstName, lastName, or emailis empty, the application will notallow the form to pass the data to the back-end registration database:
<c:if test=”${param.submitted}”>
<c:if test=”${empty param.firstName}” var=”noFirstName” />
<c:if test=”${empty param.lastName}” var=”noLastName” />
<c:if test=”${empty param.email}” var=”noEmail” />
<c:if test=”${not (noFirstName or noLastName or noEmail)}”>
<c:set value=”${param.firstName}” var=”firstName” scope=”request”/>
<c:set value=”${param.lastName}” var=”lastName” scope=”request”/>
<c:set value=”${param.email}” var=”email” scope=”request”/>
Once the user has entered the proper form entries, the data source will be established with the SQLaction tags by passing familiar JDBC driver, url, user, and passwordparameters to the library to create
a connection After the connection has been created, the SQL update tag <sql:update>can be used toperform an insert operation on the registration database using a prepared statement construct:
<sql:setDataSourcevar=”datasource”
Trang 14The following code represents the registration form and its components that will be used to register tacts in the Contact Management Tool EL constructs, such as ${param.lastName}, are used to repre-sent and persist data items entered by the form user:
<tr>
<td align=”left” nowrap=”nowrap” class=”field” colspan=”2”>
Characters remaining:
<input readonly=”readonly” type=”text” name=”inputcount” size=”5”
maxlength=”4” value=”” class=”text”>
<br>
<script language=”JavaScript”>
document.form1.inputcount.value = (200 document.form1.interests.value.length);
Trang 15</td>
</tr>
<tr>
<td nowrap=”nowrap” class=”field” align=”middle” colspan=”2”>
<input type=”hidden” name=”submitted” value=”true” />
<input type=”submit” value=”Register” />
Figure 7-4
375
Trang 16Developing Your Web Application Visualizations
with JSP 2.0
Java Server Pages (JSPs) are generally implemented in distributed systems to aggregate content withback-end components for user visualizations When application servers first receive a request from a JSPcomponent, the JSP engine compiles that page into a servlet Additionally, when changes to a JSP occur,that same component will be recompiled into a servlet again where it will be processed by a class loader
so it can restart its life cycle in the web container
A general best practice for developing web components is to use JSPs for display generation and servletsfor processing requests The idea is to encapsulate complicated business logic in JavaBean componentswritten in Java that are entirely devoid of scriplet syntax so display scripts are not obfuscated with com-plicated logic that might make your code hard to decipher for maintenance purposes Naturally, yourJavaBean code artifacts will transfer across platforms because they are written in Java, which accommo-dates reuse in your overall development operations
The benefits of JSP technology include the following points:
❑ Code reuse across disparate platforms.Components and tag libraries can be shared in ment operations and among different tools
develop-❑ Separation of roles.Web designers can work presentation scripts and developers can workback-end data transaction activities
❑ Separation of content.Both static and dynamic content can be “template-tized,” which
inevitably facilitates coding operations
A JSP page has two distinct phases during operations: translation and execution During translation, the
web container validates the syntax of a JSP script The web container manages the class instances of aJSP during the execution phase as user requests are made for it
Figure 7-5 conceptualizes how a web page can be constructed using the Model 1 Architecture
In the GUI presentation shown in Figure 7-6, when a user attempts to add a new contact to the ContactManagement Tool, a form will be presented to the user for a picture and metadata that will be associatedwith that picture The web application uses JSP 2.0 EL features to present data, and JavaBean compo-nents to persist and manipulate contact data for retrieval and storage
Trang 17header.jsp
View #1home.jsp
View #2
View #3
377
Trang 18The following form application code utilizes Jakarta Commons Upload libraries to capture fied entries for back-end database publishing If the form is properly filled out, meaning all entries arepopulated, the application will use the FileManagerbean to upload the designated image file forupload and insert the metadata associated with that image into the picture database for future retrieval:
user-speci-<%@ page language=”java” contentType=”text/html”
import=”java.util.*,java.lang.*,java.io.*,com.model1.*,org.apache.commons
.fileupload.*” %>
<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>
<%@ taglib uri=”http://java.sun.com/jsp/jstl/functions” prefix=”fn” %>
<jsp:useBean id=”fm” class=”com.model1.FileManager” scope=”request”/>
DiskFileUpload fileUpload = new DiskFileUpload();
List items = fileUpload.parseRequest(request);
if (items.size() > 0) {String tempName = “”, tempTelephone = “”, tempComments = “”, tempFilename =
“”;
Iterator iter = items.iterator();
FileItem item;
while(iter.hasNext()) {item = (FileItem) iter.next();
if(item.isFormField()) {
if (item.getFieldName().equals(“name”)) tempName = item.getString();
if (item.getFieldName().equals(“telephone”)) tempTelephone =item.getString();
if (item.getFieldName().equals(“comments”)) tempComments =item.getString();
} else {if(item.getSize() > 0) {File fullFile = new File(item.getName());
if ( !tempName.equals(“”) && !tempTelephone.equals(“”) &&
!tempComments.equals(“”) && !tempFilename.equals(“”) ) {
fm.addMetadata(tempName, tempTelephone, tempComments);
validEntry = true;
}}elseSystem.out.println(“item.size() = 0”);
}
%>
Trang 19The form applications requirement for uploading image files that will be attached to contact metadatarequires the inclusion of the enctypetag, which will dictate how the form data should be encoded fortransmission Whenever data is broadcast across a network, an agreement needs to be made as to howthat data will be represented For file uploads, the HTMLInputtag needs to be set to fileto instructthe browser to prepare to read and transmit a file from a user’s system to a remote server Setting theENCTYPE FORMattribute to multipart/form-datatells the server that the form submission contains anuploaded file The problem with implementing this form attribute is that the getParameter(String)method of the HttpServletRequestclass returns null values when the content type is
multipart/form-data To adjust for this, the Jakarta Commons FileUpload library uses the FileItemclass to parse those form elements so the data associated with them can be collected:
<form name=”formUpload” method=”post” action=”home.jsp?selection=102”
<td nowrap=”nowrap” class=”mandatory” colspan=”2”>
Add Contact [ NOTE: All field inputs required ]
<% if (validEntry) out.println(“<font color=\”#ff0000\”>Successfulentry</font>”); %>
<td align=”middle” class=”mandatory” colspan=”2”>
<input type=”submit” name=”UploadFile” value=”Upload”>
</td>
379
Trang 20public class FileManager {
private static Logger log = Logger.getLogger(“FileManager”);
private Connection conn;
private PreparedStatement pstmt;
private String dbDriver = “”;
private String dbUrl = “”;
private String dbUser = “”;
private String dbPass = “”;
// form entriesprivate String filename;
private String name;
private String telephone;
private String comments;
public FileManager() throws SQLException {The new J2EE 5 libraries enable users to inject resources with the @Resourceannotation The ideabehind dependency injection is that each application declares what type of service object it requires andthen the container resolves the dependency between application components, instantiates serviceobjects, and finally injects service stubs into the component at runtime with Java Bean accessor methodcalls or by direct data field assignment:
/* new changes with JSP 2.1 allow users to inject resources as needed
@Resource(name=”jdbc/test”) javax.sql.DataSource testDB;
public FileManager() throws SQLException {Connection conn = testDB.getConnection();
}
*/
try {
Trang 21InitialContext ic = new InitialContext();
} }public void addMetadata(String name, String telephone, String comments) {String sqlQuery = “INSERT INTO picture (name, telephone_num, comments,ignore) VALUES (?, ?, ?, ‘N’)”;
if (conn != null) {try {
}} elseSystem.out.println(“conn is NULL”);
}// getters/setters for: filename, name, telephone, comments omitted below}
The FileManagerbean application demonstrates how Java components can be constructed with robustlibraries to facilitate form processing and data persistence activities The keys to good bean developmentare to migrate common methods with one another for easy maintenance and to provide simple interfaces
to data so users will be more likely to incorporate them into their presentation code Granted, the fileupload logic in the JSP that interfaces with the bean could easily be added to the bean component, butwere not for demonstration purposes and the need to avoid a lengthy bean component that might be difficult to comprehend
AJAX
Although this chapter was written primarily to demonstrate Model 1 Architecture concepts through simple source code implementations, you should consider a popular new web page technology calledAsynchronous JavaScript and XML (AJAX) when making design decisions for web deployments thataggregate disparate web applications in a single unified view for presentation
Of course, this would apply to many portal implementations that commonly aggregate back-end datafrom distinct data sources for user presentation The collection of data for user display typically takessome time to refresh a browser page with new content predicated on user selections from the user front-end component Caching of content would allow for quicker view presentations, but the query beingcached must be performed first in order for it to be persisted
381
Trang 22The AJAX technology was established to satisfy this problem where user needs for quicker front-endresponses and more natural (quicker) data presentations are required With AJAX, back-end queriesappear a lot less obvious in a user’s browser view because the request/response action that occurs when
a user clicks a submit button or hyperlinked item in a web page is supplanted by an HTTPXMLRequestobject that performs asynchronous data processing and marshalling between client and server applica-tions This means that a page does not need to wait for a request to come back for a page to be rendered
in a browser view and data content can be fed back to a view in a continuous, free-flowing manner
The purpose of the remaining text in this chapter is to juxtapose the request/response features strated in the web applications shown in earlier sections with new AJAX script components that behave
demon-in a different fashion than older, more established web components when processdemon-ing user requests Twodifferent AJAX library extensions, AJAXTags and DWR, are discussed and exhibited through simple webapplications so their differences become more obvious and tangible as complementary technologies toexisting Model 1 web application deployments
What Is AJAXTags? Why Use It?
The AJAXTags libraries were created primarily as an alternative technology to JavaScript for client-sideweb development Although AJAX is rooted in JavaScript, it supercedes JavaScript’s functionality whenperforming form updates in that AJAX interacts asynchronously with back-end components, whichJavaScript cannot
The example implementation in Figure 7-7 demonstrates a tabbed display that generates random lotterynumbers from a JavaBean for rendering in the individual tab displays The interaction occurs throughthe AJAXTags library in an asynchronous manner using a back-end servlet delivery mechanism
Figure 7-7
Trang 23The following code implements the AJAXTags library and associates the individual tag content valuesusing through the test.jspscripts:
<%@ page language=”java” contentType=”text/html; charset=ISO-8859-1”
pageEncoding=”ISO-8859-1”%>
<%@ taglib uri=”http://ajaxtags.org/tags/ajax” prefix=”ajax” %>
<jsp:include page=”header.jsp” flush=”true” />
<h1>Do You Feel Lucky?</h1>
<script type=”text/javascript”>
function initProgress() {Element.show(‘progressMsg’);
}function resetProgress(request) {Effect.Fade(‘progressMsg’);
}function reportError() {
$(‘errorMsg’).innerHTML = “Tab panel busted!”;
<jsp:include page=”footer.jsp” flush=”true” />
The Test.javabean component creates an ArrayListof six randomly generated numbers that can beretrieved with the getData()method:
package com.ajax;
import java.util.*;
public class Test{
private ArrayList<Integer> list = new ArrayList<Integer>();
private final int NUMBERS = 6;
public Test() {}
public String getData(){
383
Trang 24Random rand = new Random();
for (int i=0; i < NUMBERS; i++) {list.add((1 + (int)(Math.random() * 60)));
}StringBuffer sb = new StringBuffer();
for (int i=0; i < NUMBERS; i++) {sb.append(list.get(i) + “ “);
}return sb.toString();
}}
The AJAXTags open source offering satisfies several client-side needs such as form auto-completion,interactive selection box population, form field refreshment, and popup generation Users should con-sider implementing AJAXTags because of its rich example base, as well as its implementation ease, butmore importantly because of its capability to serve content from back-end data stores in a rewardingmanner
What Is DWR? Why Use It?
Anyone who has engaged in large enterprise web deployments and has experienced request-drivenlatency issues with back-end components knows how frustrating operations can be when trying to per-form simple query requests or publication tasks Often the web experience is so dissatisfying that endusers would threaten to quit their jobs rather than use that agonizing application Rather than suffering
an outflow of end users who might hit the road if forced to suffer through that experience, considerationmight be given to an alternative open source web technology called Direct Web Remoting (DWR) crafted
by a small consultancy group called Getahead
DWR functions by dynamically generating JavaScript components from Java classes to overcome bersome page refresh operations that occur with large server-side data retrieval and presentation activi-ties by incorporating JavaScript XMLHttpRequestobjects This activity prevents long delays that mightoccur while a web page is collecting back-end data and reformatting it into HTML for presentation.Because requests are sent asynchronously across the network with DWR, page components can berefreshed seamlessly with new content without the appearance of breaks that some web applicationscause inside web browsers during request operations
cum-With DWR, a back-end servlet processes user requests and marshals responses back to the browser,while client-side JavaScript components send user requests and dynamically process and render contentfor presentation in the browser view The magic that allows web content to be refreshed without havingpage refreshes in the browser occurs because JavaScript interface components are dynamically generatedfrom Java applications during operations The interfaces that are crafted with DWR libraries allow forasynchronous data communication to occur between client and server programs
The sample DWR application that follows reads a MySQL database that collects and disseminates tact information through DWR interfaces and allows users to ignore items for display through the imple-mentation of checkbox selections (see Figure 7-8) When a user checks an item for omission by clickingthe Omit Checked Items button, the request is sent to the server where a flag is set so future data view-ings omit those items Alternatively, the Renew Results button allows users to reset the ignore flagattribute in the database so that previously marked items can be viewed again
Trang 25con-Figure 7-8
The following code sample incorporates DWR library scripts so that the JSP page can communicate withthe back-end database where data is collected and aggregated as web content in the user display in aseamless fashion The engine.jsscript facilitates communication from the dynamically generatedjavascriptfunction interfaces The util.jsscript consists of helpful utility functions that are desig-nated to accommodate web page refresh activities with JavaScript data
The omitCheckedItemsfunction determines what individual items will be marked for display sion and passes those items to the getContactDatabean residing on the server back-end Once thatoperation completes, the DWR library functions will receive the data that will be rendered to the displayfrom that same bean The renewResultsfunction performs the same back-end data communicationthrough DWR interfaces, but refreshes the ignoreflagattribute for all of the items in the picturedatabase so they will be eligible for display when data is passed back to the presentation tier:
omis-<%@ page language=”java” import=”java.util.*” %>
<%@ page language=”java” import=”com.dwr.*” %>
Trang 26<script type=’text/javascript’ src=’dwr/util.js’></script>
txt=txt + check.value + “,”
} count++;
}DWRUtil.removeAllRows(“mgrbody”);
The following code outlines how DWR returns data from server-side queries The individual databaseattribute mappings will be populated with content for rendering on the user display as they are returnedfrom to the back-end bean component through the JavaScript interface to the fillTablefunction ThemgrBodyobject will be used to reference the content later in the script for display Header rows aregrouped with the THEADtag, which enables browsers to support scrolling of table bodies independently
of the table header and footer:
Trang 27var getPictureId = function(unit) { return unit.pictureId };
var getName = function(unit) { return unit.name };
var getTelephone = function(unit) { return unit.telephone };
var getComments = function(unit) { return unit.comments };
var getIgnoreThis= function(unit) { return unit.ignoreThis };
function fillTable(mgr) {DWRUtil.addRows(“mgrbody”, mgr, [ getPictureId, getName, getTelephone,getComments, getIgnoreThis ]);
387
Trang 28<span style=”text-decoration:underline”
onMouseover=”this.style[‘color’]=’red’;” onMouseout=”this.style[‘color’]=’black’;”onClick=”uncheckAll()”>Uncheck all items</span>
private static Logger logger = Logger.getLogger(“ContactMgmtToolDAO”);
private static Collection<Object> list = null;
private Connection conn = null;
private PreparedStatement pstmt = null;
public getConnectionn() {conn = null;
try {Class.forName(“org.gjt.mm.mysql.Driver”);
conn = DriverManager.getConnection(“jdbc:mysql://localhost/picture”,
“root”, “”);
} catch (Exception e) {logger.info(“[ContactMgmtToolDAO:] EXCEPTION “ + e.toString());
}return conn;
}The getContactDatamethod populates a vector object with contact data where the ignorethisattribute is not Y Once all of the appropriate data has been collected, it will be returned through theinterface specified in the dwr.xmlconfiguration file placed in the web.xmldeployment descriptor:
public Collection getContactData(String filename, String omitItems) {list = new Vector<Object>();
pstmt = null;
Trang 29conn = getConnection();
if (conn != null) {try {
if (omitItems.equals(“Y”))eraseItems(filename);
elserenewItems(filename);
String sqlQuery = “select * from PICTURE where ignorethis = ?”;pstmt = conn.prepareStatement(sqlQuery);
pstmt.setString(1, “N”);
ResultSet rslt = pstmt.executeQuery();
int count = 0;
while(rslt.next()) {ContactMgmtTool mgr = this.getContactMgmtTool(rslt, count);list.add(mgr);
count++;
}} catch (Exception e) {logger.info(“[ContactMgmtToolDAO:getContactData] EXCEPTION “ +e.toString());
} finally {try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch(Exception e) {e.printStackTrace();
}}}elselogger.info(“[ContactMgmtToolDAO:getContactData] conn is NULL”);
return list;
}The getContactMgmtToolmethod creates ContactMgmtToolobjects from the result set passed into it.The countparameter is used to set the ID of the checkbox items so the checkAlland uncheckAllJavaScript methods can retrieve them with the getElementByIdmethod:
public ContactMgmtTool getContactMgmtTool(ResultSet rs, int count) throwsSQLException
{ContactMgmtTool mgr = new ContactMgmtTool();
Trang 30The eraseItemsmethod performs a simple query to update the ignore flag for individual membersusing a SQL prepared statement invocation Once this flag has been set, the item affiliated with that flagwill not be rendered to the user view when the data is passed back to the presentation tier:
public void eraseItems(String filenames) {
if (filenames.equals(“”)) return;
pstmt = null;
try { String sqlQuery = “update picture set ignorethis = ‘Y’ where picture_id
}}The renewItemsmethod refreshes the picture database by toggling all of the items flagged as ignoreto
Nso they will displayed on the user display for inspection:
public void renewItems(String omit) {pstmt = null;
try {pstmt = null;
String sqlQuery = “update picture set ignorethis = ? where ignorethis =
}}}
The dwr.xmlfile illustrates how DWR generates interfaces to the back-end JavaBean DAO components.The ContactMgmtToolDAOclass is defined here within the <create>tag so the front-end JavaScriptcomponent can communicate with it The <convert>tag is implemented so the ContactMgmtToolPlain Old Java Object (POJO) can be transformed into JavaScript associative arrays for data marshallingoperations:
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE dwr PUBLIC “-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN”
“http://www.getahead.ltd.uk/dwr/dwr10.dtd”>
<dwr>
Trang 31<create creator=”new” javascript=”ContactMgmtToolDAO”>
<param name=”class” value=”com.dwr.ContactMgmtToolDAO”/>
Summar y
This chapter has demonstrated several different implementations to enable database transactions usingtag libraries, JNDI lookups, Resource Injection, and JavaBean components with the Contact ManagementTool while incorporating the Model 1 Architecture approach Page flows were hard-coded to accommo-date user navigations from hyperlinks with the assistance of core tag library logic operators, data waspublished and collected using JavaBean database persistence methods, and lastly, content was uploadedwith the implementation of Jakarta Commons FileUpload libraries Naturally, not all of the features ofthe JSP 2.0 and JSTL 1.1 specifications and API libraries could be discussed in this chapter alone, but thesample web applications constructed here should provide ample knowledge on how to craft J2EE webcomponents with useful capabilities for professional presentation tier needs
Truth be told, software design and modeling activities typically involve difficult decision-making tions that are made from experience and the constraints that are placed on a project by scheduling time-lines But, those decisions can be facilitated by eliminating ambiguous or murky conceptualizations inyour development operations by understanding different modeling architectures and philosophies Thekey is to embrace some of the advice elaborated in Chapter 2 concerning agile software development byexperimenting and enhancing existing web components so future design decisions can be determinedmore intelligently and expediently The examples that accompany this chapter are fairly simple but can bechallenging and should serve as important reference resources in your web page development discovery
specula-391
Trang 33Developing Web Applications Using the Model 2 Architecture
In the previous chapter, you learned about building web applications using the Model 1Architecture, which is heavily dependent on a page-centric development focus In this chapter, youreview and apply a prominent pattern in software development known as Model-View-Controller(MVC) to build web applications in a more modular and componentized manner You learn a littleabout the Model 2 Architecture, particularly a framework known as WebWork, and its use of a con-cept known as Inversion of Control You will see an example of how componentized developmentwith WebWork provides a tremendous advantage to you as a web developer, as it saves you time inhaving to rebuild the same components over and over in your application
The Problem
Imagine your office needed a centralized contact manager for referencing people that could beused for given projects You know that such functionality would be useful, but are worried abouttrying to do something too ad hoc and inflexible, leading to it being quickly thrown away
You need something quick, but flexible You need something where you can reuse a lot of nents to build your solution You need to look at a Model 2 Architecture framework
compo-What Is Model 2?
To understand Model 2, you should review the Model-View-Controller paradigm, which youexamined in depth in Chapter 3 As you saw in Chapter 3, MVC is often described in the context ofSwing, so you may be wondering, “But these are web applications, how could they have much to
Trang 34do with each other?” So, you should remember that the MVC Architecture simply refers to breakingyour system into distinct components to satisfy three concepts:
❑ The Model refers to the real-world representation of your domain For example, if you have a golf
scoring system, you would have objects to represent things like a golf hole, a score, and so on
❑ The View refers to the ways that you view the data you are managing For example, you may
have a view of every player on a given hole, or you may have a scorecard for a given playerover the whole course
❑ The Controller refers to the actual discrete actions that the system can perform For example,
“enter a score,” “generate a leaderboard,” and so on
Of course, there are wide debates about where the divisions really exist — is your model just data objectsand does your controller handle the business logic? For purposes of this book, just simplify it down tothree basic concepts: The model is “what it is”; the view is “what it looks like”; and the controller is
“what it does.”
So, how does the Model 2 Architecture actually work? Figure 8-1 demonstrates the Model 2 Architecture
in action
Figure 8-1
The Model 2 Architecture works like this:
1. The Request comes into the Controller
2. The Controller performs a given action with the provided parameters
Expertise –id : int –title : String –description : String
Phone –phoneNumber : String –phoneType : String –id : int
1
* 1
*
Trang 353. The Controller forwards control to the View in order to give the response.
4. The View refers to the domain model to build the presentation
5. The View is passed back in the Response to the user.
A critical thing that is usually missed by a lot of people who look at this diagram is the concept of
“scope.” Think of it like this: There are objects that are along for the ride, whether they are along for the duration of the request, the session, or the application.
Those are the key principles of Model 2 Architectures; next you learn why the Model 2 Architecture isgood for use in web applications
Why Use Model 2?
Now that you have a good sense of what the Model 2 Architecture is, you may be asking, “Why do Ineed this?” or “Isn’t that a lot of effort for a web page?” There are a number of significant advantages tothe Model 2 Architectures, particularly in large-scale applications Here are several of the advantages
of the Model 2 Architecture:
Flexibility Model 2 is flexible because it separates your application into components by
their relevant piece of what they do This allows you to plug in new views oractions as needed without having to rewrite everything You can even reuseyour components in other application platforms like Swing
Reuse Because Model 2 is componentized by definition, you can reuse a framework to
provide a lot of the glue that holds your application together A couple of ples of Model 2 frameworks are Apache Struts and OpenSymphony’s WebWork.Scalability Because you have separated out the components, it is easy to add more compo-
exam-nents where necessary Plus, you can cache your data compoexam-nents more easilybecause of the separation of concerns — your view doesn’t care if it is handling acached version of an object or a real version
Security By handling all actions through a central controller, you can easily configure and
manage access control to your data and actions
However, there is no perfect solution The disadvantages of using the Model 2 Architecture are trated in the following table
illus-Disadvantage Description
Learning curve You cannot use the Model 2 Architecture if you do not understand it
Further-more, if you want to reuse a framework, you must learn the particulars of thatapplication Of course, you are reading this chapter, so this should be fairly wellmitigated after you read all about WebWork
Table continued on following page
395
Trang 36Disadvantage Description
Complexity There are many things to learn about Model 2 Architecture in order to use it
effectively Learning curves are different, but compared to JSP, it can be quiteintimidating to the average web developer who has been building page-centricdatabase-driven web applications for quite a while
Programming Many web developers are used to developing their applications interactively —versus as if they were scripting their web site The concept of compiling and
scripting dependencies is simply something foreign to them, particularly if they came to
web development out of graphical design rather than programming Now, youcan still separate responsibilities among the team and allow these scripters tohandle the views of the application, which are still conventional JSP
The critical concept in deciding whether to go with Model 2 is to decide whether or not it is overkill Arule of thumb could be that if you have more than five or six pages in your web application, you really
should use Model 2 Architecture Note that this assumes that you will never have more than five or six
pages, or that you are building a throwaway application
The example application in this chapter deals directly with this issue of Model 1 versus Model 2 Toomany explanations of Model 2 find it necessary to describe a system sufficiently complex to demonstratethe utility of Model 2, while ignoring the fact that the bigger the scope, the harder it is to wrap yourmind around it This application, a contact manager, would probably be a good candidate for Model 1,
if it were not going to change or grow
That is the fundamental distinction between Model 1 and Model 2 — ”Pay me now or pay me later.”Either way you are not really saving any effort with Model 1 unless you intend not to be around later —because the project is not expected to undergo further development (as opposed to some untimelydemise)
Now that you understand the concepts, advantages, and disadvantages of the Model 2 Architecture, you will want to look at an implementation of a Model 2 Architecture This chapter shows you a simple example of building a Model 2 application using the popular web application framework calledWebWork
Developing an Application with WebWor k
Building applications with the Model 2 Architecture is not very helpful if you have to build all of thisadditional glue code that provides the framework that implements the architecture It is far better if youuse a framework like Struts to implement Model 2 In this chapter, you will see one of the more popularemerging frameworks known as WebWork, or more specifically, WebWork2 WebWork is a web applica-tion framework built upon a generic command framework that provides for modularizing code through
a concept known as Inversion of Control (IoC) Though WebWork could be used to build a Model 1 web
application, it is really geared toward being a great Model 2 framework
Trang 37What Is Inversion of Control and Why Is it Useful?
To explain Inversion of Control, you should be familiar with a couple of concepts that are widely used
by software and system architects to categorize components and services of a bigger system These gories are as follows:
cate-❑ Vertical:When a component or service is referred to as being vertical, it is focused on a businessprocess For example, a billing application would be a vertical application
❑ Horizontal:Conversely, a component or service that is horizontal provides something that isrelevant to all of the vertical services and components A security manager and database con-nection pool are examples of horizontal components
What has become increasingly painful in developing enterprise applications, that is, vertical nents, is interfacing to horizontal services and components Outside of the obvious performance benefit,how much better is it to have to do a custom, configurable lookup of a database connection pool thanjust creating the connection yourself? Furthermore, you don’t want to have to account for all the hori-zontal services in all your application components, so you end up creating another layer of indirection
compo-on top of the horizcompo-ontal service in order to provide the role for that service in your applicaticompo-on
Here is what that would look like in code:
Context initCtxt = new InitialContext();
ds = (DataSource) initCtxt.lookup(“/jdbc/DS”);
} catch (NamingException e) {e.printStackTrace();
}}/**
397
Trang 38Note in the constructor how you must go to the trouble to look up a component using the Java Namingand Directory Interface — and you tie yourself to that name This wouldn’t be such a big problem insuch a limited circumstance, but consider that this class is not the start point for your application; rather,
it is just a component of the application You may have many of these components, all looking things upfor themselves
What if you inverted the whole equation and you simply declared your need for a given horizontal vice? This is what Inversion of Control does; it allows you to develop your application components inde-pendent of how they will actually be provided You simply declare the need for a given component, andallow the framework to inject the dependency — that is, provide the needed component at runtime for you
ser-Instead, you could write it as what they call a Plain Old Java Object (POJO), which simply declares amember variable for the needed dependency and leaves the how and where of satisfying that depen-dency to the framework that runs it So, your class would look something like this:
public interface Injector {
public void setDs(DataSource ds);