Cover | Table of Contents | Colophon
http://www.denverjug.org). When we polled the group for potential interest in a given subject, the same phrase came up over and over again: "I don't want to be an expert in it, I just want to make it work."http://www.jbossatwork.com. We encourage you to download the files and build them as you follow along in the book. We want you to literally see JBoss at work, not just read about it.http://java.sun.com). Follow Sun's instructions for installing the JDK on your operating system. Next, create an environment variable called JAVA_HOME that points to the Java installation
directory. Finally, add $JAVA_HOME/bin to the system path so you can run Java from the command line.http://www.jboss.org. Since it is written in Java, the same installation
files will work on Windows, Linux, Unix, or Mac OS X. Any platform that has a JVM can run JBoss.run at a command prompt (run.bat for Windows users, run.sh for Linux/Unix/Mac users). You should see something like this in your terminal window:
rosencrantz:/Library/jboss/bin sdavis$ ./run.sh
===========================================
==============================
JBoss Bootstrap Environment
JBOSS_HOME: /Library/jboss
JAVA: /System/Library/Frameworks/JavaVM.framework/home/bin/java
JAVA_OPTS: -server -Xms128m -Xmx128m -Dprogram.name=run.sh
CLASSPATH: /Library/jboss/bin/run.jar:/System/Library/Frameworks/
JavaVM.framework/home/lib/tools.jar
===========================================
==============================
22:14:03,159 INFO [Server] Starting JBoss (MX MicroKernel)...
22:14:03,177 INFO [Server] Release ID: JBoss [Zion] 4.0.2
(build: CVSTag=JBoss_4_0_2 date=200505022023)
22:14:03,181 INFO [Server] Home Dir: /Library/jboss-4.0.2
[many lines deleted for clarity...]
22:14:55,890 INFO [Http11Protocol] Starting Coyote
HTTP/1.1 on http-0.0.0.0-8080
22:14:56,396 INFO [ChannelSocket] JK: ajp13 listening on /0.0.0.0:8009
22:14:56,519 INFO [JkMain] Jk running ID=0 time=0/240 config=null
22:14:56,530 INFO [Server] JBoss (MX MicroKernel)
[4.0.2 (build: CVSTag=JBoss_4_0_2 date=200505022023)]
Started in 53s:238ms
http://www.jbossatwork.com and download the code examples. Once you've unzipped the downloaded file, copy jaw.war from the ch01/ 01a-test directory to $JBOSS_HOME/server/default/deploy. In the JBoss console window, you should see the deployed test application.http://localhost:8080/jaw (see Figure 1-2).
http://jetty.mortbay.org/jetty/download.html to download a pre-built SAR, ready to drop in and run.getCars() method call should return only data. The data shouldn't be preformatted into HTML. If it is, your data tier knows too much about the presentation tier. The two tiers are highly coupled.
<html>
<body>
<table border="1">
<tr>
<th bgcolor="cccccc" align="left">Make</th>
<th bgcolor="cccccc" align="left">Model</th>
<th bgcolor="cccccc" align="right">Model Year</th>
</tr>
<tr>
<td align="left">Toyota</td>
<td align="left">Camry</td>
<td align="right">2005</td>
</tr>
<tr>
<td align="left">Toyota</td>
<td align="left">Corolla</td>
<td align="right">1999</td>
</tr>
<tr>
<td align="left">Ford</td>
<td align="left">Explorer</td>
<td align="right">2005</td>
</tr>
</table>
</body>
</html>
CarBean is nothing more than a class with three member variables and the associated accessors and mutators.Car.make, Car.model, and Car.modelYear mean something to us, as opposed to the use of string [0], string [1], and string [2].
package com.jbossatwork;
public class CarBean
{
private String make;
private String model;
private String modelYear;
public CarBean(String make, String model, String modelYear)
{
this.make = make;
this.model = model;
this.modelYear = modelYear;
}
public String getMake()
{
return make;
}
public void setMake(String make)
{
this.make = make;
}
public String getModel()
{
return model;
}
public void setModel(String model)
{
this.model = model;
}
public String getModelYear()
{
return modelYear;
}
public void setModelYear(String modelYear)
{
this.modelYear = modelYear;
}
}
ArrayList of CarBeans instead of a simple string array (Example 2-10). The number of lines of code hasn't really changed, but hopefully the source code is far more readable using the JavaBean. (And yes, that pesky scriptlet code is still around. Once we get our Controller in place, we'll be able to replace it with something a bit more production-worthy.)CarBeans out of thin air, it will pass the request to an EJB. The EJB will eventually get the information out of a database. But for now we completed the first step toward a fully realized J2EE application.
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"
version="1.4">
<display-name>JBossAtWorkEAR</display-name>
<module>
<web>
<web-uri>webapp.war</web-uri>
<context-root>jaw</context-root>
</web>
</module>
<module>
<java>common.jar</java>
</module>
</application>
<context-root>. Recall from the previous chapter that the context root is your web site's URL. If you deploy a simple WAR file, the name of the WAR will be used as the URL. When your WAR file is deployed inside an EAR, this element allows you to override the physical name of the WAR and use whatever URL you'd like.<security-role> is another important element in application.xml. The <security-role> element describes (what else?) the security roles used throughout a J2EE application for both web and EJB components. Defining security roles in application.xml provides a single place to set up J2EE declarative security without duplicating it in web.xml and ejb-jar.xml. The Security chapter describes <security-role> in greater detail.CarBean POJO to hold the various attributes of a car. We stored it in the WAR file because, well, you didn't have any other choice at that time. We should now reconsider the storage location for the CarBean to maximize its reuse.CarBean out of the WAR and into the Common JAR. In addition to moving directories, we're going to rename it to better describe its purpose in the application.CarBean's function is a Data Transfer Object (DTO), so when we move the bean, we'll also rename it CarDTO. The source code will remain the same, but the name will give us a better idea about the true purpose of the class.
22:37:55,659 INFO [EARDeployer] Init J2EE application:
file:/Library/jboss-4.0.1/server/default/deploy/jaw.ear
22:37:55,853 INFO [TomcatDeployer] deploy, ctxPath=/jaw,
warUrl=file:/Library/jboss-4.0.1/server/default/tmp/deploy/
tmp25111jaw-ear.ear-contents/webapp.war/
22:37:56,159 INFO [EARDeployer] Started J2EE application:
file:/Library/jboss-4.0.1/server/default/deploy/jaw-ear.ear
ArrayList. In the next chapter, the DAO will pull car data from a database that uses JDBC. In the chapter after that, it will use Hibernate (an Object/Relational Mapper) to do the same thing. By getting the DAO in place now, however, we'll be able to make these implementation changes without affecting presentation-tier code. Loose coupling and high cohesion comes to the rescue again.CarDAO provides a findAll() method that returns a List of CarDTOs. The source code in Example 3-7 can be found in the common directory in ch03b-dao.
package com.jbossatwork.dao;
import java.util.*;
import com.jbossatwork.dto.CarDTO;
public class CarDAO
{
private List carList;
public CarDAO()
{
carList = new ArrayList();
carList.add(new CarDTO("Toyota", "Camry", "2005"));
carList.add(new CarDTO("Toyota", "Corolla", "1999"));
carList.add(new CarDTO("Ford", "Explorer", "2005"));
}
public List findAll()
{
return carList;
}
}
ControllerServlet calls the newly created DAO in Example 3-8.
// perform action
if(VIEW_CAR_LIST_ACTION.equals(actionName))
{
CarDAO carDAO = new CarDAO();
request.setAttribute("carList", carDAO.findAll());
destinationPage = "/carList.jsp";
}
ControllerServlet. Example 3-9 shows what your web.xml must contain to deploy this servlet correctly.
<!-- servlet definition -->
<servlet>
<servlet-name>Controller</servlet-name>
<servlet-class>com.jbossatwork.ControllerServlet</servlet-class>
</servlet>
<!-- servlet mapping -->
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>/controller/*</url-pattern>
</servlet-mapping>
ControllerServlet source code in Example 3-10. Notice the XDoclet comments we've added.
/**
* @web.servlet
* name="Controller"
*
* @web.servlet-mapping
* url-pattern="/controller/*"
*/
public class ControllerServlet extends HttpServlet
ArrayList for long enough—let's tackle saving them in a true database.INSERTs, UPDATEs, and DELETEs are the lingua franca of any database-driven application.Drivers, make Connections, and create Statements that yield ResultSets upon execution.ResultSets, OO purists bristle at the thought of dealing with a semi-structured collection of strings and primitives. Java programmers are taught from a tender young age that JavaBeans and DTOs are the one true way to represent business objects. So to get from INSERTs, UPDATEs, and DELETEs are the lingua franca of any database-driven application.Drivers, make Connections, and create Statements that yield ResultSets upon execution.ResultSets, OO purists bristle at the thought of dealing with a semi-structured collection of strings and primitives. Java programmers are taught from a tender young age that JavaBeans and DTOs are the one true way to represent business objects. So to get from ResultSets to DTOs, we must use hand-code methods that do the transformation for us, one car.setName(resultSet.getString("name")) at a time.java.sql package. JDBC 2.0 was released with JDK 1.2. It included both the Core package and what was called the Optional Package (javax.sql). The optional package brought with it better enterprise support for database connections, including connection pools and distributed transactions. JDBC 3.0 is the latest release, included with JDK 1.4.