Saturday, December 30, 2006

Entity Management for EJB3 Stateless Session Beans

@Stateless
public class StatelessSessionBean implements LocalInterface {
@PersistenceUnit(name="PUName")
private EntityManager em;
// operations on the entities, such as creating, editing, destroying, and finding.
}

  • Creates a container-managed entity manager.
  • Entity manager is transaction-scoped (meaning persistence contexts are managed by a container-controlled JTA transaction).
  • Entity manager is stateless (which is why they can be stores in any Java EE component).
  • Transaction initiated when the session bean is first invoked, and its lifecycle managed by the container.

Friday, December 29, 2006

17 Things Linux Does Better Than Windows

In June 2007, the French parliament is moving their computing base to the Linux operating system, Firefox browser, and OpenOffice.org productivity suite. It's not clear whether the whole government will eventually move away from Windows, but this is law in France.
I've had a love-hate relationship with Linux over the years, and although I still develop/run everything on Windows, there's a lot Linux offers that I wish Windows would do better:

  1. More flavors of Linux from different vendors = more competition = better software. With Windows, you are stuck with only Microsoft. Linux flavors include Linspire, Red Hat, SuSE, Ubuntu, Mandr*, Slackware, etc.
  2. Customizability to special purpose builds. If I am installing a server, I probably need less than the bulk Windows forces you to install for the same purpose. Linux builds exist that can run off floppies; with Windows, even installs can no longer be initiated from floppies.
  3. Optional GUI for a fully functional OS means increased efficiency and allows for easier remote control administration. With Windows, the GUI is pretty much required for everything; DOS and the Recovery Console might help, but we all know how limited they are.
  4. More robust shell in Linux and the option to use multiple shells. In Windows, DOS is all you got. Their new WSH is heavily dependent on Windows itself that it's almost a program within Windows than a standalone framework.
  5. Linux is essentially free for a basic home machine. You purchase support and extra packages for server platforms, but all in all, for the same level of performance and features, you spend about 1/7 the cost of Windows on Linux. Windows desktop versions start at $200. Then there's the question of ongoing costs - maintenance, bugs, viruses, and upgrades - Linux costs less in this regard.
  6. More freedom with the software you purchase: Windows allows one copy per machine (WPA/Genuine Windows) and still essentially owns your copy of the OS. With Linux you can install any number of bases with no strings attached.
  7. Smarter installs to multihomed systems: if you ever need to install Windows and Linux operating environments, you start with Windows, then Linux. Somehow, Windows kills off bootstraps of OSes it does not recognize (read non-Microsoft), whereas Linux accommodates other OSes with customizable booters.
  8. Fewer viruses, spyware, and adware. And contrary to the myth that it's because the installed base is larger, consider the Apache web server (60% of web servers) which gets significantly fewer security problems than Microsoft's IIS. Thus, Linux is more secure. Also, some default installations of Windows allow a no-password account (with Admin rights).
  9. Certification stability. For those that have navigated the certifications world, you know how soon Windows OS certification expire. Microsoft releases a new OS every 3-5 years, making certifications on older OSes obsolete. A Linux certification goes much further.
  10. I've been irked by the option to buy support and patches from Microsoft - for Windows! What the hell is wrong with this picture? If you make software, please don't charge people for fixes to your won mistakes. Sure lost updates are free, but as a developer, I know I've hit the price wall in this regard. Linux support through forums and other user bases removes this problem (though sometimes hard to come by).
  11. Wider diversity of hardware. Windows no longer runs on MIPS and Alpha processors, for example. Linux can run on even the oldest and slowest of machines - has fewer hardware requirements. Have you heard of Linux fro iPods? Try iPodLinux ... an OS that can run on iPod power.
  12. Better clustering support - you can essentially run a supercomputer using Linux for a small fraction of the cost of using windows solutions.
  13. Linux is the original true multiuser environment. Windows was originally designed as a single-user environment, but has made strides with Terminal Services/Remote Desktop/Remote Assistance. Only the latest (Windows 2003 or later) have come close.
  14. Unlimited logical partitions in Linux, as opposed to 32 for Windows. Well, there are theoretical limits (and those imposed by hardware/software constraints), but it's good to be able to create 100 small partitions that can all be used in the OS. Windows limits you to what you can name them (A-Z) - DFS may add some capabilities.
  15. Ability to schedule (and even abort) shutdowns. I can't tell you how many times I've wished I could stop a shutdown or set it to run at a certain time (without having to create a batch file and use the Scheduler program to set it - not streamlined).
  16. Linux is modular by design, so plugins and failures are localized. Windows was originally a monolithic design, although 'modular' features are offered though DLLs and COMs, and other 'plug in' models. Still, when one area suffers, it can be felt everywhere in Windows (think Blue Screens).
  17. Linux is not constrained by the RPC model, which runs all programs as network components. It makes it easier to locate programs/services across the network, but for applications without networking features, there's no need to be 'network borne' locally. Like, there's shouldn't be a need to rely on ports/sockets when 2 applications only need to run and communicate on the same machine, networkless.
That's my two cents. In the coming year, I am brushing up again on my Linux skills (hot in the job market right now) and might even pursue a Linux certification. We shall see.

Wednesday, December 27, 2006

The Roommate Nightmare

So I'm looking for a roommate to move in next month, and I'm reminded of the perils of the roommate world. Finding a good one is hard enough, but the abundance of scams out there eats at my core. I mean, this is a person you will be living with, so caution must be exercised when selecting one.
I've lived on my own since I was 17, so for 8 years, I've lived with people I am not really related with. The longest I've roomed with an individual is 2 years. Some I've only managed 6 months before it was necessary that I should move on. To friends and family, it always seems like I am moving to a new place every few months. I tend to stay away from living with families (renting a room downstairs kind of thing) - it's expensive and there's too many restrictions on how you live your life. I tend to gravitate towards peers (single people my age) or students, or young professionals (have jobs) - same energy level is the best roommate situation.
On this particular lease, I have 2 months left on it. I can tough it out and live in a 2-bedroom/2-bath apartment alone (costly unnecessarily) or find a roommate. I've chosen the latter. In the search, I've also come across a few scams. I'm compiling my notes of how they work, and will certainly post observations here. That's the kind of stuff I love messing with, for those that know me.
Meanwhile, for the genuine types around Colorado Springs: I need a male roommate, preferably a student with his own transportation. He can move in after Jan-01-2007. The apartment complex is Chimney Ridge on the north-central end of Colorado Springs. For the price ($605/month), it is a great deal. Mine is a 2-bedroom/2-bathroom variety with all the bells and whistles. If you know of anyone that can move in, let me know.

Friday, December 22, 2006

Customizing Simple EJB 3.0 Entities and Tables

The Java Persistence API does a good job mapping entities and fields in default mode to tables in a database. But sometimes you need to specify the name and columns of a table (maybe to take advantage of an existing schema). Using annotations in your entities makes this easy to implement. As an example, let us suppose you need to represent an employee in a database:
With EJB 3.0, you begin by writing an entity for the employee. The Employee class is a basic POJO, but annotations added to it are what make it persistable as we desire.

@Entity
@Table(name="EMP")
public class Employee implements Serializable {
@Column(name="NAME")
private String name;
@Column(name="SAL")
private long salary;
@Column(name="COMM")
@Basic(fetch=FetchType.LAZY)
private String comments;
@Basic(fetch=FetchType.LAZY)
@Column(name="PIC")
@Lob
private byte[] picture;
@Column(name="HIRED")
@Temporal(value = TemporalType.DATE)
private Date dateHired;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="EMP_ID")
private Long id;
@Transient
private transient String nameString;

@Override
public int hashCode() { ... }
@Override
public boolean equals(Object object) {...}
@Override
public String toString() {...}
}

The simple class above is much of what you need to represent an entity in a database. @Entity tells the persistence provider that the data of this class shall be saved in the database. @Table specifies which table shall be used. The entity must be serializable so that RMI and reflection features of Java technology can be used.
Within the table, @Column names the column for each of the attributes that shall be persisted. You can use lazy fetching to improve performance when reading entities from databases - lazy fetching skips reading columns in regular reads until the attribute is actually accessed. So it is recommended for attributes that will not be used much - in our example, pictures and comments.
The API makes it really easy to work with large objects (BLOBs and CLOBs). When we upload a picture for an employee, it'll be a huge resource. @Lob is used to indicate that a special column be allocated in the table for this kind of data.
@Temporal is used to convert dates to and from SQL types. I would not need it if I used javax.sql.Date type to represent dates in my application.
@Id specifies that the attribute/column is the primary key in the table. @GeneratedValue indicates that the primary key should be automatically generated for us. AUTO allows the persistence provider to choose a strategy (either SEQUENCE, IDENTITY, or TABLE), although you can use them directly yourself.
@Transient or the transient qualifier for properties indicates that the attribute should not be persisted. Variables like this are used to hold results of processes that use other variables and not expected to change much - helps improve efficiency if you don't have to recalculate data every time it is requested.
As usual, you need to implement hashCode(), toString(), and equals(), overriding what Object provides. Also advisable is implementing the Comparable interface on the class for sorting algorithms.

This is a basic single-entity implementation; we know that seldom do applications have single entities like this, so in the next few posts, relationships will be summarized.

Wednesday, December 20, 2006

Be Excited About BitTorrent

If you haven't heard about it, it's the next big thing in file exchange on the internet - giving users the ability to download whole DVD-quality movies, for example, in less than an hour! We are talking serious speed and download efficiencies here. It's both scary and promising for Hollywood studios obviously: scary because it means people can exchange copyrighted material a lot faster and with little effort; promising because it'll make it easier to distribute content using internet sales channels. As usual, innovation brings with it ills and goods ...
BitTorrent is designed to distribute large amounts of data widely with little cost and bandwidth implications. Some claim over 35% of traffic on the internet these days is composed of torrents. Sharing files using this protocol is is simple as publishing a torrent file (that describes your content and where to find it) to a tracker. People can then find the torrent file and download the data directly from you, or bits/chunks of the file from anyone else that might have a copy of the same file. Downloading asynchronously like this is the big secret behind the technology - final assembly of the file is done when all the chunks have been downloaded.

The only undesirable thing about BitTorrent is how it exposes the IP addresses of participants in a torrent, perhaps all the way to the original seeder. Record labels love that vulnerability, although it is a weak argument for prosecution - a torrent can include IP addresses of machines that do not contain the content being relayed and any systems that helped in the transfer of files - which would theoretically include a huge part of the internet. If your download criscrossed 10 ISPs and a few proxies, all their information could easily be discovered from torrent traces - but it doesn't make them liable for the content itself.
I use the Azureus BitTorrent client to download torrents. The process is simple: you google for torrents of content you are interested in, a few torrent files may be found, you download the file and plug it into your client, and voula, the download begins. The best thing about these clients: no banner ads, spyware, and such nonsense - so it's safe to put on your main computer. But as a programmer, I like the fact that this client is open source - I downloaded the entire code base and can do my own build.

Monday, December 18, 2006

Now Watching: Bones - Season 1

If I hadn't seen "CSI" and "House, MD", this would be a totally GREAT show. I've watched 6 episodes so far, and there's nothing really original yet: the little romantic subplots, the rich co-worker, the deductions into causes and circumstances of crimes/ailements, the character adaptation, etc - can all be drawn from those two shows ... to a large extent. I'm still watching it because it is quite interesting, actually. Plus it's based on the real-life experiences of a real criminal anthropologist (don't remember the name), and has better - or different - twists than the other two shows offer. Though, almost each episode ends with a bar scene that delivers clues to the next episode's main subplot. Not so original. Also, impressions are created earlier on in each episode as a setup for the episode's twist (it's so obvious I can smell it ...).
Unless I have become one weird critic ...

Saturday, December 09, 2006

Part III(a): Entertain(r) to Become User-Based - Requirements

The Entertain(r) application we've been developing (see Part II) has a new set of requirements - apart from managing movies only:
(1) It needs to become user-based. This includes the ability to add, edit, delete, and find users.
(2) Users must be logged in to view pages or do anything else on the system.
(3) All pages should have a standard menu that includes links to lists of users, movies, and the home page.
(4) Have a generic error page for the application.
(5) Handle database cell overflow problems.

Fullfilling these requirements will demonstrate how to use servlet filters, call JavaBeans from JSP pages, use EJB 3.0 stateless beans, and configure a generic error page for the application using NetBeans 5.5. At the end of the exercise, a basic infrastructure will exist that we can use to further explore EJB 3.0 features.

#1: a user entity must be created, with an accompanying session bean. It'll use the persistence unit we already have. Also, a servlet that does user-oriented business logic needs to be created (adding, editing, deleting, finding).
#2: Create a servlet filter that checks all requests for authentication and redirects to the login page if not logged in.
#3: Create a servlet filter that uses a response wrapper to add the menu to the response.
#4: Configure a JSP page as the error page and update the web descriptor for the web module.
#5: Check for content length and truncate, or redirect to the error page.

An auterior goal is also to find out how long it takes to add such support to an application

Friday, December 08, 2006

Part II: Creating a Simple Persistence Layer for an EJB3 Application


Follows [Part I] ...

The Entertain(r) application stores (or persists) data in a database. For now, the only data we need to store is about movies, including the title, the MPAA rating, the DVD number in my library, the date added to the library, the genre, and a short synopsis. The movie data will be represented in a Movie class, which will be annotated to become the entity.
Tools: NetBeans 5.5, Sun Java System Application Server 9, MySQL 5.

Create the Persistence Unit
Persistence units describe the datasource to the application.
- Right-click the ejb module > New > File/Folder | Persistence > Persistence Unit > [Next]. Datasource=jdbc/entertain. [Finish]. A persistence.xml descriptor file is created.

Create the Entity
An entity is a representation of an object in the datasource. Since we plan to persist movies, it's only appropriate that we call the movie entity Movie. Entities are POJOs that are annotated to indicate that they should be persisted into the database.
- Right-click the ejb module > New > File/Folder | Persistence > Entity Class > [Next]. Class Name = Movies; Package = movie.ejb. [Finish]. An entity class is created and opened in the IDE. It already has the @Entity annotation, along with @Id/@GeneratedValue (auto-generated primary key), is serializable, overrides equals(), toString(), and hashCode() methods - all requirements for an entity class.
- Add the entity's fields:
String title;
String genre;
String rating;
String synopsis;
Date dateAdded;
int dvdNumber;
- Generate bean-style getters and setters for the fields: right-click in the source file > Refactor > Encapsulate Fields ...
- Add the @Temporal(value = TemporalType.DATE) annotation for the dateAdded field. This is so that the persistence provide can translate dates correctly to the TIMESTAMP data type used in most databases.

Create the Session Bean
The session bean provides a facade that can be used to perform CRUD operations.
- Right-click the ejb module > New > File/Folder | Persistence > Session Beans for Entity Classes > [Next]. From the available list, select 'Movie (movies.ejb)' and click [Add] then [Next], then [Finish]. A stateless session bean is created and includes methods to create, edit, destroy, find, and find all movies.
** Fix:: Change the destroy() method to ensure that we operate on a managed object:
public void destroy(Movie movie) {
Movie managed = em.merge(movie);
em.remove(managed);
}

Create the Servlet
We'll use a servlet to test the persistence layer (model, par MVC), which includes the data source, persistence unit, entity class, and session bean - so far all defined in the context of the EJB module. The servlet shall exist in the web module, however.
- Right-click the war module > New > File/Folder | Web > Servlet > [Next]. Class Name = MovieServlet; Package = movie.servlet; [Finish]. A servlet class is created an opened in the IDE.
- Inject the session bean resource: right-click in the source > Enterprise Resources > Call Enterprise Bean. Select MovieFacade, click [OK]. This create an @EJB annotated reference to the session bean.
- Enter some useful code in the processRequest() method (to which all POST and GET requests are redirected). In this application, we will enter decision logic for the CRUD operations we need to test. To add, edit, remove, and find a movie, call the movieFacade methods. [Full servlet code]
- Remember to change the servlet's URL pattern to something simpler, like /Movie
- The application should be deployable now, accessible at something like http://localhost:8080/Entertain-war/.

Results:
The servlet is nowhere near perfect (for example, it does not check data lengths before posting to database fields - defaults are 255 characters), and has a lot of hard-coded lines. But it serves the simple purpose of testing the persistence layer, now composed of the data source, persistence unit, entity class, and session bean. If you are into MVC development, that layer is the model part, and the servlet serves as both the controller and view.

Part I: Creating the Entertain(r) Project

The Entertain project will be used to create the Entertain(r) web application, which contains MyMovies. As introduced earlier, MyMovies is a simple application used to manage/catalog my growing library of movies on DVD. It is a learning project meant as a simple how-to for those just starting to program with Java EE 5 technologies (especially JDK 1.6 and EJB 3). It focuses on using the NetBeans 5.5 IDE, Sun Java System Application Server 9, and MySQL 5.

Setup the database in MySQL
- Open MySQL Administrator and click on Catalogs. Right-click the bottom left pane and choose "Create New Schema" from the popup menu. Name the schema "entertain". This will be the database to use for the Entertain application, which contains MyMovies.

Add a JDBC resource in Sun Java SAS
- Copy the MySQL Connector/J JDBC driver JAR (mysql-connector-java-5.0.4-bin.jar) into ${SJSAS}/domain/domain1/lib/ext. This ensures that driver classes are included in the application server's classpath for the domain.
- Start the application server, if it not yet started, and log in using the Admin Console.
- Select Resources > JDBC > Connection Pools. Click [New...] to create a new pool. Name=EntertainDB; Resource Type=javax.sql.ConnectionPoolDataSource; Database Vendor=mysql. Click [Next]. Datasource Classname=com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource. Down under Properties, databaseName=entertain; serverName=localhost; port=3306; user=root; password=[whatever you assigned to the DB for root]. Click [Finish].
- Back in the list of connection pools, select the EntertainDB pool link and click [Ping]. If the connection was successfully set up, you will see a "Ping Successful" message.
- Now set up the JNDI resource that will be referenced in the application: select Resources > JDBC > JDBC Resources and click [New...]. JNDI Name=jdbc/entertain; Pool Name=EntertainDB. Click [OK] to create the resource.

Create a new project in NetBeans 5.5
- File | New Project ... > Enterprise > Enterprise Application > [Next]. Name="Entertain", other defaults ok [Finish].
The enterprise project created will be used to create the EJBs and webapps that we need to implement MyMovies.

Create a user-friendly URL
Just so we don't forget to deal with it later, we need to set the web module URI for the application to /entertain so that from a web browser, it can be accessed as "http://localhost:8080/entertain" (assumes SJSAS listens on its default HTTP port 8080).
- In Netbeans, right-click the Entertain-war webapp node and select Properties from the menu. Select the Run node and set Context Path=/entertain, then click [OK].

Clean up the welcome page
A index.jsp page already exists in the web module (Entertain-war > Web Pages) that will be opened when the above URL is sent from a browser. You can edit it to better suit requirements as the home page of the application.

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Entertain(r)</title>
</head>
<body>
<h1>Welcome to Entertain</h1>
Entertain is a web-based application used to manage personal entertainment artifacts.
</body>
</html>

Deploy and Test
The application cannot be deployed at this time because Java EE 5 enterprise application require at least a Session bean or Message-Driven bean.

Wednesday, December 06, 2006

Developing a Simple EJB 3.0 Application: Introducing MyMovies

In an attempt to make life easy for myself, I've decided to develop a small web application that I'll use to manage my growing list of movies. Enter MyMovies, which will be allow adding movie information, updating, deleting, searching, and listing. In the initial release, movie information will include the title, the DVD media number where the actual movie is burned, its MPAA rating, genre, date it was added to my labrary, and a brief synopsis.
Beyond these simple details, the application is meant to demonstrate using the NetBeans 5.5 IDE to develop applications for the Sun Java System Application Server 9.0 update 1 and the MySQL 5.0 database application. All the steps will be posted here for those just getting started with EJB 3.0 and other exciting Java EE 5 technologies that I may choose to play with in this application. This is my way of brushing up and learning some of the new features in Java.
At the conclusion of this track, I should have a fully functional web application that:
(1) allows me to add movie information
(2) allows me to search and list the movies
(3) allows me to update or delete movie information
(4) uses a pure Java EE 5 solution based on EJB 3.0.
I'm turning out to be the free movie rental service for people on my block, so I figured this site might as well help me keep track of who's borrowed my movies. I could also extend it to a multiuser environment, where friends can recommend movies to each other freely or keep track of what they've watched or want to watch. Then what would be cool is to port it as a plug-in for other applications and link it to big movie databases out there somehow. I'd have learned a great deal by that time, I suppose.

Tuesday, December 05, 2006

Using MySQL5 with NetBeans5.5 and Sun Java System AS 9.0u1

I've been using NetBeans 5.5 a lot lately, and I must say I like it and have decided to stick with it. NetBeans comes bundled with the Sun Java System Application Server, another product I have come to appreciate lately. These two are are the latest additions to my arsenal of development tools, alongside Eclipse and JBoss AS. I've all but dumped JBuilder (they are moving to an Eclipse base anyway).
The SJAS comes bundled with JavaDB, and open-source Java database. It's great I suppose, but without a management console, it hasn't been easy to use. So I'm switching to MySQL. The following steps are for setting up MySQL in SJSAS, and developing applications in NetBeans that'll use it.

  1. Ensure that the NetBeans 5.5 and Sun Java System AS 9u1 setup works, as in, you've done deployments to the server from the IDE. In NetBeans, you should be able to monitor and control the server from the Runtime view. You should also be able to debug easily on the server from NetBeans.
  2. Download the MySQL database driver for JDBC (Connector/J). Extract the JAR file to domains\domain1\lib\ext. In that location, it'll be included in the application server's classpath.
  3. Download and install MySql 5.0 and install it on your machine. I set mine to run as a service (though not at start up). Most defaults worked fine.
  4. Download and install MySQL Tools (which includes an administrative console). I used this to create a schema for development use (in Microsoft's world, these would be "databases").
  5. Open the web-based SJSAS console. Go to Resources -> JDBC -> Connection Pools -> New ... Provide a name, use the connection pool datasource for resource type and select mysql for vendor. Datasource class name = com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource. Add properties - user, password, server, schema (created in step #4), and port.
  6. Go to Resources -> JDBC -> JDBC Resources -> New ... to create a JNDI resource. Its name should start with jdbc/someName. Select the connection pool created in #5. If it starts without error, #2 is confirmed and you are on your way.

Saturday, December 02, 2006

Processing Input and Output with JavaServer Pages

Previous web applications I have built always did user input and output validation within the servlets that handled the particular request (of course, using utility classes accessible to the servlets). But combining JSP and servlets can reduce the overhead of input/output validation, making work a lot easier.
Validation can be done one of two ways, depending on the need. JSTL-based validation involves embedding JSP tags in HTML and having the page handle its own validation. This may be fine for an application with a few [unrelated] pages, but problems arise when you scale to multiple pages that may need to validate the same kinds of information. The solution: use JavaBeans to validate user input. With such a solution, changes are made in the beans only when validation requirements change - pages would not need to be edited.
When would your use JSTL versus JavaBeans validation? If you are only checking that fields have been filled in with certain data or selections made in a form, JSTL is best. However, if validation involves using external resources such as databases and special formating requirements, JavaBeans are best.
To protect against cross-site scripting attacks, JSP offers a great output function <c:out> that converts quotes and such to their HTML code equivalents. For example, if output text contains the '<' character, the HTML would contain the characters "& l t ;".
JSP also introduces its own set of operators to help ease coexistance with XML. If you develop a JSP/XML solution, it can become a pain to determine which operators apply to what domain, humany speaking. So, JSP allows the use of 'and' for '&&' and 'eq' for '==', for example. Essentially, you can write a JSP page that does not use the usual operators for equality and comparison.
I like the fact that JSP pages have access to the request object just as a servlet would. You can access a parameter using the implicit param object in a JSP page; example <c:out value="${param.variable}"/> for singular parameters, or paramValues for collections.
Beyond parameters, you can also access the request object itself for information sent from a client browser using "${pageContext.request.xxxxx}", where 'xxxxx' is a variable name. Such information may include character encoding, content length, content type, local/remote addresses and ports, locales, protocols, schema, security, and request headers.
The real strength of JSP and input processing is its ability to absort all request parameters into a JavaBean in a couple of lines of code:
<jsp:useBean id="beanId" class="package.BeanClass">
<jsp:setProperty name="beanId" property="*" />
</jsp:useBean>
When the number of parameters change, you only need to change the bean's methods and add/remove control names in the JSP pages. For rhis to work, parameter names in JSP must match bean properties, by case.
For most basic form input validation, you only need to be aware of a small set of JSP contructs: <c:out>, <c:forEach>, <c:if>, <c:when>, <c:choose>, and <c:set>. These and other core JSTL contructs come standard with any servlet container that can process JSPs.

JSTL <c:set> Tag

Sets values for variables.
Taglib
: http://java.sun.com/jsp/jstl/core (Core)
Prefix: c
Attributes:
value | * = value to set.
var | String = variable holding the value. If not used, target/property MUST be used.
scope | String = scope for var e.g. page, session, request, or application.
target | JavaBean object, Map = collection or bean specified by 'property' below.
property | String = name of the target above.
Example:
<c:set var="pizzaSelected" value="true" />

JSTL <c:choose> Tag

Selection/switching mechanism.
Taglib
: http://java.sun.com/jsp/jstl/core (Core)
Prefix: c
Attributes: none. Contains statements and an optional statement.
Example:
<c:choose>
<c:when test="${param.gender eq 'f'}">
// Stuff to do when gender = f
</c:when>
<c:otherwise>
// Stuff to do when none of the above when's tests true
</c:otherwise>
</c:choose>

JSTL <c:when> Tag

Tests for when an expression is set.
Taglib
: http://java.sun.com/jsp/jstl/core (Core)
Prefix: c
Attributes:
test | String = expression that evaluates to true or false.
Example:
<c:when test="${param.gender eq 'f'}>
// Things to do when parameter gender is 'f' ...
</c:when>

JSTL <c:if> Tag

Tests whether an expression is true.
Taglib
: http://java.sun.com/jsp/jstl/core (Core)
Prefix: c
Attributes:
test | boolean = expression that evaluates to true or false.
var | String = variable holding the result.
scope | String = scope for var e.g. page, session, request, or application.
Example:
<c:if test="${empty param.name}" >
// Stuff to do if the expression is true
</c:if>

JSTL <c:forEach> Tag

Used as a for loop in JSP to process elements of a collection.
Taglib
: http://java.sun.com/jsp/jstl/core (Core)
Prefix: c
Attributes:
items | String = collection to operate on.
var| String = variable holding the current item in iteration.
varStatus| String = variable holding the LoopTagStatus object.
begin| String = first index, 0-based.
end| String = last index, 0-based.
step| String = increment value, numeric.
Example:
<c:forEach items="${headerValues}" var="h">
<c:out value="${h.key}" />
</c:forEach>

JSTL <c:out> Tag

Taglib: http://java.sun.com/jsp/jstl/core (Core)
Prefix: c
Attributes:
value | String = the value to output as HTML.
[default] | String = the value to output if value is null.
[escapeXml] | boolean = whether to convert special characters to character entity codes. Default is true.
Example:
<c:out value="${param.name}" /> // To output the value of the name parameter.