Java Plugin Examples

Java Plugin Examples

The following plugin archives are installed automatically, when double clicked in Total Commander. Each plugin has a README.TXT with additional notes and included source code in each *.jar file.

Plugin Type

Plugin Download

File Extensions

Description

Please install first!

Demo Plugins

Lister plugin

Swing Demo

*.swing

The popular JFC Applet SwingSet2

Lister plugin

SWT Demo

*.swt

The Eclipse Demo Control Example

Multimedia Plugins

Lister plugin

Audio Player

*.mp3, *.mpeg, *.flac, *.ape,
*.mac, *.ogg, *.spx

Winamp Clone in Java JLGui

Lister plugin

Video Player

*.mpg, *.mpeg, *.mov, *.avi

Java Video Player

Java Media Framework

Java Developement

Lister plugin

Java Decompiler

*.class, *.java

Uses JAD to decompile class files (supports syntax highlighting and context menu)

Fans of good old C-64

Packer plugin

D64 disk image viewer

*.d64

Java version of DIRCBM

Lister plugin

CBM 6510 Disassembler

*.prg

Disassemble CBM 6510 machine code instructions

Lister plugin

C64 SID player

*.sid, *.psid

Uses JSIDPlay of the Java emulator JAC64 to play C64 sound files

Graphics

Lister plugin

3D graphics model viewer

*.3ds

Uses Starfire Researchs Java 3D loader for the 3DS file format

Java 3D

Lister plugin

Ima

ge Viewer

*.bmp, *.ico, *.jp(e)g, *.gif, *.png

Image viewer using Java 2D

Windows Application Integration (OLE based)

Lister plugin

OLE Viewer

*.doc, *.rtf, *.xls, *.wmv, *.mpa, *.mp(e)g, *.avi, *.asf, *.wav, *.pdf

Uses Microsofts OLE interface

Internet Access

Lister plugin

HTML Browser

*.html

Embeds Microsoft Internet Explorer

File system plugin

Email reader

Check your email account, protocols pop3 and imap are supported

Networking

File system plugin

SNMP plugin

Analyse network using SNMP (Simple Network Monitor Protocol), plugin author: Ján Gregor

Plugin Developement Samples to Learn

Packer plugin

File lister

*.jlst

Creates a file list and browse its contents

Content plugin

Image Content

*.bmp, *.ico, *.jp(e)g, *.gif, *.png

Shows image properties (width, height, bit-depth) – poor performance 🙁

Lister plugin

Hello World

*.tst

Hello World: show java properties in a window

File system plugin

Local Drives

Browse your local file systems

Content plugin

Content Demo

*.prg

Shows several test columns

Java Media Framework

Java Media Framework

Introduction

The Java Media Framework (JMF) is a recent API for Java dealing with real-time multimedia presentation and effects processing. JMF handles time-based media, media which changes with respect to time. Examples of this are video from a television source, audio from a raw-audio format file and animations. The beta JMF 2.0 specification will be used for this report, as they currently reflect the features that will appear in the final version.

Stages

The JMF architecture is organized into three stages:

During the input stage, data is read from a source and passed in buffers to the processing stage. The input stage may consist of reading data from a local capture device (such as a webcam or TV capture card), a file on disk or stream from the network.

The processing stage consists of a number of codecs and effects designed to modify the data stream to one suitable for output. These codecs may perform functions such as compressing or decompressing the audio to a different format, adding a watermark of some kind, cleaning up noise or applying an effect to the stream (such as echo to the audio).

Once the processing stage has applied its transformations to the stream, it passes the information to the output stage. The output stage may take the stream and pass it to a file on disk, output it to the local video display or transmit it over the network.

For example, a JMF system may read input from a TV capture card from the local system capturing input from a VCR in the input stage. It may then pass it to the processing stage to add a watermark in the corner of each frame and finally broadcast it over the local Intranet in the output stage.

Component Architecture

JMF is built around a component architecture. The compenents are organized into a number of main categories:

  • Media handlers
  • Data sources
  • Codecs/Effects
  • Renderers
  • Mux/Demuxes

Media Handlers

MediaHandlers are registered for each type of file that JMF must be able to handle. To support new file formats, a new MediaHandler can be created.

Data Sources

A DataSource handler manages source streams from various inputs. These can be for network protocols, such as http or ftp, or for simple input from disk.

Codecs/Effects

Codecs and Effects are components that take an input stream, apply a transformation to it and output it. Codecs may have different input and output formats, while Effects are simple transformations of a single input format to an output stream of the same format.

Renderers

A renderer is similar to a Codec, but the final output is somewhere other than another stream. A VideoRenderer outputs the final data to the screen, but another kind of renderer could output to different hardware, such as a TV out card.

Mux/Demuxes

Multiplexers and Demultiplexers are used to combine multiple streams into a single stream or vice-versa, respectively. They are useful for creating and reading a package of audio and video for saving to disk as a single file, or transmitting over a network.

Presenting Data

The Java Media Framework provides a number of pre-built classes that handle the reading, processing and display of data. Using the Player, media can easily be incorporated into any graphical application (AWT or Swing). The Processor allows you to control the encoding or decoding process at a finer level than the Player, such as adding a custom codec or effect between the input and output stages.

Using the Player

The Player class is an easy way to embed multimedia in an application. It handles the setup of the file handler, video and audio decoders, and media renderers automatically. It is possibly to embed the Player in a Swing application, but care must be taken as it is a heavy-weight component (it won?t clip if another component is placed in front of it).

import java.applet.*;

import java.awt.*;

import java.net.*;

import javax.media.*;

public class PlayerApplet extends Applet {

Player player = null;

public void init() {

setLayout( new BorderLayout() );

String mediaFile = getParameter( “FILE” );

try {

URL mediaURL = new URL( getDocumentBase(), mediaFile );

player = Manager.createRealizedPlayer( mediaURL );

if (player.getVisualComponent() != null)

add(“Center”, player.getVisualComponent());

if (player.getControlPanelComponent() != null)

add(“South”, player.getControlPanelComponent());

}

catch (Exception e) {

System.err.println( “Got exception ” + e );

}

}

public void start() {

player.start();

}

public void stop() {

player.stop();

player.deallocate();

}

public void destroy() {

player.close();

}

}

In this case, we are using the static createRealizedPlayer() function of the Manager class to create the Player object. This ensures that the visual and control panel components are created before it gets added to the window by blocking until then. It is also possible to create an unrealized player and implement the ControllerEventHandler interface. The window then waits for the controllerUpdate event to fire and adds the components to the layout as they are realized:

public synchronized void controllerUpdate( ControllerEvent event ) {

if ( event instanceof RealizeCompleteEvent ) {

Component comp;

if ( (comp = player.getVisualComponent()) != null )

add ( “Center”, comp );

if ( (comp = player.getControlPanelComponent()) != null )

add ( “South”, comp );

validate();

}

}

Using a simple applet tag, a multimedia stream can easily be embedded in a webpage:

<APPLET CODE=PlayerApplet WIDTH=320 HEIGHT=300>

<PARAM NAME=FILE VALUE=”sparkle2.mpeg”>

</APPLET>

This will create an applet with an embedded MPEG video stream:

This can also be used to embed multimedia content in an HTML file, as shown below. Previously, browser-specific plugins were required.

Using the Player with Swing

The Player can be easily used in a Swing application as well. The following code creates a Swing-based TV capture program with the video output displayed in the entire window:

import javax.media.*;

import javax.swing.*;

import java.awt.*;

import java.net.*;

import java.awt.event.*;

import javax.swing.event.*;

public class JMFTest extends JFrame {

Player _player;

JMFTest() {

addWindowListener( new WindowAdapter() {

public void windowClosing( WindowEvent e ) {

_player.stop();

_player.deallocate();

_player.close();

System.exit( 0 );

}

});

setExtent( 0, 0, 320, 260 );

JPanel panel = (JPanel)getContentPane();

panel.setLayout( new BorderLayout() );

String mediaFile = “vfw://1”;

try {

MediaLocator mlr = new MediaLocator( mediaFile );

_player = Manager.createRealizedPlayer( mlr );

if (_player.getVisualComponent() != null)

panel.add(“Center”, _player.getVisualComponent());

if (_player.getControlPanelComponent() != null)

panel.add(“South”, _player.getControlPanelComponent());

}

catch (Exception e) {

System.err.println( “Got exception ” + e );

}

}

public static void main(String[] args) {

JMFTest jmfTest = new JMFTest();

jmfTest.show();

}

}

Capturing Real-time Data

Video and audio data can be captured in real-time from input sources and streamed to files on the local filesystem.

Capturing Audio

To capture audio, the specified sampling frequency, sample size and number of channels must be specified. JMF will attempt to locate any devices which will support this format and return a list of all that match.

CaptureDeviceInfo di = null;

Vector deviceList = CaptureDeviceManager.getDeviceList(

new AudioFormat( “linear”, 44100, 16, 2 ) );

if ( deviceList.size() > 0 )

di = (CaptureDeviceInfo)deviceList.firstElement();

Processor p = Manager.createRealizedProcessor(di.getLocator());

DataSource source = p.getDataOutput();

The source object returned from the Processor can then be turned into a Player object by calling Manager.createPlayer(). To capture it to an audio file instead, a DataSink can take the data instead:

DataSink sink;

MediaLocator dest = new MediaLocator(“file://output.wav”);

try {

sink = Manager.createDataSink(source, dest);

sink.open();

sink.start();

} catch (Exception e) { }

The combined source above will take input from the first matching audio device (usually a microphone) and stream it to a wave file on the local filesystem.

Capturing Video

Capturing video is identical to capturing audio. Most video sources have an accompanying audio track that must be encoded as well, so we must create a compound destination file.

Format formats[] = new Format[2];

formats[0] = new AudioFormat( “linear”, 44100, 16, 2 );

formats[1] = new VideoFormat( “cvid “); // Cinepak video compressor

Processor p;

try {

p = Manager.createRealizedProcessor( new ProcessorModel( formats, null ) );

} catch ( Exception e ) { }

DataSource source = p.getDataOutput();

MediaLocator dest = new MediaLocator( “file://output.mov” );

DataSink filewriter = null;

try {

filewriter = Manager.createDataSink( source, dest );

filewriter.open();

filewriter.start();

} catch ( Exception e ) { }

p.start();

This source will create a Quicktime-format file called “output.mov” with an audio track encoded raw and a video track encoded with the Cinepak compressor.

Conclusions

JMF is a highly flexible multimedia architecture that shows a lot of promise. In the future, hopefully Sun will work on making it more stable as well as on documenting the framework and providing more example code. The support for Video For Windows (VFW) makes it a good contender for future multimedia applications. In its current state, it is usable, but the lack of information makes it difficult to create a complex program.

Exercises

  1. Create a JMF-based teleconferencing system for two people to communicate over. Use RTP as the network communication protocol.
  2. Create a Swing-based TV watcher program. The program should allow the user to select the video device to use for capture.

Issues

  • Can JMF help propel Java into the field of multimedia display and editing?
  • Will Sun develop a Linux-native “performance pack” for JMF, even though Linux competes with Solaris?
  • What changes need to be made to the current beta version of JMF to make it more usable when it becomes a release?

References

Apache FOP- PDF RTF generation for JAVA

Apache FOP

Domain path: for examples and packages:

\domainJAVACODE LIBRARYFOP_PDF_RTF_generationpackage

Introduction

Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PS, PCL, AFP, XML (area tree representation), Print, AWT and PNG, and to a lesser extent, RTF and TXT. The primary output target is PDF.

Render Diagram

A beta release of the latest version of FOP (0.95) is now available. After a short testing period it will become the third stable release after the large redesign effort and will implement a large subset of the XSL-FO Version 1.1 W3C Recommendation.

Support for each of the standard’s objects and properties is detailed in FOP Compliance. Download options include a precompiled version, source code, and many example files to get you started. Resources include links to XSL-FO introductions and many other useful references. A checklist for Getting Help will guide you toward maximizing the usefulness of FOP.

FOP is proud to be part of Apache’s XML Graphics project.

Demonstration

Formatting Diagram

This image is a demonstration of a real two page document. The xml data on the left is formatted into the two pages on the right. The document contains static areas that appear on every page, an external graphic, a footnote on the first page, and a table that goes across both pages.

FOP uses the standard XSL-FO file format as input, lays the content out into pages, then renders it to the requested output. One great advantage of using XSL-FO as input is that XSL-FO is itself an XML file, which means that it can be conveniently created from a variety of sources. The most common method is to convert semantic XML to XSL-FO, using an XSLT transformation.

FOP Objectives

The goals of the Apache FOP project are to deliver an XSL-FO to PDF formatter that is compliant to at least the Basic conformance level described in the W3C Recommendation from 05 December 2006, and that complies with the November 2001 Portable Document Format Specification (Version 1.4) from Adobe Systems.

Conformance to the XML 1.0 Recommendation, XSLT 1.0 Recommendation and the XML Namespaces Recommendation is understood. Other relevant documents, such as the XPath and XLink Working Drafts, are referenced as necessary. The FOP Project will attempt to use the latest version of evolving specifications.

How to set JNDI in Hibernate?

How to set JNDI in Hibernate?

Configuration for Tomcat and Jboss is almost same.

I did check in both it is working.

Set the following in Hibernate.hbm and then set the datasource in jndi config file.


<?xml version=’1.0′ encoding=’utf-8′?>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>

<hibernate-configuration>
<!– a SessionFactory instance listed as /jndi/name –>
<session-factory
name=”java:hibernate/SessionFactory”>

<!– properties –>
<property name=”connection.datasource”>java:/comp/env/jdbc/MyDB</property>
<property name=”dialect”>org.hibernate.dialect.SCJASQLDialect</property>
<property name=”show_sql”>true</property>
<property name=”transaction.factory_class”>
org.hibernate.transaction.JTATransactionFactory
</property>
<property name=”jta.UserTransaction”>java:comp/UserTransaction</property>

<!– mapping files –>

<!– cache settings –>

</session-factory>

</hibernate-configuration>

server.xml configuration

Configure the JNDI DataSource in Tomcat by adding a declaration for your resource to $CATALINA_HOME/conf/server.xml.

Add this in between the </Context> tag of the examples context and the </Host> tag closing the localhost definition.

<Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" crossContext="true">
 
  <Logger className="org.apache.catalina.logger.FileLogger"
             prefix="localhost_DBTest_log." suffix=".txt"
             timestamp="true"/>
 
  <Resource name="jdbc/MyDB"
               auth="Container"
               type="javax.sql.DataSource"/>
 
  <ResourceParams name="jdbc/MyDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>
 
    <!-- Maximum number of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to 0 for no limit.
         -->
    <parameter>
      <name>maxActive</name>
      <value>100</value>
    </parameter>
 
    <!-- Maximum number of idle dB connections to retain in pool.
         Set to 0 for no limit.
         -->
    <parameter>
      <name>maxIdle</name>
      <value>30</value>
    </parameter>
 
    <!-- Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>
 
    <!-- MySQL dB username and password for dB connections  -->
    <parameter>
     <name>username</name>
     <value>javauser</value>
    </parameter>
    <parameter>
     <name>password</name>
     <value>javadude</value>
    </parameter>
 
    <!-- Class name for mm.mysql JDBC driver -->
    <parameter>
       <name>driverClassName</name>
       <value>org.gjt.mm.mysql.Driver</value>
    </parameter>
 
    <!-- The JDBC connection url for connecting to your MySQL dB.
         The autoReconnect=true argument to the url makes sure that the
         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
         connection.  mysqld by default closes idle connections after 8 hours.
         -->
    <parameter>
      <name>url</name>
      <value>jdbc:mysql://localhost:3306/javatest?autoReconnect=true</value>
    </parameter>
  </ResourceParams>
</Context>

Hibernate Dielect example

Hibernate Dielect example

<?xml version=’1.0′ encoding=’utf-8′?>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>

<hibernate-configuration>
<session-factory>
<property name=”hibernate.connection.driver_class”>

com.mysql.jdbc.Driver</property>
<property name=”hibernate.connection.url”>

jdbc:mysql://localhost/hibernatetutorial</property>
<property name=”hibernate.connection.username”>root</property>
<property name=”hibernate.connection.password”></property>
<property name=”hibernate.connection.pool_size”>10</property>
<property name=”show_sql”>true</property>
<property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>
<property name=”hibernate.hbm2ddl.auto”>update</property>
<!– Mapping files –>
<mapping resource=”contact.hbm.xml“/>
</session-factory>
</hibernate-configuration>

In the above configuration file we specified to use the “hibernatetutorial” which is running on localhost and the user of the database is root with no password. The dialect property is org.hibernate.dialect.MySQLDialect which tells the Hibernate that we are using MySQL Database. Hibernate supports many database. With the use of the Hibernate (Object/Relational Mapping and Transparent Object Persistence for Java and SQL Databases), we can use the following databases dialect type property:

  • DB2- org.hibernate.dialect.DB2Dialect
  • HypersonicSQL – org.hibernate.dialect.HSQLDialect
  • Informix – org.hibernate.dialect.InformixDialect
  • Ingres – org.hibernate.dialect.IngresDialect
  • Interbase – org.hibernate.dialect.InterbaseDialect
  • Pointbase – org.hibernate.dialect.PointbaseDialect
  • PostgreSQL – org.hibernate.dialect.PostgreSQLDialect
  • Mckoi SQL – org.hibernate.dialect.MckoiDialect
  • Microsoft SQL Server – org.hibernate.dialect.SQLServerDialect
  • MySQL – org.hibernate.dialect.MySQLDialect
  • Oracle (any version) – org.hibernate.dialect.OracleDialect
  • Oracle 9 – org.hibernate.dialect.Oracle9Dialect
  • Progress – org.hibernate.dialect.ProgressDialect
  • FrontBase – org.hibernate.dialect.FrontbaseDialect
  • SAP DB – org.hibernate.dialect.SAPDBDialect
  • ass=”klink”>Sybaseorg.hibernate.dialect.SybaseDialect
  • Sybase Anywhere – org.hibernate.dialect.SybaseAnywhereDialect

The <mapping resource=”contact.hbm.xml“/> property is the mapping for our contact table.

Writing First Persistence Class
Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table. We can configure the variables to map to the database column. Here is the code for Contact.java:

package com.hibernate;

public class Contact {
private String firstName;
private String lastName;
private String email;
private long id;

/**
* @return Email
*/
public String getEmail() {
return email;
}

/**
* @return First Name
*/
public String getFirstName() {
return firstName;
}

/**
* @return Last name
*/
public String getLastName() {
return lastName;
}

="color:white;"> /**
* @param string Sets the Email
*/
public void setEmail(String string) {
email = string;
}

/**
* @param string Sets the First Name
*/
public void setFirstName(String string) {
firstName = string;
}

/**
* @param string sets the Last Name
*/
public void setLastName(String string) {
lastName = string;
}

/**
* @return ID Returns ID
*/
public long getId() {
return id;
}

/**
* @param l Sets the ID
*/
public void setId(long l) {
id = l;
}

}

Mapping the Contact Object to the Database Contact table
The file contact.hbm.xml is used to map Contact Object to the Contact
table in the database. Here is the code for contact.hbm.xml:

<?xml version=”1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC
“-//Hibernate/Hibernate Mapping DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>

<hibernate-mapping>
<class name=”example.hibernate.Contact” table=”CONTACT”>
<id name=”id” type=”long” column=”ID” >
<generator class=”assigned”/>
</id>

<property name=”firstName”>
<column name=”FIRSTNAME” />
</property>
<property name=”lastName”>
<column name=”LASTNAME”/>
</property>
<property name=”email”>
<column name=”EMAIL”/>
</property>
</class>
</hibernate-mapping>

Setting Up MySQL Database
In the configuration file(hibernate.cfg.xml) we have specified to use hibernatetutorial database running on localhost. So, create the databse (“hibernatetutorial”) on the MySQL server running on localhost.

Developing Code to Test Hibernate example
Now we are ready to write a program to insert the data into database. We should first understand about the Hibernate’s Session. Hibernate Session is the main runtime interface between a Java application and Hibernate. First we are required to get the Hibernate Session.SessionFactory allows application to create the Hibernate Sesssion by reading the configuration from hibernate.cfg.xml file. Then the save method on session object is used to save the contact information to the database:

session.save(contact)

Here is the code of FirstExample.java

package com.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class FirstExample {
public static void main(String[] args) {
Session session = null;

try{
// This step will read hibernate.cfg.xml

and prepare hibernate for use
SessionFactory sessionFactory = new

Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
//Create new instance of Contact and set

values in it by reading them from form object
System.out.println("Inserting Record");
Contact contact = new Contact();
contact.setId(3);
contact.setFirstName("Steven");
contact.setLastName("R");
contact.setEmail("info@theunical.com");
session.save(contact);
System.out.println("Done");
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
// Actual contact insertion will happen at this step
session.flush();
session.close();

}

}
}

JavaFX as Rich Internet Application Platform

JavaFX as Rich Internet Application Platform

JavaOne wrapped up on Friday. We hosted individuals from across the globe, and from every industry: consumer electronics and gaming, to enterprise IT, space exploration, factory automation, the automotive industry, academia – like the network itself, Java delivers something for nearly everyone, everywhere.


This year’s biggest announcements centered around Java’s role in the future of rich internet applications (or RIA’s). What’s a rich internet application? It depends on your perspective – from mine, it’s any network connected application that persists in front of a user, typically outside a browser, that can operate when disconnected from the network.

On the one hand, I’d claim Java’s always been a RIA platform – before the world really wanted one. Early Java applets delivered interactivity, but at the expense of development complexity and, in the early days, performance – when a browser, and more recently Javascript, would suffice.

But browser based applications are hitting complexity and performance limits, and content owners are striving for higher levels of engagement (via high definition video, or advanced interactivity). Developers are demanding something new – the browser’s a wonderfully accessible programming model, but it’s a weak deployment model for rich/disconnected applications.

An unspoken driver of RIA is also business model evolution – many companies behind rich applications are seeking independence from browsers and search engines, whose default settings and corporate parents present a competitive threat. There’s a growing appetite for locally installed applications that build rich, direct and permanent engagement with consumers. No one wants to pay a toll to meet their own customers.

With that in mind, as we looked to reinvent the Java platform, we heard a consistent set of requirements. And not just from coders, but from sports francishes seeking to directly engage their fans, media companies wanting to bypass browser defaults, to artists and businesses and device manufacturers – everyone’s looking to uniquely engage consumers via the network. These audiences have nearly identitical requirements for a RIA platform – they want technology that:

  • Reaches every internet consumer – on desktops, mobile, and new devices, too.
  • Delivers high performance – and the ability to engage creative professsionals in the design process.
  • Leverages existing skills and enterprise infrastructure.
  • Is totally free, and open source.
  • Provides content owners with control and ownership of their own data.

At JavaOne last week, we addressed every one of those issues – here’s how:

First, RIA developers want to reach every consumer on earth, and on every device.

Why? Because the market is in front of consumers – no matter what screen they may be using. Desktop, mobile phone, personal navigation, digital book – you name it. The market’s in front of all the screens in your life, not just a PC.

That said, on PC’s alone, Java’s popularity has grown in the last few years, as measured by runtime downloads – we routinely download 40 to 50 million new Java runtimes a month, and update more than a billion every year. The adoption of the Java platform exceeds the adoption of Microsoft’s Windows itself – Sun’s Java runtime environment (JRE) is preloaded on nearly every Windows machine (from HP, Dell, Lenovo, etc.), but also runs on Apple’s Macintosh, Ubuntu, Fedora, SuSe, Solaris and OpenSolaris desktops. In addition, a JRE is present on billions – yes, billions – of wireless and mobile devices, from automobile dashboards and navigation devices, to Amazon’s Kindle (did you know Amazon’s Kindle is a Java platform?).

Which is to say, the Java platform reaches more people than any other software technology the world has ever seen.

Second, RIA developers want performance, functionality AND simplicity.

Why? Because content owners and application developers want to engage consumers – and want to engage artists and creative professionals in the workflow.

Java’s history with simplicity isn’t perfect – which is why our teams have rewritten the applet model, and focused so intently on making the new consumer Java runtime environment (download a beta version here) exceptionally fast to load within a web page, exceptionally performant for complex interactivity, and trivially accessible to consumers. We’ve also simplified Java with a scripting language, JavaFX script, that enables creative professionals to engage with coders to create immersive experiences, while embracing the creative tool chain (from interaction design to pixel manipulation) used by the worlds designers and digital artists.

And I’m really pleased we’ve solved the desktop installation problem, by making JavaFX applets separable from a web page with a simple drag and drop (click the image above to watch this demonstrated). Developers can now bypass the browser to trivially install apps on desktops – once the applet’s dropped on the desktop, content owners have a direct relationship with their consumers.

You might have also seen that we’re adding full high quality audio and video codecs to Java on every platform on which it runs – resolving another gap for RIA developers, support for time-based media (click here for a demo of high performance video).

Third, enterprises want to reuse their existing Java skills and assets in moving to RIA.

Nearly every enterprise employs programmers with Java skills – it’s still the number one internet language taught across the world, and found pervasively in global business infrastructure. As businesses move to engage their customers via RIA platforms, reusing existing skills, and connecting RIA’s to existing systems, gives the Java community a unique ability to build from what exists – rather than attempt to replace it.


This familiarity also allows businesses and developer teams to focus on engaging with consumers – rather than irritating IT with new infrastructure requirements (JavaFX developers simply link to existing enterprise infrastructure, vs. requiring new systems for RIA apps).

Fourth, RIA developers want free and open platforms.

Why free? Because developers don’t want to encumber their applications with royalty bearing dependencies, or use technologies that predefine where consumers might appear. You don’t build developer communities around closed source, you build user communities – and this is an instance where developer selection and adoption will define the broadest RIA marketplace. JavaFX will, like all of Sun’s software platforms, be made freely available as open source, and it’ll be released via the GPL (v2) license.

And lest you think free and open software is the province of those with goatees and tattoos… we’re seeing a rising tide of developing nations mandating free and open software in government and academic procurement. Why? To protect choice, and build indigenous opportunity – there’s no reason to build dependencies upon proprietary software if you can avoid it.

Lastly, lets face it, the real value in Web 2.0 is the data – not the app. And that data is YOURS.

If you’ve been watching the social media space as carefully as we have, you understand the value of instrumentation and intentionality in building a business on the web. Knowing what users are doing with your product, whether it’s a fantasy cricket league or a consumer banking application, enables more innovative business models, the delivery of higher value services, placement of more valuable ads – data allows for better decisions, and better value creation (and bluntly put, higher CPA).

But most rich internet applications are built, then deployed – into a fog. Developers who leave the confines of the browser either lose access to information about what their users are doing, or have to rely upon a technology provider that’s inserting itself into their data stream. And some of those technology providers compete with content developers.

With a project code named Project Insight, we’ll be instrumenting the Java platform to enable developers to harvest the data stream generated by their RIA content. JavaFX developers can focus on their business models – rather than enhancing someone else’s.

_______________________

With all that said, what’s the success of JavaFX worth to Sun?

By definition, it’s worth more to Sun than the adoption of someone else’s platform (known as “positive option value”) – and the proprietary infrastructure used to serve it (don’t forget, RIA’s have rich internet back-ends (RIBs?). And in the RIA world, all the options are going to be priced at free, anyways – this isn’t a contest to be won on price.

From where I sit, the platform likely to win will be the one that sets developers free – to pursue markets, opportunities and customer experiences as they define them, not as vendors define them. Now, setting developers free – that’s where we can excel. It’s in the DNA of everything we do.

For developers, learn more at JavaFX.com. And be sure to check out NetBeans – like Java itself, it’s starting to rock the free world…

See also

Creating Portlets for Web Sites With the NetBeans IDE

A portal is a web page that contains individual and customizable web applications. For example, My Yahoo is a portal page. The portal provides value-added services, such as single sign-on, customization, content aggregation, and localization.

Individual web applications that are added to the portal page are called portlets. A portlet is a Java technology web component that is based on the JSR 168 specification and JSR 286, which includes Web Service for Remote Portlets (WSRP). Portlets are managed by portlet containers that supply dynamic content. Portals employ portlets as pluggable user-interface components that provide users with desired content such as RSS feeds, mashups of services such as the current weather in a given area, or even static content such as a group of hyperlinks.

In the past, creating portlets was a complex process. Now, you can quickly and easily create and test portlets using the NetBeans IDE 6.0 and the OpenPortal Portlet Container 2.0 Beta 2. Deploying the portlets onto the server is also simple.

This article shows you how to create portlets and provide dynamic content through drag-and-drop widgets in the NetBeans IDE. The example portlet in this article uses the jMaki Tabbed View widget, pulls in RSS feeds, and uses static links from the New to Java Programming Center.

What You Need to Get Started

To create and test portlets, you need the following software installed on your computer:

For instructions on installing the OpenPortal Portlet Container 2.0 Beta 2, see the installation page. You must download and install the OpenPortal Portlet Container before you follow the next steps.

The portlet container works similarly to servlet containers. A portlet container does the following:

  • Provides the runtime environment for portlets
  • Manages the life cycle of portlets
  • Provides persistent storage for storing portlet preferences
  • Caches the portlets
  • Receives requests from the portal to execute requests on the portlet

Once you have installed the necessary software, start the NetBeans IDE. Next, install the portlet and portlet container plug-ins by following these steps:

  1. Go to Tools in the main menu.
  2. Select Plug-ins.
  3. Click on the Available Plug-ins tab.
  4. Check the boxes for Portlets, the OpenPortal Portlet Container, and jMaki Ajax Support.
  5. Click the Install button and follow the directions from there. You may need to accept a few licenses before the installation process can complete.

Lastly, add the OpenPortal Portlet Container server:

  1. Go to Tools in the main menu.
  2. Select Servers.
  3. Click on Add Server.
  4. Select OpenPortal Portlet Container 2.0 from the list.
  5. Click Next.
  6. Use Browse to set the location in which to install the GlassFish application server. You may need to search your system separately to discover where the NetBeans IDE installed the GlassFish application server.
  7. Click OK.

You are now ready to create a portlet.

Creating a Portlet Project

As you do whenever you create an application in the NetBeans IDE, go to File > New Project, and choose Web > Web Application, then click Next. For the name of this project, type New2JavaPortlet. In the Server drop-down menu, choose OpenPortal Portlet Container 2.0 Beta, then click Next. In the next screen, check the jMaki Ajax Framework box. In the lower half of the pane, you get a selection of layouts. Scroll to the bottom, and choose No CSS Style.

Lastly, at the top of the screen, check the Portlets Support box. Use the Portlet Version drop-down menu and select 2.0, then check the Create Portlet box. In Portlet Class Name, type New2JavaPortlet. Note that the project name and the portlet name must be the same. The other fields are filled in automatically. Click Finish.

Because of the way that portlets are set up within the container, you will not need the displayed index.jsp page. On the left side of the screen, under the Projects tab, you see index.jsp listed. Right-click on index.jsp and select Delete. The file you are going to work on is named New2JavaPortlet_view.jsp. You can find that file by expanding the WEB-INF directory, then the jsp directory. Double-click the file name New2JavaPortlet_view.jsp The file now opens in the workspace.


How the Java Portlet Works

Even though all you’ve done is create a portlet project, the NetBeans IDE has already written an essential class for you. From the Projects tab, expand the Source Packages. Then expand com.text, and open the file New2JavaPortlet.java by double-clicking the file name.

The New2JavaPortlet extends a GenericPortlet class, which is provided, that implements the render() method and delegates the call to more specific methods to display the portlet based on its mode. Developers can extend GenericPortlet and implement as many of the following specialized render methods as are necessary for their portlet:

  • doView() Called by render() when the portlet is in View mode. Intended to contain logic that displays the View page for the portlet.
  • doEdit() Called by render() when the portlet is in Edit mode. Intended to contain logic that displays the Edit page for the portlet.
  • doHelp() Called by render() when the portlet is in Help mode. Intended to contain logic that displays the Help page for the portlet.

Notice that the New2JavaPortlet calls these methods, locating the pages for each. In this article, you will put the content of the portlet in the View page through drag-and-drop widgets and some HTML code. But you can extend this GenericPortlet cl

ass for other portlets. You can also go back later and modify the Edit or Help page. Once you have had a good look at the New2JavaPortlet class, you can close it.

When you build and run the portlet, the browser will display the New2JavaPortlet_view.jsp. Currently, this page contains only the static text: New2JavaPortlet – VIEW MODE. Because it is a JavaServer Pages (JSP) technology page, you can add any scripts or JSP tag libraries that you wish, and treat it like any other JSP page.

Test your portlet environment now before adding more content: From the main menu, click Build and select Build Main Project. Once the build is successfully completed, go to the main menu and click Run. Select Run Main Project. This takes a little longer as the application server is started, the portlet container is started, and a browser window is opened.

Notice that the portlet project name is the same as the portlet itself. Once you see that your development and testing environments are working properly, you can add content to replace the static text on the New2JavaPortlet_view.jsp page. To see the changes that you make to your portlet, you undeploy and deploy the portlet, as explained in the next section.

Adding Dynamic and Static Content to the Portlet

Because this portlet will contain several kinds of content, organize the content for a small area on a web page by using tabbed panes. You can choose other types of layouts, of course, but for this example, use the jMaki widget named Tabbed View. On the right side of your screen, notice that you have many available widgets to drag and drop. Check to be sure that the jMaki Yahoo widgets list is expanded .

Within the workspace page, delete the static text that says New2JavaPortlet - VIEW MODE. Also, delete the surrounding HTML code for bold: <b></b>. Now drag and drop the Tabbed View widget, shown highlighted in white , from the palette onto the page, exactly where you have just deleted text. Once you have dropped the Tabbed View widget onto the page, the following code appears on the page:

<a:widget name="yahoo.tabbedview"
   value="{items:[
           {label : 'My Tab', content : 'Some Content'},
           {id : 'bar', label : 'My Tab 2', include : 'test.jsp ', lazyLoad : true },
           {label : 'My Tab 3', content : 'More Content',  selected : true}
          ]
         }" />

The action of dragging and dropping a jMaki widget onto the page causes the creation in the resources directory of all the files necessary to build that widget.

To get an idea for how this widget works, save the file. Next, right-click the project name in the Projects pane and select Undeploy and Deploy. Once it is built, run the project: Go to the main menu, click Run, and select Run Main Project. When the project runs, your changes appear in the browser window. Click on each of the tabs in the Tabbed View pane. Notice on the tab named My Tab 2 that the file test.jsp was not loaded. This is only because a test.jsp had not been created, but it does demonstrate how you call a JSP page to appear in the pane.

For the New2JavaPortlet, you are going to create new JSP pages that the widget will call. Each of these pages provides the content for each of the tabs. On the New2JavaPortlet_view.jsp page, replace the code shown earlier with the following code:

<a:widget name="yahoo.tabbedview"
   value="{items:[
           {id : 'bar', label : 'Popular & New', include : '/New2JavaPortlet/whatsnew.jsp ', selected : true },
           { label : 'Java Fundamentals', include : '/New2JavaPortlet/fundamentals.jsp ', lazyLoad : true },
           { label : 'Downloads', include : '/New2JavaPortlet/downloads.jsp ', lazyLoad : true },
          ]
         }" />

This code calls three JSP pages: whatsnew.jsp, fundamentals.jsp, and downloads.jsp.

The next step is to create those pages. In the Projects pane, right-click on Web Pages. Then select New, and lastly JSP. Notice that you are saving these pages into the Web Pages directory, not the jsp directory that the portlet container created for the New2JavaPortlet_view.jsp. Any JSP pages that you create must go into the Web Pages

Create three JSP pages in this manner, naming them whatsnew, fundamentals, and downloads. The NetBeans IDE automatically adds the .jsp extension, so don’t include that in the file name.

Next, run Undeploy and Deploy again. Then click on the Run menu, and select Run Main Project. This time, note that the tab names have changed. As you click on each tab name, you get the JSP pages that you just created because of the code you replaced. Open each of these JSP pages — downloads.jsp, fundamentals.jsp, and whatsnew.jsp — and add content as described in the following subsections.

The downloads.jsp Page

This page contains simple static content, a title, and a list of links. Do not change the first two lines of code that appear at the top of the page:

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

But replace all of the HTML code with the following:

<h3>Downloads for New Developers</h3>
 
<ul>
  <li><a href="http://java.sun.com/javase/downloads/i">Java SE (JDK)</a>
  <li><a href="http://www.netbeans.org/">NetBeans IDE</a>
  <li><a href="http://www.mysql.com">MySQL Database</a>
</ul>

The fundamentals.jsp Page

This page will provide dynamic content, pulling in an RSS feed. Again, leave the first two lines of code alone, and remove all of the HTML code. Next, from the jMaki Widgets palette on the right side of the display, drag and drop the Block List widget onto the page.

The following code should appear on your page:

<a:widget name="jmaki.blockList" value="[
{title : 'jMaki Project Home', link : 'https://ajax.dev.java.net', description : 'Where to go for the latest jMaki.' },
{title : 'jMaki Widgets Home', link : 'https://widgets.dev.java.net', description : 'The source for the latest jMaki widgets.' },
{title : 'jMaki-Charting Home', link : 'https://jmaki-charting.dev.java.net', description : 'Enables complex charts rendered on the client in any modern browser.' }
]"  />

The widget prov

ides placeholder text only. Replace everything with the following code:

<h3>Java Technology Fundamentals</h3>
 
<a:widget name="jmaki.blockList" service="/xhp?id=rss"  />

In order to populate the widget with data from an external service, such as an RSS feed, you must replace the value attribute with service="/xhp?id=rss". If any page consists of a jMaki widget, then the jMaki runtime is bundled with the application. The runtime consists of jmaki.xhp.XmlHttpProxyServlet class that maps to the /xhp URL pattern within the application context.

The identifier or ID specified in the URL, rss, is configured in a configuration file named xhp.json. This file consists of a list of default external services that the widgets in a page can access. You can specify each entry in the xhp.json file by using up to five different parameters:

  • ID: This required parameter is a unique identifier for the entry.
  • URL: This required parameter gives the location of the external service.
  • Parameters: These optional parameters specify the default values passed to the URL.
  • API key: This is an optional parameter to invoke the service with a specific key.
  • Stylesheet: This is an optional parameter to process the response.

Next, you must change the xhp.json file. Go to the Projects tab and expand the resources directory. Double-click the file xhp.json, and scroll to the bottom of that page. Search for this code in the xhp.json file:

{"id": "rss",
      "url":"http://weblogs.java.net/blog/ludo/index.rdf",
      "xslStyleSheet": "rss.xsl"
  }

The tag and the default entry tell the jMaki runtime to fetch the RSS feed from http://weblogs.java.net/blog/ludo/index.rdf, apply the rss.xsl stylesheet — which understands the multiple RSS/Atom formats — to the received response, and convert the data into a common JavaScript Object Notation (JSON) data format of the type "dataType" : "jMakiRSS". The jMaki Block List widget can convert jmakiRSS data to its specific data model.

But the intention of this article is not to pull in Ludovic Champenois’s blog. So change the URL of http://weblogs.java.net/blog/ludo/index.rdf to http://blogs.sun.com/JavaFundamentals/feed/entries/rss.

Additionally, you will pull in another feed on the whatsnew.jsp page, so change the URL in the code as shown in the following code snippet. The new URL is highlighted in red.

{"id": "rss2",
      "url":"http://blogs.sun.com/new2javaUpdates/feed/entries/rss",
      "xslStyleSheet": "rss.xsl"
   }

Notice that the ID for the second RSS feed to pull in is named rss2. Notice also that the URL pulls in the blogs from the “What’s New” section of the New to Java Programming Center. Save the xhp.json file. Because you’ve added another block of code to pull in the second feed, you must separate the two
with a comma after the closing curly bracket (}) of the first block. The following code snippet shows the added comma in red on the fourth line:

    {"id": "rss",
      "url":"http://blogs.sun.com/JavaFundamentals/feed/entries/rss",
      "xslStyleSheet": "rss.xsl"
     },
    {"id": "rss2″,
      "url":"http://blogs.sun.com/new2javaUpdates/feed/entries/rss",
      "xslStyleSheet": "rss.xsl"
     }

The whatsnew.jsp Page

Go to the whatsnew.jsp page, and delete the HTML code. Add the following static HTML code:

<h3>What's Popular</h3>
 
<ul>
  <li><a href="http://java.sun.com/docs/books/tutorial/">The Java Tutorial</a></li>
  <li><a href="http://blogs.sun.com/JavaFundamentals/">Java Technology Fundamentals</a></li>
  <li><a href="http://blogs.sun.com/CoreJavaTechTips/">Core Tech Tips</a></li>
  <li><a href="http://java.sun.com/developer/onlineTraining/tools/netbeans/">Easy Web Site Creation in the NetBeans IDE</a></li>
  <li><a href="http://java.sun.com/javaee/5/docs/tutorial/doc/">The Java EE 5 Tutorial</a></li>
</ul>
 
<h3>What's New</h3>

Next, from the jMaki Widgets palette on the right side of the display, drag and drop the Block List widget onto the page. Change the code as shown here:

<a:widget name="jmaki.blockList" service="/xhp?id=rss2"  />

Customizing the jMaki Widgets

All the files that you need for customizing any of the widgets are available in the resources directory by widget name. In this case, look under jMaki for the files for the block list. Expand the blocklist directory, and open the file called component.css.

Change the line that says height : 85px; to height : 25px; and save the file.

Next, open the component.html file, and delete the following code from it:

<br/>
@{description}<br/>

This removes the descriptions from the RSS feeds, leaving only the title as a link. You can also add content, such as a date, by adding it to this file. Now, save all the files, click Undeploy and Deploy, then run the portlet again by clicking on Run in the menu and selecting Run Main Project.

Again, click Undeploy and Deploy. Then click Run the application. You now see the pages that you

‘ve created with the content. Notice also that the block list is taking up a lot of room. You can customize jMaki widgets easily by going to the Projects tab, expanding the resources directory, expanding the jMaki directory and then blockList. Edit component.css so that the height is just 25 pixels (25px).

Click Undeploy and Deploy again. When you run the portlet.

Your portlet is now complete. Once the portlet is deployed, users can add the portlet to their portal page and have access to the information they want on their page. You can tailor portlets in many different ways to suit the needs of your web site. The NetBeans IDE provides many widgets that you can drag and drop, but you are not limited by what that palette provides. You can also create your own widgets, or use Java code to create an unlimited number of objects to get the functionality that you want.

The next step is to archive the entire project in a ZIP file and send it to the server administrator. If you are also the server administrator, read the next section.

Packaging and Deployment

The portlet specification specifies the packaging and deployment of portlets as part of standard Web Application Archive (WAR) files that may contain other web components, such as JSP pages and servlets. In addition to the web.xml deployment descriptor now found in WAR files, the portlet.xml file in the WEB-INF directory descriptor defines all portlets and portlet-related configurations. An XML schema included in the portlet specification JSR 168 defines the standard elements for portlet configuration stored in the portlet.xml file.

Each portal-server vendor must provide a tool to parse the portlet descriptor file and deploy the portlet. These tools likely exist in GUI form as well as in command-line form. Developers will be able to integrate the command-line deployment tools with the Apache Ant tool. This creates additional development environment possibilities, because most development tools provide an interface for Apache Ant.

To deploy the project onto the server, see the documentation for your portal server for complete details. Most portal servers will allow you to deploy the WAR file, which is located in your project’s dist directory after you perform a build. Depending on your portal server, this may be deployed by using the Ant command, copying the WAR to your portal autodeploy directory, or using the administrative feature of your portal server.

Summary

Now that you have created a portlet, you can create other types of portlets for the portal page for your users. Portlets can include components such as local weather, the latest news, live sports scores, maps, and RSS feeds from other sites. Portlets allow your users to customize the web page to meet their specific needs, and this keeps them coming back to your web site.

For More Information

Expression Language

Expression Language

A primary feature of JSP technology version 2.0 is its support for an expression language (EL). An expression language makes it possible to easily access application data stored in JavaBeans components. For example, the JSP expression language allows a page author to access a bean using simple syntax such as ${name} for a simple variable or ${name.foo.bar} for a nested property.

The test attribute of the following conditional tag is supplied with an EL expression that compares the number of items in the session-scoped bean named cart with 0:

<c:if test="${sessionScope.cart.numberOfItems > 0}"> 
  ...
</c:if> 

The JSP expression evaluator is responsible for handling EL expressions, which are enclosed by the ${ } characters and can include literals. Here’s an example:

<c:if test="${bean1.a < 3}" >
  ...
</c:if> 

Any value that does not begin with ${ is treated as a literal and is parsed to the expected type using the PropertyEditor for the type:

<c:if test="true" >
...
</c:if> 

Literal values that contain the ${ characters must be escaped as follows:

<mytags:example attr1="an expression is ${'${'}true}" /> 

Deactivating Expression Evaluation

Because the pattern that identifies EL expressions–${ }–was not reserved in the JSP specifications before JSP 2.0, there may be applications where such a pattern is intended to pass through verbatim. To prevent the pattern from being evaluated, you can deactivate EL evaluation.

To deactivate the evaluation of EL expressions, you specify the isELIgnored attribute of the page directive:

<%@ page isELIgnored ="true|false" %> 

The valid values of this attribute are true and false. If it is true, EL expressions are ignored when they appear in static text or tag attributes. If it is false, EL expressions are evaluated by the container.

The default value varies depending on the version of the web application deployment descriptor. The default mode for JSP pages delivered using a Servlet 2.3 or earlier descriptor is to ignore EL expressions; this provides backward compatibility. The default mode for JSP pages delivered with a Servlet 2.4 descriptor is to evaluate EL expressions; this automatically provides the default that most applications want. You can also deactivate EL expression evaluation for a group of JSP pages (see Deactivating EL Expression Evaluation).

Using Expressions

EL expressions can be used:

  • In static text
  • In any standard or custom tag attribute that can accept an expression

The value of an expression in static text is computed and inserted into the current output. If the static text appears in a tag body, note that an expression will not be evaluated if the body is declared to be tagdependent (see body-content Attribute).

There are three ways to set a tag attribute value:

  • With a single expression construct:

<some:tag value="${expr}"/>

The expression is evaluated and the result is coerced to the attribute’s expected type.

  • With one or more expressions separated or surrounded by text:

<some:tag value="some${expr}${expr}text${expr}"/>

The expressions are evaluated from left to right. Each expression is coerced to a String and then concatenated with any intervening text. The resulting String is then coerced to the attribute’s expected type.

  • With text only:

<some:tag value="sometext"/>

In this case, the attribute’s String value is coerced to the attribute’s expected type.

Expressions used to set attribute values are evaluated in the context of an expected type. If the result of the expression evaluation does not match the expected type exactly, a type conversion will be performed. For example, the expression ${1.2E4} provided as the value of an attribute of type float will result in the following conversion:

Float.valueOf("1.2E4").floatValue()  

See section JSP2.8 of the JSP 2.0 specification for the complete type conversion rules.

Variables

The web container evaluates a variable that appears in an expression by looking up its value according to the behavior of PageContext.findAttribute(String). For example, when evaluating the expression ${product}, the container will look for product in the page, request, session, and application scopes and will return its value. If product is not found, null is returned. A variable that matches one of the implicit objects described in Implicit Objects will return that implicit object instead of the variable’s value.

Properties of variables are accessed using the . operator and can be nested arbitrarily.

The JSP expression language unifies the treatment of the . and [] operators. expr-a.identifier-b is equivalent to expr-a["identifier-b"]; that is, the expression expr-b is used to construct a literal whose value is the identifier, and then the [] operator is used with that value.

To evaluate expr-a[expr-b], evaluate expr-a into value-a and evaluate expr-b into value-b. If either value-a or value-b is null, return null.

  • If value-a is a Map, return value-a.get(value-b). If !value-a.containsKey(value-b), then return null.
  • If value-a is a List or array, coerce value-b to int and re

    turn value-a.get(value-b) or Array.get(value-a, value-b), as appropriate. If the coercion couldn’t be performed, an error is returned. If the get call returns an IndexOutOfBoundsException, null is returned. If the get call returns another exception, an error is returned.

  • If value-a is a JavaBeans object, coerce value-b to String. If value-b is a readable property of value-a, then return the result of a get call. If the get method throws an exception, an error is returned.

Implicit Objects

The JSP expression language defines a set of implicit objects:

In addition, several implicit objects are available that allow easy access to the following objects:

  • param: Maps a request parameter name to a single value
  • paramValues: Maps a request parameter name to an array of values
  • header: Maps a request header name to a single value
  • headerValues: Maps a request header name to an array of values
  • cookie: Maps a cookie name to a single cookie
  • initParam: Maps a context initialization parameter name to a single value

Finally, there are objects that allow access to the various scoped variables described in Using Scope Objects.

  • pageScope: Maps page-scoped variable names to their values
  • requestScope: Maps request-scoped variable names to their values
  • sessionScope: Maps session-scoped variable names to their values
  • applicationScope: Maps application-scoped variable names to their values

When an expression references one of these objects by name, the appropriate object is returned instead of the corresponding attribute. For example, ${pageContext} returns the PageContext object, even if there is an existing pageContext attribute containing some other value.

Literals

The JSP expression language defines the following literals:

  • Boolean: true and false
  • Integer: as in Java
  • Floating point: as in Java
  • String: with single and double quotes; " is escaped as ", ‘ is escaped as ‘, and is escaped as \.
  • Null: null

Operators

In addition to the . and [] operators discussed in Variables, the JSP expression language provides the following operators:

  • Arithmetic: +, - (binary), *, / and div, % and mod, - (unary)
  • Logical: and, &&, or, ||, not, !
  • Relational: ==, eq, !=, ne, <, lt, >, gt, <=, ge, >=, le. Comparisons can be made against other values, or against boolean, string, integer, or floating point literals.
  • Empty: The empty operator is a prefix operation that can be used to determine whether a value is null or empty.
  • Conditional: A ? B : C. Evaluate B or C, depending on the result of the evaluation of A.

The precedence of operators highest to lowest, left to right is as follows:

  • [] .
  • () – Used to change the precedence of operators.
  • - (unary) not ! empty
  • * / div % mod
  • + - (binary)
  • < > <= >= lt gt le ge
  • == != eq ne
  • && and
  • || or
  • ? :

Reserved Words

The following words are reserved for the JSP expression language and should not be used as identifiers.

and   eq   gt   true   instanceof
or    ne   le   false  empty
not   lt   ge   null   div   mod 

Note that many of these words are not in the language now, but they may be in the future, so you should avoid using them.

Examples

Table 12-2 contains example EL expressions and the result of evaluating them.

Table 12-2 Example Expressions 

EL Expression

Result

${1 > (4/2)}

false

${4.0 >= 3}

true

${100.0 == 100}

true

${(10*10) ne 100}

false

${a < b}

true

${hip gt hit}

false

${4 > 3}

true

${1.2E4 + 1.4}

12001.4

${3 div 4}

0.75

${10 mod 4}

2

${empty param.Add}

True if the request parameter named Add is null or an empty string

${pageContext.request.contextPath}

The context path

${sessionScope.cart.numberOfItems}

The value of the numberOfItems property of the session-scoped attribute named cart

${param[mycom.productId]}

The value of the request parameter named mycom.productId

${header["host"]}

The host

${departments[deptName]}

The value of the entry named deptName in the departments map

${requestScope['javax.servlet.
forward.servlet_path']}

The value of the request-scoped attribute named javax.servlet.
forward.servlet_path

Functions

The JSP expression language allows you to define a function that can be invoked in an expression. Functions are defined using the same mechanisms as custom tags (See Using Custom Tags and Chapter 15).

Using Functions

Functions can appear in static text and tag attribute values.

To use a function in a JSP page, you use a taglib directive to import the tag library containing the function. Then you preface the function invocation with the prefix declared in the directive.

For example, the date example page index.jsp imports the /functions library and invokes the function equals in an expression:

<%@ taglib prefix="f" uri="/functions"%>
...
    <c:when
      test="${f:equals(selectedLocaleString,
        localeString)}" > 

Defining Functions

To define a function you program it as a public static method in a public class. The mypkg.MyLocales class in the date example defines a function that tests the equality of two Strings as follows:

package mypkg;
public class MyLocales {
 
  ...
  public static boolean equals( String l1, String l2 ) {
    return l1.equals(l2);
  }
} 

Then you map the function name as used in the EL expression to the defining class and function signature in a TLD. The following functions.tld file in the date example maps the equals function to the class containing the implementation of the function equals and the signature of the function:

<function>
  <name>equals</name>
<


span style='font-size:10pt;'>  <function-class>mypkg.MyLocales</function-class>
  <function-signature>boolean equals( java.lang.String,
    java.lang.String )</function-signature>
</function> 

A tag library can have only one function element that has any given name element.

 

JSTL Examples

JSTL Examples
Select font size:
8pt 9pt 10pt 11pt 12pt 14pt 16pt
Download the

JSTLexamples.war
archive. This archive contains the following files:

index.jsp Script with a variety of examples
bean/MyBean.java User-defined bean example
mytaglib/MyFunctions.java JSTL tag library classes
Functions.tld JSTL tag library definition
Install and run in Eclipse
Prior to starting eclipse, you need to make available two new library JAR files which are included in the apache-tomcat distribution but not available for all applications. Locate the directory:

apache-tomcat-6.0.14/webapps/jsp-examples/WEB-INF/lib/

and within it, the files:

jstl.jar standard.jar

Simply copy these two files into:

apache-tomcat-6.0.14/common/lib/

Then start up eclipse. Follow the steps in JSP Forms import the WAR file JSTLexamples.war and run the project on Tomcat.

The JSP Standard Tag Library (JSTL)
The JSTL library provides a means, through variables, expressions and tags, to avoid the interleaving of Java and tag-style code. Using this language, we can, for the most part, eliminate explicit Java code in JSP pages in favor of augmenting the XML-like tag structure. See

http://jakarta.apache.org/taglibs/
http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/
You should refer to this online documentation:

jstl tld docs
and/or download it yourself:

jstl-1_1-mr2-spec-tlddoc.zip
The standard tags are those described in the table below. We have omitted the sql tags since we don’t plan to use SQL done directly in JSP. Using one of tag groups is effected by the addition of one of the following respective tag statements below.

c: <%@taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
fn: <%@taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions” %>
fmt: <%@taglib prefix=”fmt” uri=”http://java.sun.com/jsp/jstl/fmt” %>
xml: <%@taglib prefix=”x” uri=”http://java.sun.com/jsp/jstl/xml” %>

The uri is simply an identifier of the tag set. The prefix is determinable by the user, but the prefixes seen here are standard.

TLD tags and functions c: core fmt: formatting fn: functions x: xml
c:catch
c:choose
c:forEach
c:forTokens
c:if
c:import
c:otherwise
c:out
c:param
c:redirect
c:remove
c:set
c:url
c:when
fmt:bundle
fmt:formatDate
fmt:formatNumber
fmt:message
fmt:param
fmt:parseDate
fmt:parseNumber
fmt:requestEncoding
fmt:setBundle
fmt:setLocale
fmt:setTimeZone
fmt:timeZone
fn:contains()
fn:containsIgnoreCase()
fn:endsWith()
fn:escapeXml()
fn:indexOf()
fn:join()
fn:length()
fn:replace()
fn:split()
fn:startsWith()
fn:substring()
fn:substringAfter()
fn:substringBefore()
fn:toLowerCase()
fn:toUpperCase()
fn:trim()

x:choose
x:forEach
x:if
x:otherwise
x:out
x:param
x:parse
x:set
x:transform
x:when

These and other tag systems are used in JSP in one of two forms:

<tag-prefix:type attribute1=”VALUE1″ …

or, as functions to create expressions:

tag-prefix:function(arg1,arg2,…)

As in XML, tags can be complete, using a single tag ending with “/>“, or in pairs, containing a content terminated by a matching ending tag </tag-prefix:tag-type>. Some example of the common usages of the “c” tags are these:

<c:out value=”…” escapeXml=”true”/>
<c:set var=”x” value=”…” />
<c:if test=”…” > … </c:if>
<c:forEach var=”x” items=”…” > … </c:forEach>

Expression Language (EL)
The syntax for what replaces the “…” above is specified by a Java-like language, unimaginately called Expression Language (EL). EL is part of JSP; its expressions are all surrounded by the syntax ${ }. but typically can only be used most effectively in conjunction with JSTL tags. EL is closely related to Java but has some extensions and conceptual simplifications. In particular, EL is more like other web script languages being loosely typed along with other semantic simplifications. EL expressions permit variables and most of the usual arithmetic and boolean operators. Here are some points:

The == operator for strings functions like the Java .equals operator.
an EL expression with an undefined value, which (normally represented by null in Java) is also represented by null in EL, but is equivalent to the empty string.
EL has a unary operator empty: empty(x) acts like the expression x==null but also means “x equals the empty string”.
the operators or, and are synonyms for ||, &&, respectively.
Query parameters
The value of the parameter “xx” is expressed by the EL expression param.xx. When used directly in HTML,

${param.xx}

is equivalent to the JSP expression:

<%= (request.getParameter(“xx”) != null) ? (request.getParameter(“xx”) : “” %>

Session variables are EL variables
A session variable x automatically becomes available as an EL variable, e.g. if we have:

<%
session.setAttribute( “x”, “hello” );
// or
pageContext.setAttribute( “x”, “hello” );
%>

x = ${x} <!– prints: x = hello — >

JSP beans in JSTL
The EL language provides a simplified syntax for accessing bean’s get/set accessor functions. For example, the bean we use in the examples below is this:

<jsp:useBean id=”mb” class=”bean.MyBean” />

from the class:

——————————————————————————– bean/MyBean.java

package bean;

public class MyBean {
private String count;
public String getCount() { return count; }
public void setCount(String count) { this.count = count; }
public MyBean() {
System.out.println(”MyBean intialized”);
count = “0?;
}
}
EL treats the expression ${mb.count} as the value of mb.getCount(). A typical JSTL tag statement is something like

<c:set var=”i” value=”${mb.count}” />

The c:set tag is also used to call the set member function as follows:

<c:set target=”${mb}” property=”count” value=”5″ />

is equivalent to mb.setCount(”5?). Caution: If you use both set and get property, they must be consistent. For example, suppose you have these member functions:

String getSomeProperty() { … }
void setSomeProperty(int n) { … }

Then EL will consider this a mismatch and most likely reject the setter member function if you tried to use:

<c:set target=”${mb}” property=”someProperty” value=”5″ />

We can also remove a bean from the session using the JSTL c:remove tag:

<c:remove var=”mb” />

Data structures: arrays, arrays, maps, sets
Arrays and maps permit access to their collection via indices: arrays via integer indices and maps via key indices. EL regards both of these accesses as syntactically similar using the [ ] operator. For example:

<%
Map<String,String> theMap = new HashMap<String,String>();
theMap.put(“John”, “5”); theMap.put(“Jim”, “7”);
String theArray[] = { “aaa”, “bbb”, “ccc” };

session.setAttribute( “theMap”, theMap );
session.setAttribute( “theArray”, theArray );
%>

${theMap[“Jim”]} <!– same as theMap.get(”Jim”), outputs 7 –>
${theArray[1]} <!– outputs bbb –>

The EL expressions for maps, sets and lists can all print directly. Arrays,
as in Java, don’t print directly, but must use an auxiliary function. In this case the fn:join function serves the purpose:

${fn:join(theArray,”,”)}

Iterating over data structures
In order to iterate over an array, list, map, or set, the c:forEach tag pair serves our interests. Iteration with c:forEach treats arrays, lists and sets identically. For example, this code will iteratively print the elements:

<!– L represents either an array, list or set –>
<c:forEach var=”x” items=”${L}” >
${x}
</c:forEach>

When using a map, the iteration generates Map.Entry pairs. Using the getKey and getValue functions the structure of the JSTL code to iteratively print the key/value pairs looks like this:

<!– M is a map –>
<c:forEach var=”x” items=”${M}” >
${x.key}: ${x.value}
</c:forEach>

Choice tags c:if, c:choose/c:when
The c:if tag generates a choice situation with a syntax like:

<c:if test=”${EL_BOOLEAN_EXPRESSION}” > … </c:if>

The EL_BOOLEAN_EXPRESSION uses the usual boolean operators with simplifications and additions as mentioned above. If-else structures are based on the c:choose/c:when/c:otherwise tags:

<c:choose>
<c:when test=”${EL_EXPR1}”> … </c:when>
<c:when test=”${EL_EXPR2}”> … </c:when>

<c:otherwise> … </c:otherwise>
</c:choose>

User-generated tag functions
If one wants to avoid explicit JSP sections of code then the Java classes and functions must be able to be accessed through the tag system. Beans provide a limited way of doing so through combinations of “get/set” member functions, but this is not intended for utility functions to manipulate objects. The fn tags provide some of these utility functions, but one can imagine that soon there would be need for your own specific utility functions. Towards this end, JSP provides a means to add your own tag libraries using a combination of Java classes and Tag Library Definition (TLD) files. Both XML-like tags and EL function tags can be added, but it’s much easier to create user-defined EL function tags. The utility functions used must be static functions. For example, suppose we want to use the function defined in this class in an EL expression.

——————————————————————————– mytaglib/MyFunctions.java

package mytaglib;
import java.util.*;
public class MyFunctions {
public static boolean contains(Set<String> set, String target) {
return set.contains(target);
}
}
The glue which connects this functions to JSP is the XML file MyTags.tld held stored in the /WEB-INF/ project directory.

——————————————————————————– MyTags.tld

<?xml version=”1.0? encoding=”UTF-8??>
<taglib version=”2.0? …>
<tlib-version>1.1</tlib-version>
<uri>/WEB-INF/MyTags</uri>
<function>
<name>contains</name>
<function-class>mytaglib.MyFunctions</function-class>
<function-signature>
boolean contains(java.util.Set,java.lang.String)
</function-signature>
</function>
</taglib>
This file defines a uri by which it is accessed and a set of function prototypes in XML format. Each function has a tag name, the class it belongs to and the actual function prototype within this class. The necessary specification within the JSP file is something like this:

<%@taglib prefix=”mtg” uri=”/WEB-INF/MyTags”%>

The prefix chosen specifies how the function will be referenced within the EL syntax — it can be anything you want, so long as it doesn’t conflict with another tag set. In this case the function will be prefaced by mtg: as in this example:

<c:if test=”${mtg:contains(someSet,someValue)}” > … </c:if>

Example script
——————————————————————————– index.jsp

<%@ page language=”java” contentType=”text/html;
charset=US-ASCII” pageEncoding=”US-ASCII”%>

<%@page import=”java.util.*”%>

<%@taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
<%@taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions”%>
<%@taglib prefix=”mtg” uri=”/WEB-INF/MyTags”%>

<jsp:useBean id=”mb” scope=”session” class=”bean.MyBean” />

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=US-ASCII”>
<title>Insert title here</title>
<style>
h4 { color: red; margin-bottom:0px; text-decoration: underline; }
</style>
</head>
<body>
<%
String x = “testing”;
String[] a = { “xx”, “yy”, “zz” };

Map<String, String> m = new LinkedHashMap<String, String>();
m.put(”aa”, “1?);
m.put(”bb”, “2?);
m.put(”cc”, “3?);

List<String> l = new ArrayList<String>();
l.add(”nn”);
l.add(”mm”);
l.add(”oo”);
Set<String> s = new LinkedHashSet<String>();
s.add(”aa”);
s.add(”bb”);
s.add(”cc”);
session.setAttribute(”x”, x);
session.setAttribute(”a”, a);
session.setAttribute(”m”, m);
session.setAttribute(”l”, l);
session.setAttribute(”s”, s);
%>
<h4>access values of query parameter p</h4>
<c:if test=”${param.p == null}”>param.p not defined<br /></c:if>
first value: ${param.p}<br />
all values: ${fn:join(paramValues.p,”,”)}

<h4>print objects</h4>
x: ${x}<br />
m: ${m}<br />
s: ${s}<br />
l: ${l}<br />

<h4>print array using join</h4>
a: ${fn:join(a,”,”)}
<br />

<h4>access individuals of array or map via [ ]</h4>
a[1]: ${a[1]}
<br />
m[“bb”]: ${m[“bb”]}
<br />

<h4>access individuals in c:forEach loop</h4>
a: <c:forEach var=”i” items=”${a}”>${i} </c:forEach><br />
s: <c:forEach var=”i” items=”${s}”>${i} </c:forEach><br />
l: <c:forEach var=”i” items=”${l}”>${i} </c:forEach><br />
m: <c:forEach var=”i” items=”${m}”>${i.key}=>${i.value} </c:forEach><br />

<h4>using c:set and escapeXml</h4>
<c:set var=”k” value=”<b>bold</b>” />
k: ${k}<br />
escaped(k): ${fn:escapeXml(k)}<br />
c:out escaped: <c:out value=”${k}” escapeXml=”true” />

<h4>using a bean’s get and set properties indirectly</h4>
mb.count: ${mb.count}:
<c:set target=”${mb}” property=”count” value=”${mb.count + 1}” />
<c:choose>
<c:when test=”${mb.count > 6}”>
became bigger than 6, re-initialize mb
<c:remove var=”mb” />
</c:when>
<c:when test=”${mb.count > 3}”>became bigger than 3</c:when>
<c:otherwise>no more than 3</c:otherwise>
</c:choose>

<h4>User defined tag functions</h4>
s: ${s}<br />
<c:set var=”t” value=”cc” />
s.contains(${t}): ${mtg:contains(s,t)}<br />
<c:set var=”t” value=”dd” />
s.contains(${t}): ${mtg:contains(s,t)}

</body>
</html>
Regards
R.Satish Kumar
JSTL Examples
Select font size:
8pt 9pt 10pt 11pt 12pt 14pt 16pt
Download the

JSTLexamples.war
archive. This archive contains the following files:

index.jsp Script with a variety of examples
bean/MyBean.java User-defined bean example
mytaglib/MyFunctions.java JSTL tag library classes
Functions.tld JSTL tag library definition
Install and run in Eclipse
Prior to starting eclipse, you need to make available two new library JAR files which are included in the apache-tomcat distribution but not available for all applications. Locate the directory:

apache-tomcat-6.0.14/webapps/jsp-examples/WEB-INF/lib/

and within it, the files:

jstl.jar standard.jar

Simply copy these two files into:

apache-tomcat-6.0.14/common/lib/

Then start up eclipse. Follow the steps in JSP Forms import the WAR file JSTLexamples.war and run the project on Tomcat.

The JSP Standard Tag Library (JSTL)
The JSTL library provides a means, through variables, expressions and tags, to avoid the interleaving of Java and tag-style code. Using this language, we can, for the most part, eliminate explicit Java code in JSP pages in favor of augmenting the XML-like tag structure. See

http://jakarta.apache.org/taglibs/
http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/
You should refer to this online documentation:

jstl tld docs
and/or download it yourself:

jstl-1_1-mr2-spec-tlddoc.zip
The standard tags are those described in the table below. We have omitted the sql tags since we don’t plan to use SQL done directly in JSP. Using one of tag groups is effected by the addition of one of the following respective tag statements below.

c: <%@taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
fn: <%@taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions” %>
fmt: <%@taglib prefix=”fmt” uri=”http://java.sun.com/jsp/jstl/fmt” %>
xml: <%@taglib prefix=”x” uri=”http://java.sun.com/jsp/jstl/xml” %>

The uri is simply an identifier of the tag set. The prefix is determinable by the user, but the prefixes seen here are standard.

TLD tags and functions c: core fmt: formatting fn: functions x: xml
c:catch
c:choose
c:forEach
c:forTokens
c:if
c:import
c:otherwise
c:out
c:param
c:redirect
c:remove
c:set
c:url
c:when
fmt:bundle
fmt:formatDate
fmt:formatNumber
fmt:message
fmt:param
fmt:parseDate
fmt:parseNumber
fmt:requestEncoding
fmt:setBundle
fmt:setLocale
fmt:setTimeZone
fmt:timeZone
fn:contains()
fn:containsIgnoreCase()
fn:endsWith()
fn:escapeXml()
fn:indexOf()
fn:join()
fn:length()
fn:replace()
fn:split()
fn:startsWith()
fn:substring()
fn:substringAfter()
fn:substringBefore()
fn:toLowerCase()
fn:toUpperCase()
fn:trim()

x:choose
x:forEach
x:if
x:otherwise
x:out
x:param
x:parse
x:set
x:transform
x:when

These and other tag systems are used in JSP in one of two forms:

<tag-prefix:type attribute1=”VALUE1″ …

or, as functions to create expressions:

tag-prefix:function(arg1,arg2,…)

As in XML, tags can be complete, using a single tag ending with “/>“, or in pairs, containing a content terminated by a matching ending tag </tag-prefix:tag-type>. Some example of the common usages of the “c” tags are these:

<c:out value=”…” escapeXml=”true”/>
<c:set var=”x” value=”…” />
<c:if test=”…” > … </c:if>
<c:forEach var=”x” items=”…” > … </c:forEach>

Expression Language (EL)
The syntax for what replaces the “…” above is specified by a Java-like language, unimaginately called Expression Language (EL). EL is part of JSP; its expressions are all surrounded by the syntax ${ }. but typically can only be used most effectively in conjunction with JSTL tags. EL is closely related to Java but has some extensions and conceptual simplifications. In particular, EL is more like other web script languages being loosely typed along with other semantic simplifications. EL expressions permit variables and most of the usual arithmetic and boolean operators. Here are some points:

The == operator for strings functions like the Java .equals operator.
an EL expression with an undefined value, which (normally represented by null in Java) is also represented by null in EL, but is equivalent to the empty string.
EL has a unary operator empty: empty(x) acts like the expression x==null but also means “x equals the empty string”.
the operators or, and are synonyms for ||, &&, respectively.
Query parameters
The value of the parameter “xx” is expressed by the EL expression param.xx. When used directly in HTML,

${param.xx}

is equivalent to the JSP expression:

<%= (request.getParameter(“xx”) != null) ? (request.getParameter(“xx”) : “” %>

Session variables are EL variables
A session variable x automatically becomes available as an EL variable, e.g. if we have:

<%
session.setAttribute( “x”, “hello” );
// or
pageContext.setAttribute( “x”, “hello” );
%>

x = ${x} <!– prints: x = hello — >

JSP beans in JSTL
The EL language provides a simplified syntax for accessing bean’s get/set accessor functions. For example, the bean we use in the examples below is this:

<jsp:useBean id=”mb” class=”bean.MyBean” />

from the class:

——————————————————————————– bean/MyBean.java

package bean;

public class MyBean {
private String count;
public String getCount() { return count; }
public void setCount(String count) { this.count = count; }
public MyBean() {
System.out.println(”MyBean intialized”);
count = “0?;
}
}
EL treats the expression ${mb.count} as the value of mb.getCount(). A typical JSTL tag statement is something like

<c:set var=”i” value=”${mb.count}” />

The c:set tag is also used to call the set member function as follows:

<c:set target=”${mb}” property=”count” value=”5″ />

is equivalent to mb.setCount(”5?). Caution: If you use both set and get property, they must be consistent. For example, suppose you have these member functions:

String getSomeProperty() { … }
void setSomeProperty(int n) { … }

Then EL will consider this a mismatch and most likely reject the setter member function if you tried to use:

<c:set target=”${mb}” property=”someProperty” value=”5″ />

We can also remove a bean from the session using the JSTL c:remove tag:

<c:remove var=”mb” />

Data structures: arrays, arrays, maps, sets
Arrays and maps permit access to their collection via indices: arrays via integer indices and maps via key indices. EL regards both of these accesses as syntactically similar using the [ ] operator. For example:

<%
Map<String,String> theMap = new HashMap<String,String>();
theMap.put(“John”, “5”); theMap.put(“Jim”, “7”);
String theArray[] = { “aaa”, “bbb”, “ccc” };

session.setAttribute( “theMap”, theMap );
session.setAttribute( “theArray”, theArray );
%>

${theMap[“Jim”]} <!– same as theMap.get(”Jim”), outputs 7 –>
${theArray[1]} <!– outputs bbb –>

The EL expressions for maps, sets and lists can all print directly. Arrays, as in Java, don’

t print directly, but must use an auxiliary function. In this case the fn:join function serves the purpose:

${fn:join(theArray,”,”)}

Iterating over data structures
In order to iterate over an array, list, map, or set, the c:forEach tag pair serves our interests. Iteration with c:forEach treats arrays, lists and sets identically. For example, this code will iteratively print the elements:

<!– L represents either an array, list or set –>
<c:forEach var=”x” items=”${L}” >
${x}
</c:forEach>

When using a map, the iteration generates Map.Entry pairs. Using the getKey and getValue functions the structure of the JSTL code to iteratively print the key/value pairs looks like this:

<!– M is a map –>
<c:forEach var=”x” items=”${M}” >
${x.key}: ${x.value}
</c:forEach>

Choice tags c:if, c:choose/c:when
The c:if tag generates a choice situation with a syntax like:

<c:if test=”${EL_BOOLEAN_EXPRESSION}” > … </c:if>

The EL_BOOLEAN_EXPRESSION uses the usual boolean operators with simplifications and additions as mentioned above. If-else structures are based on the c:choose/c:when/c:otherwise tags:

<c:choose>
<c:when test=”${EL_EXPR1}”> … </c:when>
<c:when test=”${EL_EXPR2}”> … </c:when>

<c:otherwise> … </c:otherwise>
</c:choose>

User-generated tag functions
If one wants to avoid explicit JSP sections of code then the Java classes and functions must be able to be accessed through the tag system. Beans provide a limited way of doing so through combinations of “get/set” member functions, but this is not intended for utility functions to manipulate objects. The fn tags provide some of these utility functions, but one can imagine that soon there would be need for your own specific utility functions. Towards this end, JSP provides a means to add your own tag libraries using a combination of Java classes and Tag Library Definition (TLD) files. Both XML-like tags and EL function tags can be added, but it’s much easier to create user-defined EL function tags. The utility functions used must be static functions. For example, suppose we want to use the function defined in this class in an EL expression.

——————————————————————————– mytaglib/MyFunctions.java

package mytaglib;
import java.util.*;
public class MyFunctions {
public static boolean contains(Set<String> set, String target) {
return set.contains(target);
}
}
The glue which connects this functions to JSP is the XML file MyTags.tld held stored in the /WEB-INF/ project directory.

——————————————————————————– MyTags.tld

<?xml version=”1.0? encoding=”UTF-8??>
<taglib version=”2.0? …>
<tlib-version>1.1</tlib-version>
<uri>/WEB-INF/MyTags</uri>
<function>
<name>contains</name>
<function-class>mytaglib.MyFunctions</function-class>
<function-signature>
boolean contains(java.util.Set,java.lang.String)
</function-signature>
</function>
</taglib>
This file defines a uri by which it is accessed and a set of function prototypes in XML format. Each function has a tag name, the class it belongs to and the actual function prototype within this class. The necessary specification within the JSP file is something like this:

<%@taglib prefix=”mtg” uri=”/WEB-INF/MyTags”%>

The prefix chosen specifies how the function will be referenced within the EL syntax — it can be anything you want, so long as it doesn’t conflict with another tag set. In this case the function will be prefaced by mtg: as in this example:

<c:if test=”${mtg:contains(someSet,someValue)}” > … </c:if>

Example script
——————————————————————————– index.jsp

<%@ page language=”java” contentType=”text/html;
charset=US-ASCII” pageEncoding=”US-ASCII”%>

<%@page import=”java.util.*”%>

<%@taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
<%@taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions”%>
<%@taglib prefix=”mtg” uri=”/WEB-INF/MyTags”%>

<jsp:useBean id=”mb” scope=”session” class=”bean.MyBean” />

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=US-ASCII”>
<title>Insert title here</title>
<style>
h4 { color: red; margin-bottom:0px; text-decoration: underline; }
</style>
</head>
<body>
<%
String x = “testing”;
String[] a = { “xx”, “yy”, “zz” };

Map<String, String> m = new LinkedHashMap<String, String>();
m.put(”aa”, “1?);
m.put(”bb”, “2?);
m.put(”cc”, “3?);

List<String> l = new ArrayList<String>();
l.add(”nn”);
l.add(”mm”);
l.add(”oo”);
Set<String> s = new LinkedHashSet<String>();
s.add(”aa”);
s.add(”bb”);
s.add(”cc”);
session.setAttribute(”x”, x);
session.setAttribute(”a”, a);
session.setAttribute(”m”, m);
session.setAttribute(”l”, l);
session.setAttribute(”s”, s);
%>
<h4>access values of query parameter p</h4>
<c:if test=”${param.p == null}”>param.p not defined<br /></c:if>
first value: ${param.p}<br />
all values: ${fn:join(paramValues.p,”,”)}

<h4>print objects</h4>
x: ${x}<br />
m: ${m}<br />
s: ${s}<br />
l: ${l}<br />

<h4>print array using join</h4>
a: ${fn:join(a,”,”)}
<br />

<h4>access individuals of array or map via [ ]</h4>
a[1]: ${a[1]}
<br />
m[“bb”]: ${m[“bb”]}
<br />

<h4>access individuals in c:forEach loop</h4>
a: <c:forEach var=”i” items=”${a}”>${i} </c:forEach><br />
s: <c:forEach var=”i” items=”${s}”>${i} </c:forEach><br />
l: <c:forEach var=”i” items=”${l}”>${i} </c:forEach><br />
m: <c:forEach var=”i” items=”${m}”>${i.key}=>${i.value} </c:forEach><br />

<h4>using c:set and escapeXml</h4>
<c:set var=”k” value=”<b>bold</b>” />
k: ${k}<br />
escaped(k): ${fn:escapeXml(k)}<br />
c:out escaped: <c:out value=”${k}” escapeXml=”true” />

<h4>using a bean’s get and set properties indirectly</h4>
mb.count: ${mb.count}:
<c:set target=”${mb}” property=”count” value=”${mb.count + 1}” />
<c:choose>
<c:when test=”${mb.count > 6}”>
became bigger than 6, re-initialize mb
<c:remove var=”mb” />
</c:when>
<c:when test=”${mb.count > 3}”>became bigger than 3</c:when>
<c:otherwise>no more than 3</c:otherwise>
</c:choose>

<h4>User defined tag functions</h4>
s: ${s}<br />
<c:set var=”t” value=”cc” />
s.contains(${t}): ${mtg:contains(s,t)}<br />
<c:set var=”t” value=”dd” />
s.contains(${t}): ${mtg:contains(s,t)}

</body>
</html>