j2ee weblogic documentation

239
Shree-Technologies 11/29/2008 Shrikant J2EE Practical Guide Bea Weblogic

Upload: api-3733850

Post on 18-Nov-2014

2.372 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: J2EE Weblogic Documentation

S h r e e - T e c h n o l o g i e s

1 1 / 2 9 / 2 0 0 8

Shrikant

J2EE

Practical Guide

Bea Weblogic

Page 2: J2EE Weblogic Documentation

2

Table of Contents

Module: Architecture ............................................................................................................................ 13

Lab exercise - WebLogic setup ..................................................................................................... 13

Installing your WebLogic server ................................................................................................... 13

Creating aliases for commonly used commands ........................................................................... 14

Deleting your WebLogic directory ............................................................................................... 15

Copying your WebLogic directory ............................................................................................... 15

Module: Architecture ........................................................................................................................ 15

Lab exercise - Familiarisation 1 - Installing Eclipse ..................................................................... 15

Installing Workshop For Weblogic ............................................................................................... 15

Creating a project .......................................................................................................................... 17

Deploying static HTML ................................................................................................................ 20

Running the HTML page .............................................................................................................. 22

Module: Architecture ........................................................................................................................ 25

Lab exercise - Familiarisation 2 .................................................................................................... 25

The environment ........................................................................................................................... 25

Familiarisation with the directory structure .................................................................................. 26

Starting your WebLogic server ..................................................................................................... 27

Getting started ............................................................................................................................... 28

Reading the configuration ............................................................................................................. 28

Relevant areas: .............................................................................................................................. 28

DOMAIN: ..................................................................................................................................... 29

Changing the configuration ........................................................................................................... 30

Module: Servlets ............................................................................................................................... 32

Lab exercise - Hello World Servlet ............................................................................................... 32

A HelloWorld servlet .................................................................................................................... 32

Using Eclipse to create a servlet ................................................................................................... 32

Packaging your servlet 1: directory structure................................................................................ 36

Page 3: J2EE Weblogic Documentation

3

Packaging your servlet 2: deployment descriptor ......................................................................... 37

Packaging your servlet 3: static HTML files ................................................................................ 39

Packaging your servlet 4: create the WAR file ............................................................................. 41

Deploying your web application ................................................................................................... 42

Testing your web application ........................................................................................................ 43

Exploring the WebLogic console .................................................................................................. 43

Reflection ...................................................................................................................................... 46

Module: Servlets ............................................................................................................................... 47

Lab exercise - Counter Servlet ...................................................................................................... 47

A Counter servlet .......................................................................................................................... 47

Copying an existing Servlet .......................................................................................................... 47

Servlets and threading ................................................................................................................... 48

Running your servlet ..................................................................................................................... 48

Module: Servlets ............................................................................................................................... 51

Lab exercise - Form parameters .................................................................................................... 51

A SettableCounter servlet ............................................................................................................. 52

Request and Response objects ...................................................................................................... 52

Reading form parameters .............................................................................................................. 53

Aside: printing all form parameters .............................................................................................. 54

Module: Servlets ............................................................................................................................... 55

Lab exercise - HTTP Sessions ...................................................................................................... 55

A SessionCounter servlet .............................................................................................................. 55

The state problem .......................................................................................................................... 55

Sessions and Java .......................................................................................................................... 56

SessionCounterServlet .................................................................................................................. 57

Aside: common usage pattern for sessions ................................................................................... 57

URL Rewriting .............................................................................................................................. 57

Module: Servlets ............................................................................................................................... 60

Page 4: J2EE Weblogic Documentation

4

Tutorial - Accessing resources (e.g. relative files) ........................................................................ 60

Some sample code ......................................................................................................................... 60

Module: Servlets ............................................................................................................................... 61

Tutorial exercise - Creating a WAR file manually ....................................................................... 61

Manually creating a servlet ........................................................................................................... 61

Packaging your servlet 1: directory structure................................................................................ 62

Packaging your servlet 2: deployment descriptor ......................................................................... 63

Packaging your servlet 3: static HTML files ................................................................................ 64

Packaging your servlet 4: final check ........................................................................................... 64

Packaging your servlet 5: create the WAR file ............................................................................. 65

Deploying your web application ................................................................................................... 65

Testing your web application ........................................................................................................ 66

Reflection ...................................................................................................................................... 66

Module: JSP ...................................................................................................................................... 67

Lab exercise - Hello World JSP .................................................................................................... 67

A HelloWorld JSP ......................................................................................................................... 67

Creating a subfolder (subdirectory) .............................................................................................. 68

Module: JSP ...................................................................................................................................... 70

Lab exercise - JSP and form parameters ....................................................................................... 70

More implicit objects in JSP ......................................................................................................... 70

Reading form parameters in JSP ................................................................................................... 70

JSP declarations, scriptlets and expressions.................................................................................. 71

The exercise - changing background colours ................................................................................ 72

Module: JSP ...................................................................................................................................... 73

Lab exercise - JSP and sessions .................................................................................................... 73

Accessing sessions in JSP ............................................................................................................. 73

Using Java class libraries in JSP ................................................................................................... 74

The exercise - storing a history of background colours ................................................................ 74

Page 5: J2EE Weblogic Documentation

5

Module: JSP ...................................................................................................................................... 76

Lab exercise - JSP and sessions .................................................................................................... 76

Accessing sessions in JSP ............................................................................................................. 76

Using Java class libraries in JSP ................................................................................................... 77

The exercise - storing a history of background colours ................................................................ 77

Module: JSP ...................................................................................................................................... 78

Lab exercise - Web authentication ................................................................................................ 78

HTTP Basic Authentication .......................................................................................................... 79

Module: JSP ...................................................................................................................................... 83

Lab exercise - Using a JavaBean .................................................................................................. 83

Why use JavaBeans? ..................................................................................................................... 84

What are JavaBeans? .................................................................................................................... 84

Creating your JavaBean ................................................................................................................ 85

Packaging your JavaBean ................................................................................................................. 87

Creating your JSP page ................................................................................................................. 88

Adding new properties .................................................................................................................. 89

Beans and sessions ........................................................................................................................ 89

Module: JSP ...................................................................................................................................... 90

Lab exercise - Using Struts ........................................................................................................... 90

Adding support for Struts .................................................................................................................. 90

Our Lab example ............................................................................................................................... 91

Struts Configuration ...................................................................................................................... 92

Struts layout .................................................................................................................................. 92

Modifying struts ............................................................................................................................ 92

More tasks ..................................................................................................................................... 94

References ......................................................................................................................................... 94

Module: JDBC .................................................................................................................................. 94

Lab exercise - Oracle Familiarisation - command line version .................................................... 94

Page 6: J2EE Weblogic Documentation

6

Setting up your Oracle account ..................................................................................................... 95

Creating an SQL command file .................................................................................................... 95

Starting SQL*Plus ........................................................................................................................ 97

Running your SQL command file ................................................................................................. 98

Running ad-hoc SQL queries and SQL*Plus commands ............................................................. 98

Quick SQL*Plus Tutorial.............................................................................................................. 98

Changing your password ............................................................................................................... 98

Disconnecting from SQL*Plus ..................................................................................................... 99

Oracle Tools .................................................................................................................................. 99

Oracle Documentation .................................................................................................................. 99

Module: JDBC .................................................................................................................................. 99

Lab exercise - Oracle Familiarisation - Workshop for Weblogic version .................................. 100

Setting up your Oracle account ................................................................................................... 100

Setting up your Workshop project .............................................................................................. 100

Creating an SQLpage file ............................................................................................................ 100

Creating a Database Connection ................................................................................................. 102

Running your SQL command file ............................................................................................... 102

Exploring your Database ............................................................................................................. 103

Disconnecting ............................................................................................................................. 104

Module: JDBC ................................................................................................................................ 105

Lab exercise - Hello World JDBC .............................................................................................. 105

A HelloWorld JDBC application ................................................................................................ 105

Running in Workshop ................................................................................................................. 106

Running from the Command Prompt .......................................................................................... 106

Notes ........................................................................................................................................... 107

Module: JDBC ................................................................................................................................ 107

Lab exercise - JDBC in a JavaBean ............................................................................................ 108

JDBC in a JavaBean .................................................................................................................... 108

Page 7: J2EE Weblogic Documentation

7

A unit test for the JDBC JavaBean ............................................................................................. 109

Module: JDBC ................................................................................................................................ 110

Lab exercise - JDBC in a JavaBean in a JSP .............................................................................. 111

Adding JSP.................................................................................................................................. 111

Improving formatting .................................................................................................................. 112

Better Solution ............................................................................................................................ 112

Module: JDBC ................................................................................................................................ 113

Lab exercise - Connection Pools and Data Sources .................................................................... 113

JDBC Connection Pools.............................................................................................................. 113

Verifying your Connection Pool and Data Source ...................................................................... 115

The exercise ................................................................................................................................ 115

Testing your new bean ................................................................................................................ 116

Module: JDBC ................................................................................................................................ 117

Tutorial - Using other databases with Weblogic 10 .................................................................... 117

Module: JDBC ................................................................................................................................ 120

Tutorial - ODBC example ........................................................................................................... 120

Creating an ODBC DSN ............................................................................................................. 121

Accessing the ODBC DSN from a Java program ....................................................................... 122

Module: JDBC ................................................................................................................................ 122

Tutorial - Oracle SQL*Plus ........................................................................................................ 122

Running SQL*Plus ..................................................................................................................... 123

Useful SQL*Plus commands ...................................................................................................... 123

Module: JDBC ................................................................................................................................ 124

Tutorial - Quick SQL Refresher .................................................................................................. 125

SQL SELECT statement ............................................................................................................. 125

SQL CREATE/DROP statements ............................................................................................... 128

SQL INSERT/DELETE statements ............................................................................................ 129

SQL UPDATE statements .......................................................................................................... 130

Page 8: J2EE Weblogic Documentation

8

Module: RMI .................................................................................................................................. 131

Lab exercise - RMI client/server application .............................................................................. 131

Overview of RMI ........................................................................................................................ 132

Development Process .................................................................................................................. 132

Creating a simple RMI application ............................................................................................. 133

Running the HelloWorld example .............................................................................................. 137

Next step ... ................................................................................................................................. 138

Module: JNDI ................................................................................................................................. 139

Lab exercise - overview .............................................................................................................. 139

About LDAP and directory structures......................................................................................... 140

Accessing an LDAP Directory from the command line ............................................................. 140

Module: JNDI ................................................................................................................................. 142

Lab exercise - LDAP programming ............................................................................................ 142

An example first .......................................................................................................................... 143

Accessing an LDAP Directory from a web application .............................................................. 143

Module: JNDI ................................................................................................................................. 144

Tutorial - Looking up Weblogic LDAP ...................................................................................... 144

Viewing internal LDAP objects .................................................................................................. 144

Setting up Weblogic LDAP for external access .......................................................................... 144

Using the Weblogic Embedded LDAP directory server ............................................................. 145

Module: EJB ................................................................................................................................... 146

Lab exercise - Stateless Session Bean - Manual technique ......................................................... 146

Overview of EJB ......................................................................................................................... 146

Development Process .................................................................................................................. 147

Creating an EJB stateless session bean ....................................................................................... 148

Running the HelloWorld EJB example ....................................................................................... 156

Next step ... ................................................................................................................................. 156

Module: EJB ................................................................................................................................... 156

Page 9: J2EE Weblogic Documentation

9

Lab exercise - Using Eclipse + Xdoclet to generate EJB ............................................................ 156

Rapid code development ............................................................................................................. 156

Using Weblogic Workshop EJBgen ........................................................................................... 157

Using Eclipse & XDoclet ............................................................................................................ 157

Step 2 - Create a new Session Bean ............................................................................................ 161

Step 3: Enhancing the Enterprise JavaBean ................................................................................ 164

Step 4: Deploy the bean .............................................................................................................. 165

Step 5: Creating the client: .......................................................................................................... 165

Step 6: Running the client ........................................................................................................... 167

Problems you may encounter ...................................................................................................... 167

Next step ... ................................................................................................................................. 167

Module: EJB ................................................................................................................................... 168

Lab exercise - CMP Entity Bean- manually ............................................................................... 168

Overview of Entity Beans ........................................................................................................... 168

Development Process .................................................................................................................. 169

Creating an EJB CMP Entity bean .............................................................................................. 169

Module: EJB ................................................................................................................................... 175

Lab exercise - CMP Entity Bean-using Eclipse + XDoclet ........................................................ 176

Entity Beans using XDoclet ........................................................................................................ 176

Development Process .................................................................................................................. 176

Creating an EJB CMP Entity bean .............................................................................................. 176

Creating a custom ejbCreate() method. ....................................................................................... 179

Deploying it ................................................................................................................................ 181

Client code. ................................................................................................................................. 181

More things to do ........................................................................................................................ 183

Facade patterns................................................................................................................................ 183

What if the EJB's are in seperate projects? ................................................................................. 184

Module: EJB ................................................................................................................................... 184

Page 10: J2EE Weblogic Documentation

10

Creating EAR files for deployment ............................................................................................ 184

Directory structure ...................................................................................................................... 185

application.xml deployment descriptor ....................................................................................... 185

Notes about EAR files (and why they are good) ......................................................................... 186

Referencing EJBs that your components use .............................................................................. 186

Steps in deploying a Java application with many parts ............................................................... 189

Using Eclipse to generate EAR files ............................................................................................... 189

An example EAR file .................................................................................................................. 190

Module: XML ................................................................................................................................. 191

Lab exercise - Parsing XML in a JSP ......................................................................................... 191

XML ............................................................................................................................................ 191

Parsing an XML file with SAX ................................................................................................... 191

Module: XML (DOM) .................................................................................................................... 196

Lab exercise - Writing XML via DOM ...................................................................................... 196

Understanding the code ............................................................................................................... 196

Adding indenting to show nesting level ...................................................................................... 200

Formatting the data in a table ...................................................................................................... 201

Printing a subset of the data ........................................................................................................ 201

Module: XML ................................................................................................................................. 202

Lab exercise - Transforming XML in a JSP ............................................................................... 202

Creating an XSLT sample file .................................................................................................... 202

Using a web browser to do transformations ................................................................................ 204

Using Java to do transformations ................................................................................................ 204

More exercises: XSLT functions ................................................................................................ 205

Advanced exercises: .................................................................................................................... 205

Printing a subset of the data ........................................................................................................ 206

Formatting the data in a table ...................................................................................................... 206

Module: Web Services .................................................................................................................... 206

Page 11: J2EE Weblogic Documentation

11

Lab exercise 1 - Exploring RPC Web Services .......................................................................... 206

Finding Web services .................................................................................................................. 206

Using Xmethods.com .................................................................................................................. 207

Using the Weblogic Universal Test Client ..................................................................................... 207

Alternative testing points ............................................................................................................ 209

Lab exercise 2 - Exploring other Web Services .......................................................................... 212

Reflection ........................................................................................................................................ 213

Module: Web Services .................................................................................................................... 213

Lab exercise 3 - Writing a simple RPC client ............................................................................. 213

JAX-RPC Static clients ................................................................................................................... 214

Create new project .......................................................................................................................... 214

Generating a static client stub ..................................................................................................... 214

Module: Web Services .................................................................................................................... 216

Lab exercise 5 - Writing a simple web service ........................................................................... 216

Writing the server code ............................................................................................................... 217

Generating the code .................................................................................................................... 217

Test .............................................................................................................................................. 218

Problems ..................................................................................................................................... 218

Module: Web Services .................................................................................................................... 218

Lab exercise 6 - Adding Basic security to a simple web service ................................................ 218

Setting up usernames & roles ...................................................................................................... 219

Writing the server code ............................................................................................................... 220

Redeploy & Test ......................................................................................................................... 220

Generating the Client skeleton .................................................................................................... 221

Test .............................................................................................................................................. 221

Module: Web Services .................................................................................................................... 222

Lab exercise 7 - Writing a more complex web service ............................................................... 222

Other data types .......................................................................................................................... 223

Page 12: J2EE Weblogic Documentation

12

Lab Exercise: Returning complex types ......................................................................................... 223

Creating a JavaBean .................................................................................................................... 223

Add new complex methods to your class .................................................................................... 224

Building a client .............................................................................................................................. 224

Module: Security ............................................................................................................................. 225

Lab exercise - Confidentiality ..................................................................................................... 225

Using SSL ................................................................................................................................... 226

Enforcing SSL ............................................................................................................................. 226

Module: Security ............................................................................................................................. 227

Lab exercise - Web authentication .............................................................................................. 227

Declarative web authentication ................................................................................................... 228

Programmatic web authentication ............................................................................................... 228

Module: Transactions ...................................................................................................................... 229

Lab exercise - Transactions ......................................................................................................... 229

Transactions ................................................................................................................................ 230

Starting a transaction in a servlet ................................................................................................ 231

Module: Legacy .............................................................................................................................. 231

Lab exercise - Using CORBA ..................................................................................................... 231

CORBA - C example .................................................................................................................. 232

Java CORBA client ..................................................................................................................... 234

Additional exercises .................................................................................................................... 235

Module: Legacy .............................................................................................................................. 235

Lab exercise - Using JMS ........................................................................................................... 235

Point-to-Point messaging ............................................................................................................ 236

Extra work ................................................................................................................................... 239

Page 13: J2EE Weblogic Documentation

13

Module: Architecture

Lab exercise - WebLogic setup

This laboratory exercise should be the first one you attempt, as it gives instructions on the steps to follow to set WebLogic up for use in the Faculty of IT environment.

Level of Difficulty: 1 (easy) Estimated time: 10 minutes

Installing your WebLogic server

With the WebLogic setup we are using, each person will run their own separate copy of the WebLogic server on the lab workstations. Each student will also have their own configuration for their server. This configuration is stored in your home directory.

The first step is to logon to the lab workstations. You will have been allocated to a specific machine. This will be the workstation allocated to you for the rest of the semester.

Open a terminal. To do this, select System → Terminal. If you are using KDE, you can also press Right Mouse Button → Terminal.

Enter:

/opt/bea10/wlserver_10.0/common/bin/config.sh

Handy hint: Linux let's you complete the command line by pressing the first letter then the tab key.

The BEA WebLogic Configuration Window should appear. Take the following steps to set up WebLogic on your account:

1. At the Welcome panel: Select [x] Create a new WebLogic domain. Then press the [Next] button.

2. At The Select Domain Source panel: Select [x] Base this domain on an existing template

Leave the default directory and file: (/opt/bea10/wlserver_10.0/common/templates/domains/wls.jar)

3. At The Configure administrator username panel: Enter: Username: weblogic Password: weblogic

4. At The Configure server start mode and JDK panel: Select [x] Development Mode and select [x] BEA supplied JDK, and select jRockit

5. At The Customize environment panel: [x] No

Page 14: J2EE Weblogic Documentation

14

6. At Create WebLogic Domain panel: Domain name: weblogic & Domain location: /home/userid

(where userid is your Faculty of IT userid 7. At Creating Domain panel: [done] 8. Now note that the weblogic install is now in the in /home/userid/weblogic directory

Note: you have now completed the one mandatory part of this lab exercise. You should

read the following information, but you do not need to carry out the tasks below

immediately.

Creating aliases for commonly used commands

There are a few commands you will need to use over and over again. It might be useful for you to create aliases for those commands to save you time and avoid repetitive typing.

Note that the following instructions assuming you are using the Bash shell (which is the default within the Faculty). If you have changed your Unix shell to something else, the following syntax may need to be adjusted to your shell.

Paste the following bash functions into a file in your home directory called: .bashrc (note the leading "."). Create this file if it doesn't already exist.

Note: Don't forget the . (period) characters and spaces.

if [ -d /opt/bea10/wlserver_10.0 ] ; then wlenv() { pushd .; . ~/weblogic/bin/setDomainEnv.sh; popd; } wlstart() { cd ~/weblogic/; ./startWebLogic.sh; } wlstop() { java weblogic.Admin -url t3://localhost:7001 \ -username weblogic -password weblogic FORCESHUTDOWN; } wlenv fi

With these aliases:

• 'wlenv' will set your environment variables ready to compile code for WebLogic • 'wlstart' will start your server • 'wlstop' will stop your server

You should also modify your: .bash_profile file with the following

source .bashrc export PS1="[\u@\h:\w]\\$"

Page 15: J2EE Weblogic Documentation

15

Deleting your WebLogic directory

During the semester, you may find that part of your WebLogic configuration becomes corrupted, and your server will not start. If this happens, the easiest solution is to remove your webLogic directory, and re-create it. Be sure you have kept a copy of all of your deployed applications before you delete the directory though!

To delete your WebLogic directory, run the Unix command:

cd ~/weblogic rm -r .

Note: be very careful to type this command correctly, as it will recursively delete all files in the named directory. In particular, take care that there is no space following the tilde character (~) or you will erase your entire home directory!

After deleting your webLogic directory, you can re-create it as described above.

Copying your WebLogic directory

If you wish to copy your webLogic directory, DO NOT use the Unix 'cp' command. Your webLogic directory contains a number of symbolic links, and it is important that these are kept as symbolic links.

Use the following command if you wish to copy your entire webLogic directory (replacing 'destdir' with the actual destination directory name):

cd; tar cf - weblogic | (cd destdir; tar xfBp -)

Module: Architecture

Lab exercise - Familiarisation 1 - Installing Eclipse

The laboratory exercise for this module to install Eclipse and then develop a one or two static HTML pages

Level of Difficulty: 2 (moderately easy) Estimated time: 30 minutes Pre-requisites:

• Completed WebLogic setup lab exercise • Run 'setDomainEnv.sh' to set your environment correctly

Installing Workshop For Weblogic

Open a terminal, then type the following commands

Page 16: J2EE Weblogic Documentation

16

mkdir ~/workspace tar xvf /pub/ajpcpe/workspace.tar

You now should have a directory called workspace. This is where your lab files will be stored when using Workshop for WebLogic

To start workshop, type

cd ~/workspace ./workshop4WP

You now should see

Page 17: J2EE Weblogic Documentation

17

You should click on the X on the [Welcome] tab to close this window to get the following window:

This is the main J2EE "perspective".

Creating a project

To create a new J2EE project, we are going to create a Web application first.

Step 1: From the Project Explorer:, Right Mouse Button click -> New-> Dynamic Web

Project (alternatively: Choose the File->New->Other->Web->Dynamic Web Project )

Page 18: J2EE Weblogic Documentation

18

Page 19: J2EE Weblogic Documentation

19

Choose the name: labs Target runtime: BEA Weblogic Configurations: Weblogic Web Project Facets (minimal) (hint: Press the down arrow in the Configuration box to get the list)

Then press [Next]

Step 2: We now get a Project Facets popup screen. A 'project facet' is Eclipse terminology for the additional wizards and tools installed for this project. As you can see, there are many to choose from such as Java Annotation processing (this handles Java 5 @annotations). For the moment, don't change this screen.

Then press [Next]

Step 3: We now get a Web Module popup screen:

Page 20: J2EE Weblogic Documentation

20

Change the Context root from "labs" to / (note: this is the "subdirectory" of the web page, so we are now creating a home page for the Weblogic server!) Content directory: WebContent Java source: src

Then press [Next]

Step 4: From the Weblogic Web Module panel: [x] Use Shared Libraries & press [Finish]

Deploying static HTML

The next challenge is to create HTML files for our web site

From Project Explorer select Labs

Page 21: J2EE Weblogic Documentation

21

Now Right Mouse Button click -> New > HTML

→ (note: WebContent is highlighted)

Page 22: J2EE Weblogic Documentation

22

Filename: index.html & press [Next]

At the Select HTML Template panel: HTML 4.01 Transitional & press [Finish]

You can now see it generates a HTML page which you can edit. Why not add some text or HTML formatting tags - change the title and maybe add a a <h1> in the body would be nice. Use Ctrl-S (or File->Save) to save this file.

Running the HTML page

Before you can start testing, you need to define a server to run this web page one. We will use Weblogic as a normal web server for the moment.

Select the labs project in the Project Explorer and press the Right mouse button Select Run As -> Run on Server

You will get a define new server panel:

Page 23: J2EE Weblogic Documentation

23

Choose [x] Manually define a new server

Server host name: localhost Server type: Bea Systems->BEA Weblogic Server v10

Server runtime: BEA weblogic v10

Select [x] Set server as project default:

You will now get a Define a weblogic server panel:

Page 24: J2EE Weblogic Documentation

24

Domain Home: /home/userid/weblogic & select [finish] button (note: userid should be your faculty userid)

You should get a "Add and Remove Projects" panel.

You can have more than one project running on each Weblogic server. For the moment, we will leave this as-is. Press [finish] to continue.

You should get weblogic server starting in a new window - see the Console view on the bottom right hand side for % progress) Wait till the <Server started in RUNNING mode> message appears. You should get a minibrowser in eclipse window with your web page! You can add many extra pages. Try make them link eg: <a href=..">

If you get an error message saying "Publish was cancelled" this could be because your server and project is already running.

If this is the case, you could start the server manually, by pressing the green arrow

If you double-click on the server name (eg: "BEA Weblogic Server V10.0" above), you can also get the server configuration settings. This will allow you to manually remove (ie: "undeploy" ) a project which may be preventing weblogic from starting (for example, "labs" )

Page 25: J2EE Weblogic Documentation

25

If you need to restart the internal browser for any reason, use Window -> Show View -> Other -> General -> Internet Web Browser, however, it is better to start an external browser, as the internal browser may not support all the latest browser functionality.

Test to see that your new application works. In a browser, open a URL like:

http://localhost:7001/index.html

Note that in most cases you will have a "Context root" which is effectively a subdirectory. So if our web Context root was, for example, labs, our URL would be: http://localhost:7001/labs/index.html

Notes:

• Write down notes as you go, particular parts of the process that seem difficult or confusing.

• Ask questions. • Use the WebLogic documentation to help you (start to become familiar with browsing

the documentation). You can find the documentation at: o http://e-docs.bea.com/wls/docs1001/

For an introduction to WAR files, JAR files and EAR files, read Understanding WebLogic Server Applications, URL: http://e-docs.bea.com/wls/docs100/programming/concepts.html

This will give you a head start on some of the later course material.

Module: Architecture

Lab exercise - Familiarisation 2

This laboratory exercise is intended to help you become familiar with running the application server. It will cover starting up and shutting down the server, setting some of the configuration options, and deploying static HTML web pages into the server.

Level of Difficulty: 1 (easy) Estimated time: 45 minutes Pre-requisites:

• Completed WebLogic setup lab exercise • Completed Familiarisation 1 lab exercise

The environment

Page 26: J2EE Weblogic Documentation

26

You will be running WebLogic Server on a Linux workstation. The WebLogic software is installed centrally on file server, and is NFS mounted across all workstations, so everybody will run the same version of the software.

In addition to the central installation of the software, every person will have their own private WebLogic "domain". Each person will start up their own copy of the WebLogic software, and load their domain. Your WebLogic domain configuration will be stored in a subdirectory off your home directory.

There are three parts to using WebLogic:

1. running the server (starting/stopping) 2. using the management console (in a web browser) 3. installing your own applications

This lab exercise is designed to help you become familiar with the first two.

Familiarisation with the directory structure

Record your answers to the following questions.

• In which directory is your domain's config file, config.xml installed?

____________________________________________________________

• In the bin directory, there is a file called 'setDomainEnv.sh'. Have a look at the contents of this file and see what it does. You should run this file every time, before you work with WebLogic. If you haven't run it already in this session, do so now. Note that you must run it by prefixing it with a dot, followed by a space, e.g. . setDomainEnv.sh

Note that the alias you created earlier called wlenv also executes this shell script. If you have started a new shell, then this alias should be created and you can type wlenv instead.

• In which directory is the WebLogic Server installed? (Hint: echo $CLASSPATH)

____________________________________________________________

• What version of Java are you using? (hint: java -version)

____________________________________________________________

Page 27: J2EE Weblogic Documentation

27

• Does your PATH environment variable include the path to the correct version of Java? (hint: echo $PATH). If not, you have not run setDomainEnv.sh correctly. What is the path to the Java compiler?

____________________________________________________________

• In which directory are the WebLogic Java class libraries?

____________________________________________________________

• BEA provide some examples as part of the distribution of WebLogic. In which directory are the examples located?

____________________________________________________________

• In your own WebLogic domain, in which directory is the file 'startWebLogic.sh' located in?

____________________________________________________________

Starting your WebLogic server

IMPORTANT:

Make sure you only run 1 copy of weblogic at a time on the workstation.

This includes the test weblogic server running within Eclipse

Ensure that if this is the case, you should stop the weblogic server within eclipse first!

Use the following steps to start your WebLogic server:

1. First, check that you are logged in to a workstation machine, and NOT charlie or sally. You must NOT run WebLogic on charlie or sally. If you are not sure which host you are logged in to, type the Unix command:

2. hostname

3. Change into the directory where your 'startWebLogic.sh' script is located. You must run the server from this directory. e.g.

4. cd ~/weblogic/

5. Start the server running: 6. ./startWebLogic.sh

You could also use the wlstart alias your set up in an earlier lab.

Page 28: J2EE Weblogic Documentation

28

Getting started

• What are the ports your server is listening on? (hint: netstat -an )

____________________________________________________________

• Start your default WebLogic console by opening a web browser, and accessing the URL:

• http://localhost:7001/console/

Note: If you are accessing this workstation from another machine, change localhost to the name of the workstation

• Note that in the earlier lab, we defined an alias called wlstop, and this had hardcoded the userid and password. Is this a good thing to do? Why?

____________________________________________________________

____________________________________________________________

Enter 'weblogic' for the userid and 'weblogic' to logon to the WebLogic console.

Reading the configuration

Once you logon to the WebLogic console, you will see that there are various options to change and view.

Relevant areas:

Page 29: J2EE Weblogic Documentation

29

DOMAIN:

(this is the top of the menu tree [weblogic] in our console) This provides management of the entire weblogic domain. Note in production you may have more than 1 server.

We will just use the adminServer also as the development server. You can start/stop server by [control] tab. Select AdminServer(admin) & then you can start/resume/shutdown etc.

Shutting down the server: Note that if you just press Shutdown, WebLogic will wait until all requests are serviced. If your program (JSP/Servlet etc) is in a loop, you can click on the pull down and select Force Shutdown Now

Page 30: J2EE Weblogic Documentation

30

ENVIRONMENT:

Don't worry about these options, this is used for clustering and production environments

DEPLOYMENTS:

You will see that this lists all J2EE applications and shared librarys installed ("deployed") on your server. Some relevant tabs to look at:

[Control tab] You can individually (or globally) start or stop the applications. If you have [Lock & Edit] the configuration, you can also install new apps, update and delete existing apps. If you select any app, you will see it's [settings].

This has details like name, context root, path (if you generated this from eclipse, it will be something like /home/chw/workspace/.metadata/.plugins/org.eclipse.core.resources/.projects/labs/

beadep/weblogic/labs !!

[Testing] tab is particularly handy to see what the full URL of the application is and any welcome files in the web application. [Monitoring] is good to see how many active servlets are being used (note: each JSP is also considered to be a servlet) [Monitoring[Servlets]] is good for seeing the servlets available. FileServlet, JSPServlet & WebServiceServlet are automatically generated ones from weblogic. [Monitoring [Sessions]] will track HTTP sessions being used.

SERVICES:

this section covers the J2EE services that the container must provide eg: JDBC, JMS etc When using Database access, you need to define your JDBC details here.

SECURITY REALMS:

You can define a security realm to protect your web application. The default realm is 'myrealm' but you can create many more.Within this tab is [Configuration] & [Users and Groups] where you can define users and groups.

Changing the configuration

Be careful at this point! Don't change anything you don't understand!

In order to change any parameter, you need to click the [Lock & Edit] button on the upper left corner of the control panel

Page 31: J2EE Weblogic Documentation

31

• Change the port that your server listens on to be port 12345. What additional step is needed before the change is committed?

________________________________________________________

• Shut down your server using the WebLogic console. Generally, you should always shut down gracefully using the console, or the command-line shutdown utility - don't just close the Unix shell window.

• Restart your server (from the Windows Command Prompt). • Change your port back to what it was before. • Add some 'Notes' to your domain (or server).

Eclipse Links

http://www.stanford.edu/class/cs108/JavaTools/eclipse-guide/#NewProject

Page 32: J2EE Weblogic Documentation

32

Module: Servlets

Lab exercise - Hello World Servlet

This laboratory exercise involves developing a Hello World servlet, step by step. It is a long process, but each step should be simple enough. Take careful note of what you are doing at each step, and the commands you need to run. It gets easier once you've worked out the process - your first servlet will be your hardest!

Level of Difficulty: 1 (easy) Estimated time: 30 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Start your WebLogic server running in the background

A HelloWorld servlet

There are 2 main ways of creating a servlet

Manually creating a servlet

Before the days of Integrated Development Environments, programmers had to develop servlets much like any other Java package (eg: Applets). The steps involved were

1. Create a development directory structure (typically a source code, build and deployment directory).

2. Create a java class file which imports the relevant javax.servlet.* package (plus any other utility packages you might need such as java.io.*)

3. This class needs to extend javax.servlet.http.HttpServlet and implements the doGet() (and possibly doPost() )methods

4. You then compile this class into the build directory into the WEB-INF/classes directory 5. You then create & edit a deployment descriptor (WEB-INF/web.xml) with the relevant servlet

details 6. Add any extra files like graphics, html and .properties files into the top of the build directory. 7. You then use the jar cvf HelloWorldApp.war command to archive the entire build directory

into a single WAR file 8. You then deploy (copy) this .war file following the instructions of your particular web

application server.

You can optionally attempt this later by looking at the "tutorial: creating war files manually".

Using Eclipse to create a servlet

In this lab we will use Eclipse (Workshop for Weblogic) to create our first servlet.

This exercise will lead you step by step through writing and deploying your first Java servlet.

Page 33: J2EE Weblogic Documentation

33

1. We will re-use the existing lab project from the previous module. However, there is one change that we will make - we will remove the default context since this is effectively hardcoding our URL! From the Project Explorer, DOUBLE click on Weblogic Deployment Descriptor. Select the Design tab and select the wls:context-root attribute. Press RIGHT Mouse button, and select Remove. Save the changes (Control-S).

2. Now to create a servlet, highlight the project name (labs) and use the RIGHT mouse button to select New -> Servlet

3.

4. In the Create Servlet wizard window, enter the Class name for the servlet - ie: HelloWorldServlet. You can optionally enter a Java Package name but this and future lab

Page 34: J2EE Weblogic Documentation

34

examples won't use one for the moment. Press Next to continue.

5. We finish by entering information about the servlet deployment descriptor - the name defaults to HelloWorldServlet, but we will change this to HelloWorld. Enter a description as well. Finally, change the URL mapping (the default is /HelloWorldServlet). To do this, highlight the URL mapping and click Edit. Press Finish to create the Servlet.

Page 35: J2EE Weblogic Documentation

35

6. Eclipse now creates a skeleton of the Servlet code. Eclipse tags the places where you enter your own code with the comment // TODO: Auto Generated Method Stub

7. Replace this comment with the following code fragment. FOR THE MOMENT, PLEASE

DON'T CUT AND PASTE THE CODE. We will experiment with Eclipse's Code assist features to help you enter the correct code as you type!

response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><head><title>Hello, World response</title></head><body>"); out.println("<h1>Hi, this is from a servlet</h1>"); out.println("doesnt do much so far."); out.println("</body></html>");

As you type resp, you can press Ctrl-spacebar to ask Eclipse to show you the valid

candidates which you can legally enter in the Java class that start with the letters resp. Try it...

Page 36: J2EE Weblogic Documentation

36

8. Pressing Enter will insert the whole string response for you. Now if we press the . key to continue, Eclipse will pop up a list of valid methods for this object - we can type-ahead to narrow this list down. Try the first 4 letters setc to get the list down to setContentType. The really neat thing about Eclipse is it also describes what the method does. This even works for

your own custom built methods. However, you do need to use Javadoc /** descriptors before your methods for this to work...

Pressing Enter will insert the template for this method. You simply replace the highlighted string with your own code.

9. Finish typing in the rest of the code now. In later labs you are welcome to cut and paste the code directly into Eclipse, but for the moment, just get used to the Eclipse code editor by typing it in by hand....

10.

Packaging your servlet 1: directory structure

Page 37: J2EE Weblogic Documentation

37

Java servlets execute as part of a web server. You cannot run or test them from the command line. The web server you will use to run your servlet is the web server built in to the application server (WebLogic). To "run" your servlet, you will access a URL in your web browser. This is quite similar to running a CGI program, or running a PHP script.

Before you can install your servlet into the application server, it needs to be packaged properly. Servlets are part of what J2EE calls 'web applications', and web applications should be packaged in a Web Application Archive file, or WAR file.

A WAR file is basically a compressed zip file that contains all parts of your web application. The parts may include:

• static web site files (HTML, GIF, JPEG, CSS, etc) • Java servlets • a deployment descriptor (described later)

When you package your application as a WAR file, it must follow a particular directory structure like the following.

Packaging your servlet 2: deployment descriptor

Page 38: J2EE Weblogic Documentation

38

As mentioned above, a WAR file contains static HTML (etc) files, Java servlet classes, and a deployment descriptor. The next step is for you to create a deployment descriptor.

A deployment descriptor is an XML file describing the properties of your 'web application'. When your web application includes servlets, the deployment descriptor file describes the name of each servlet, and what URL should be used to invoke the servlet.

In the case of web applications, the deployment descriptor is contained in a file called web.xml, and it must be placed in the WEB-INF directory.

The Eclipse Servlet wizard automatically updates and generates this web.xml file. To view this file, check the double click the Deployment Descriptor (alternatively, look in the WEB-INF subdirectory for web.xml )

You could also view this in the Deployment Descriptor/Design tab

Page 39: J2EE Weblogic Documentation

39

Points to note:

• servlet-name can be any name you choose. It does not have to be the same as the filename in which the servlet class is stored. Every servlet referenced in your web.xml must have a unique servlet-name within that one web.xml file.

• servlet-class specifies the name of the Java class file containing the compiled servlet code.

• url-pattern specifies the URL by which you want users to be able to execute your servlet. In the example shown above, the url-pattern is "/HW", so the URL that will be used to invoke the servlet will look like http://hostname:7001/HelloWorldApp/HW

Packaging your servlet 3: static HTML files

Your WAR file can also include static HTML files, as well as images (GIF, JPEG), style sheets (CSS), and any other static files you would expect to find on a web server.

In the WAR file, these files must be placed outside the WEB-INF directory. Any files not in the WEB-INF directory can be accessed through the web browser. Any files that are inside the WEB-INF directory (including your web.xml deployment descriptor, and your servlet class files) will be protected, and are not accessible to users over the web.

Page 40: J2EE Weblogic Documentation

40

You can create subdirectories visible to the user by selecting WebContent and Right Mouse clicking and selecting New -> Folder.

CAUTION: Any subdirectory created OUTSIDE of WebContent will not be accessible to web users - this includes any file placed in WEB-INF!!

You should already have a static HTML file called index.html from the previous lab. Modify this file to link to your new servlet.

<h1>My first WAR file</h1> <P>Run my <A HREF="HW">Hello World servlet</A>.</P>

NOTE: Notice that our HREF refers to HW not /HW or HelloWorldServlet. This is because a putting a / in front of a reference will make the browser look for the absolute URL at the root context (ie: / ) of the web site, not the relative sub-context (ie: /labs ) which we will be deployed as. So putting a /HW will force the web browser to look for http://localhost:7001/HW instead of http://localhost:7001/labs/HW

Here is a rough mapping of how your Eclipse/Workshop project maps to a WAR file.

Page 41: J2EE Weblogic Documentation

41

Packaging your servlet 4: create the WAR file

When testing using Eclipse/Workshop we have been running under what's called an "exploded war directory", ie. the war file has not been archived. While this isn't specified in the Java Enterprise standard, most vendors including Weblogic allow you to specify a directory instead of a WAR file to deploy. This is great for application development and testing. If you are curious about where this directory is located when developing using Eclipse, look at the Weblogic console for a deployment module called "_workshop_auto_generated_ear_" file.

Let's now create a war file which we can distribute and deploy seperately.

1. Step 1: Select the project you wish to create (in our case, labs ) and press Right mouse button. Select Export -> WAR file

2. Next , choose the destination file - let's call this helloWorldApp.war. You should put this into your own directory (I created a local directory called aip to put these files in) Note: Normally you don't includfe source files, but when developing I tend to do this so when I debug I can view which version of the source code I used. You must export the source files when submitting assignments though, so let's Select "Export Source Files" now.. You may also have to select "Overwrite existing file" if helloWorldApp.war exists already.

Page 42: J2EE Weblogic Documentation

42

Also note that the META-INF directory and the MANIFEST.MF file are automatically added by Eclipse.You can ignore them for the moment.

Deploying your web application

Now that you have a WAR file, you can "deploy" it to the web server. Deployment is the process of installing an application.

In WebLogic, there are a variety of ways you can deploy an application. The simplest is just to copy your WAR file into your WebLogic server's "autodeploy" directory.

cp helloWorldApp.war ~/weblogic/autodeploy

You can do this when the server is running. The server checks the contents of the autodeploy directory every few seconds, and when it sees a new WAR file, or one with an updated timestamp, it automatically deploys (or redeploys) it.

Note: if you don't have a weblogic.xml file with a wls:context-root entry in it, weblogic will use the name of the war file as the context-root.

So in our case, the context-root will be helloWorldApp

NOTE: URL's in Java Enterprise are case sensitive!!! So if you type in /HelloWorldApp or /helloworldapp on the browser, you will get a 404 Not Found error!!

Page 43: J2EE Weblogic Documentation

43

Testing your web application

If you have followed the steps above exactly, try accessing your application through the following URL:

http://localhost:7001/helloWorldApp/

It should show you the contents of your index.html file. If you click on the link to your servlet, it should execute your servlet and display the servlet's "Hello World" message.

Note that when you deployed your WAR file into WebLogic, it created a virtual directory under the root of your web server with the same name as your WAR file. So the name you choose for your WAR files is important, because the WAR filename will become part of the URL.

Exploring the WebLogic console

Open the weblogic console (hint: http://localhost:7001/console) and enter the usual administrator userid and password (recall: we set this to weblogic and weblogic respectively??)

On the left hand menu (Domain Structure menu) is a choice called deployments. Select this and you should see the Summary of Deployments" screen like:

Page 44: J2EE Weblogic Documentation

44

(this may not be exactly the same as yours)

You should see a module called _appsdir_helloWorldApp_war (autodeployed) module. Click on this to see the Settings for this deployed war file.

Page 45: J2EE Weblogic Documentation

45

You can see that the path is where the actual WAR file resides - in our ~/autodeploy directory. Also note that the console will display any sub-modules of your deployed module. In our case, there is a Web Application called _appsdir_helloWorldApp_war (autodeployed) which if clicked, returns to this very same page!! (this is more useful when we have an Enterprise Archive (EAR) file which may contain many sub-modules.

Click on the Testing tab at the top. This allows you to check what Weblogic thinks the URL to this application should be. If it is something other than "http://127.0.0.1" just ignore that for the moment. (technically this is because Weblogic binds to all the available network addresses of the host. So it could be something like http://138.25.16.222 or some other weird number).

For the moment, the only important item we want to observe here is the URL and note that the default URL is something like http://xxx.xxx.xxx.xxx/helloWorldApp

So if you are trying to debug your web application and can't seem to start, use this to find out what the default URL should be.

As mentioned earlier, note that there is a Deployment module called "_workshop_auto_generated_ear_". If you select this you could also click on this to see the labs web module, and do the same exploring we did the the helloWorldApp module..

Page 46: J2EE Weblogic Documentation

46

Reflection

This exercise took you through the steps to to create a Servlet using Eclipse (Workshop for Weblogic). Certainly it is possible to create a WAR file by creating a directory structure much like a WAR file, creating web.xml/weblogic.xml by hand, creating Servlet java files and compiling them by hand (or with a build script like Makefile or Ant) and finally generating a WAR file using the jar cvf command.

Using tools like Eclipse improve programmer efficiency by allowing you to incrementally build and test and using wizards to generate & "instantly" test your application.

Note what steps you took, and don't forget to ask your tutor for assistance as necessary.

Furthur labs will not be as detailed as this one, so you must be comfortable using the Eclipse IDE as we go on further

Page 47: J2EE Weblogic Documentation

47

Module: Servlets

Lab exercise - Counter Servlet

This laboratory exercise involves modifying your Hello World servlet to make it keep count of the number of times it has been invoked.

Level of Difficulty: 2 (moderately easy) Estimated time: 15 minutes Pre-requisites:

• Completed the Hello World servlet lab exercise

A Counter servlet

The goal of this exercise is to create a servlet that maintains a counter of the number of times it has been invoked since it was last reloaded by the web server. It will use a class variable (i.e. static) to keep count of the number of invocations. Each time the servlet is invoked, it will print out the value of the counter.

There are 2 main ways to do this lab.

• Method 1 is to create a new Servlet (as per the Hello World Servlet lab) and name this CounterServlet, with the URL mapping of /Counter. You then add the required code to perform the desired task. This is fairly straight forward.

• Method 2 is to copy the existing Servlet and to add it into the deployment descriptor. This is a touch more complicated, so we will do this in this lab to show you how to copy an existing servlet class and insert it into the web project.

Copying an existing Servlet

Begin by copying your Hello World servlet code, and putting it into a file called CounterServlet.java. You may keep it in the same project (WAR file) as before, or put it in a separate WAR file (if you would like more practice at the process of creating WAR files).

Make the following modifications to your Hello World servlet source code:

1. You can cut and paste the HelloWorldServlet from the src folder. Rename the class to CounterServlet

2. Declare a class variable to hold the value of your counter. 3. private static int numRequests = 0;

4. Declare a synchronized method to update the value of the numRequests variable.

private synchronized void incNumRequests() { numRequests++; }

Page 48: J2EE Weblogic Documentation

48

5. Modify the code inside your existing doGet() method to make it call the incNumRequests method you have just created, and print out the current value of the counter.

incNumRequests(); out.println("Number of requests since reload: " + numRequests);

Servlets and threading

The question you should be asking yourself right now is: why do I need to create an extra method just to increment the value of numRequests? Why can't I just have my servlet increment the value directly?

The answer lies in the way servlets handle threading. By default, every servlet you create is multi-threaded. That means that at any given instant in time, multiple instances of your doGet() method could be executing simultaneously.

Also recall the meaning of a class variable (i.e. declared as static) in Java. A static variable is one that is shared between all instances of a given class. So if you have 10 instances of your CounterServlet executing, all 10 instances will be sharing a single copy of the numRequests variable.

What happens if two different instances of your servlet running at the same time both try and update the value of numRequests at the same time? In theory, this could lead to a semantic error in the program because two threads are trying to update the same shared resource simultaneously. [Although strictly speaking in this case there is not much danger because all we are doing is incrementing a single value.]

The general principle that you should follow is that if you ever write a Java servlet where multiple threads will be accessing a single, non-shareable resource, you must programmatically ensure that at most one thread can be accessing the resource at any one time. Java provides this facility through the use of its synchronized keyword.

If you have studied operating systems, note that this is similar in concept to monitors and semaphores used to ensure at most one process is executing a critical section at any given time.

Running your servlet

Page 49: J2EE Weblogic Documentation

49

Follow the same steps you used when creating your Hello World servlet to edit and compile the code.

You now need to do some additional work.. Declare this servlet in your web.xml deployment descriptor. The following steps shows you how to do this via Eclipse/Workshop, but do note that it can be easier just to type the extra entries into the web.xml file directly! (see step 5 for the raw XML code to add)

1. Step 1: Right click on the Deployment Descriptor item. This should show you either the source or the design views. The main advantage of using the IDE is the guarantee of a correctly formatted xml file so let's select the design (also called Deployment Descriptor) tab.

2. Step 2: Right mouse click on the Servlets entry and select New Servlet

3. Step 3: You now create the servlet. You enter the servlet name (Counter) and the name of the servlet class (CounterServlet). Note that you can also use a JSP instead of a servlet class if you wish but we will wait till a later lab to try this out.

Page 50: J2EE Weblogic Documentation

50

4. Step 4: You now enter the servlet URL mapping. We will use /Counter to point to our servlet. You can optionally add more mappings by using the Add button on the Servlet Properties page. One neat trick is to map sub-contexts (which act like virtual subdirectories on the URL) and file names to a servlet directly. For example, you could choose a mapping called /*.counter or index.html to map to CounterServlet!

5. Step 5: If you inspected the generated XML code in web.xml, you should have entries looking somewhat like:

Page 51: J2EE Weblogic Documentation

51

<servlet> <servlet-name>Counter</servlet-name> <servlet-class>CounterServlet</servlet-class> </servlet>

and later in the file ...

<servlet-mapping> <servlet-name>Counter</servlet-name> <url-pattern>/Counter</url-pattern> </servlet-mapping>

Note that the ORDER of these XML entities are important in web.xml. Misplacing them may result in an error or your web application to fail to deploy.

6. Eclipse automatically re-deploys the updated lab so you can now unit-test the

application. Note that each time you reload the browser with the refresh button, the displayed counter should update.

7. You should now redeploy your WAR file by using the Export .. as WAR file menu

and by copying the war file to your WebLogic autodeploy directory. 8. cp HelloWorldApp.war ~/weblogic/autodeploy

9. Test your new servlet, in your web browser, by viewing a URL like the following (the filename on the end of the URL will depend upon the name you chose for the <url-

pattern> 10. http://localhost:7001/HelloWorldApp/Counter

Module: Servlets

Lab exercise - Form parameters

This laboratory exercise involves modifying your Counter servlet so that you may set the value of the counter to an arbitrary value. The servlet takes its input from a HTML form, where the user can enter a value, and the counter will be set to that value.

Level of Difficulty: 3 (requires some thought) Estimated time: 20 minutes Pre-requisites:

• Completed the Counter servlet lab exercise

Page 52: J2EE Weblogic Documentation

52

A SettableCounter servlet

The goal of this exercise is to create a servlet that can both print out the value of a counter (as with the CounterServlet exercise), but also allows a user to set the counter to an arbitrary value.

Begin by creating a HTML form that you will use to view and set the value of the counter. Remember this HTML file must go inside your WAR file.

<FORM METHOD="GET" ACTION="SettableCounter"> <P> Set counter to equal: <INPUT TYPE="TEXT" NAME="newvalue" SIZE="5"> </P> <P><INPUT TYPE="SUBMIT" VALUE="Set Counter"></P> </FORM> <P><A HREF="SettableCounter"> Get counter value</A></P>

As you can see, your servlet code will need to be able to read the value of a parameter taken from a HTML form. Moreover, because the same servlet is being used for both viewing the counter value and setting it, you will need to check if there is a form parameter value supplied. If so, set the counter to the supplied value. If not, just display the counter.

Don't forget to set the Servlet mapping to /SettableCounter

Request and Response objects

Reading the value of form parameters in a servlet is quite easy. However before we get to that, first, notice the definition of the doGet() that you have been using in earlier servlets:

protected void doGet (HttpServletRequest request, HttpServletResponse response) ...

In this definition, there is a "request" object (called request, although you may choose another name if you wish), and a "response" object (called response).

The request Java object encapsulates all the details about the HTTP request that was sent by the user's web browser. This includes the URL of the request, the request method (e.g. GET or POST), the IP address of the client's machine, etc. The request object has methods available to retrieve these various pieces of information about the request. Another piece of information associated with the request object is the names and values of any form parameters that the user might have supplied. This is what we need for this exercise.

Page 53: J2EE Weblogic Documentation

53

The response Java object encapsulates all the details of the HTTP response that will be sent back to the user's web browser. This includes the MIME type (content type) of the document, plus the actual document itself. Even in the Hello World servlet, we have seen two examples of using the response object:

• response.setContentType("text/html"); • PrintWriter out = response.getWriter();

What happens when you change the content type to to be "text/html" instead?

You should also browse the JavaDoc documentation for servlets, and get a feel for the methods available on the HttpServletRequest and HttpServletResposne objects. Both are found in the package javax.servlet.http.

Reading form parameters

By now we have established that to read HTML form parameters, we need to use a method on the request object. The method we need is called getParameter().

To read the value of a HTML form parameter named "newvalue", use the following line of Java code:

String formvalue = request.getParameter("newvalue");

If there was no form field named "newvalue", then the getParameter() function will return null. To see whether a particular form field was supplied or not, you can just compare the result of getParameter() against null. [Hint: you need to do this as part of your SettableCounterServlet.]

Finally, note that when you read form parameters, they are always read as Java String objects. Your SettableCounterServlet will probably need to use the value as a Java int, not a String. Here's a reminder of how to convert a String to an int, although in general you should be able to work things like this out for yourself (remember this is not an introductory Java course). Do not expect tutors to answer questions like this for you!

int formvalueint = Integer.parseInt(formvalue);

(this may throw a NumberFormatException that you must handle).

You should now have all the information you need to create your SettableCounterServlet. You just have to put it all together!!!!

Page 54: J2EE Weblogic Documentation

54

Aside: printing all form parameters

For debugging, sometimes it is useful to have your servlet print out a list of all form field names and their associated values. Here is a piece of code to do that. Try it out in one of your own servlets if you wish, and use a HTML form with several parameters to invoke your servlet.

java.util.Enumeration e = request.getHeaderNames(); while (e.hasMoreElements()) { String hdrName = (String) e.nextElement(); String hdrValue = request.getHeader(hdrName); out.println(hdrName + ": " + hdrValue); }

Page 55: J2EE Weblogic Documentation

55

Module: Servlets

Lab exercise - HTTP Sessions

This laboratory exercise involves modifying your Counter servlet to introduce a second counter. The second counter should keep count of how many times the current user has accessed the servlet, and this counter will be different for each user.

Level of Difficulty: 4 (moderately difficult) Estimated time: 20 minutes Pre-requisites:

• Completed the Counter servlet lab exercise

A SessionCounter servlet

The goal of this exercise is to create a servlet that, when invoked, will print out two different counter values:

• the original CounterServlet value (total number of times the servlet has been invoked since it was reloaded);

• a counter that keeps count of the number of times the current user has invoked the servlet in his/her current session.

This requires the use of sessions and session variables in your servlet.

The state problem

As you know, HTTP is a stateless protocol. This means that a web server sees each incoming request as being completely independent from all earlier requests.

However many web applications need to keep state information at the server, so the statelessness of HTTP is a problem. For example, when you access an online banking application, you first log in with your account number and PIN, and then as you click through various pages on the bank's web site, the application running on the bank's web server needs to keep track of who you are.

Another example is the ubiquitous shopping cart. As you browse through a product catalog, and add items to your cart, the web application needs to keep track of which items are currently in your cart.

Page 56: J2EE Weblogic Documentation

56

In web application terminology, the word session refers to the interaction between a user and a web application, where the web application keeps state information about the user's interactions even though they span multiple HTTP requests. A session typically lasts for a single browsing session. If a user closes their browser and re-opens it and goes back to the web application, they will have to begin a new session. If a user doesn't access the web application for a period of time, their session might time out (whether or not it does is application-dependent).

There are different ways to implement sessions on top of the stateless HTTP protocol. The two typical ways are using cookies and URL rewriting. These will be described in the lecture notes.

Sessions and Java

Java servlets have built-in support for session management that simplifies the task of creating a web application that requires a session-based interaction with a user.

The abstraction used in Java is the notion of session attributes that can be stored in a session

object. The session object acts like a container. You can store attributes (name/value pairs) into the session object, and you can retrieve attributes out of the session object. Attributes that are stored in the session object will still keep their value in between successive HTTP requests. Each "attribute value" is, of course, a Java object.

Each attribute stored in the session has a name, and a value. The name is just a String. The value is a Java object. The HttpSession class uses the methods setAttribute() and getAttribute for storing and retrieving attributes in sessions respectively.

Where do you get the session object from in the first place? From the request object. You get the session from the request. If there was already a session established, then you will have access to all the variables stored in the session. However if there was not already a session established, one will be created automatically (by default), and you will then have access to a blank session object in which you can store variables.

Now for some code snippets:

1. Getting hold of a session object (from the request): 2. HttpSession sess = request.getSession();

3. Storing an object into the session: 4. Integer counterval = new Integer(105); 5. sess.setAttribute("sessioncounter", counterval);

6. Retrieving an object from the session: 7. Integer newcounterval = sess.getAttribute("sessioncounter");

Page 57: J2EE Weblogic Documentation

57

SessionCounterServlet

With that knowledge, work on modifying your CounterServlet to add a second counter - one that keeps track of the number of accesses a user has made in the current session.

To test, try accessing your servlet from two different browsers (e.g. Firefox and IE on the same machine, or two different browsers on two different machines). Don't just use two different windows belonging to the same browser (because different browser windows still share cookie data, which is used to maintain sessions).

Aside: common usage pattern for sessions

Typically a servlet has to be able to deal with the situation when a session does not already exist and has to be initialised. One way to do this is to retrieve an attribute from the session, and if it is null (or if a flag is set to indicate that the session is new), then automatically initialise the attribute and store it in the session. This means that your servlet can both deal with existing session attributes and automatically set up a new session attribute when needed.

Here is a code sample:

HttpSession sess = request.getSession(); Integer sesscounter; sesscounter = (Integer) sess.getAttribute("numaccesses"); if (sess.isNew() || sesscounter == null) { sesscounter = new Integer(0); sess.setAttribute("numaccesses", sesscounter); }

URL Rewriting

The following servlet illustrates the use of URL rewriting when cookies aren't supported in your browser. This servlet also illustrates the use of Servlet API to extract various information related to a session.

// Retrieve the count value from the session Integer ival = (Integer) session.getAttribute("numaccesses"); // If the counter is not currently contained in the session, // one needs to be created:

Page 58: J2EE Weblogic Documentation

58

if (ival==null) { ival = new Integer(1); } else { ival = new Integer(ival.intValue() + 1); } session.setAttribute("numaccesses", ival); // Print out how many times the user has hit the current page: out.println("You have hit this page <b>" + ival + "</b> times.<p>"); out.println("Click <a href=" + response.encodeURL("SessionServletApp") + ">here</a>"); out.println(" to ensure that session tracking is working even " + "if cookies aren't supported.<br>"); out.println("<p>"); // Finally, demonstrate some of the more common methods in the // HttpSession object surrounding sessions: out.println("<h3>Request and Session Data:</h3>"); out.println("Session ID in Request: " + req.getRequestedSessionId()); out.println("<br>Session ID in Request from Cookie: " + req.isRequestedSessionIdFromCookie()); out.println("<br>Session ID in Request from URL: " + req.isRequestedSessionIdFromURL()); out.println("<br>Valid Session ID: " + req.isRequestedSessionIdValid()); out.println("<h3>Session Data:</h3>"); out.println("New Session: " + session.isNew()); out.println("<br>Session ID: " + session.getId()); out.println("<br>Creation Time: " + new Date(session.getCreationTime())); out.println("<br>Last Accessed Time: " + new Date(session.getLastAccessedTime()));

Ensure your browser accepts cookies by checking Tools -> Options -> Privacy (Firefox) or Tools -> Privacy -> Sites (Internet Explorer). If the browser is not allowed to accept cookies, please enable it to accept cookies for this exercise to work. You may need to start the browser again for any changes to take place.

When you access the servlet for the very first time, observe the information returned from the server. Among many things, it should display the session as new. If you press 'Reload'

button, the new session should be displayed as false. Also, the request session id from cookie and URL are true and false respectively. This is because you browser is set to accept cookies.

Now, disable the cookies (see Tools -> Options -> Privacy/ Tools->Privacy-Sites). Restart the browser to take effect of this new change. Don't forget to reset to the setting you had before after the exercise.

Access your servlet as before and session should be correctly reported as new. Press Reload button and what you should observe is that the session is still reported as new (same behaviour for multiple reloads). Remember, earlier new session is only reported for the first

Page 59: J2EE Weblogic Documentation

59

time you access the page and false for any subsequent accesses (within a session). Even though you didn't use Cookies explicitly, Weblogic uses a temporary cookie to store the current session. Since your browser is set not to accept any cookies (including temporary cookies), sessions do not work correctly.

However, press on 'Click here' link to enable URL writing and watch the URL that appears in the Address/Location bar. You should notice some extra text on the end of the URL indicating that URL rewriting is now being used to maintain the session state when cookies are disabled. What is also interesting to observe is that the display correctly reports the requested session id is from a URL and not from a Cookie.

Page 60: J2EE Weblogic Documentation

60

Module: Servlets

Tutorial - Accessing resources (e.g. relative files)

Note that this is not a lab exercise - it is just some information that you may find useful when using servlets (or JSPs).

So you create a web application and package it up in a WAR file. But then from within your servlet or JSP code, you want to open a file which is also stored inside the WAR file.

But you can't use the normal Java File class, because it expects a full absolute pathname!!!

The solution: use methods on the ServletContext.

• java.net.URL getResource("/path") - this will return the URL to use to access a specific file in the war file

• java.util.Set getResourcePaths("/path") - this will return a directory like listing of files that start with /path

• java.io.InputStream getResourceAsStream("/path") - this will return the contents of the file named /path

(Follow the links above to go to the Sun JavaDoc documentation.)

Some sample code

Use your right-mouse button to save this to a local file.

• ResourceTest.war A WAR file containing an example of using these methods.

Page 61: J2EE Weblogic Documentation

61

Module: Servlets

Tutorial exercise - Creating a WAR file manually

This laboratory exercise involves developing a Hello World servlet, step by step. It is a long process, but each step should be simple enough. Take careful note of what you are doing at each step, and the commands you need to run. It gets easier once you've worked out the process - your first servlet will be your hardest!

Level of Difficulty: 1 (easy) Estimated time: 30 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Start your WebLogic server running in the background

Manually creating a servlet

This exercise will lead you step by step through writing and deploying your first Java servlet without an Integrated Development Environment (IDE) such as Eclipse.

1. Create a directory to store your source code. This directory should be completely outside the WebLogic server directory hierarchy, e.g.

cd mkdir aip mkdir aip/servlets mkdir ajp/servlets/helloworld cd aip/servlets/helloworld

Create a file called HelloWorldServlet.java with the following contents. If you are familiar with Unix, try the 'vi' editor, e.g. vi HelloWorldServlet.java

import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class HelloWorldServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); out.println("Hello servlet world!"); out.close(); }

Page 62: J2EE Weblogic Documentation

62

}

Compile your source code using javac.

javac HelloWorldServlet.java

If you see an error message that it cannot import the servlet packages (javax.servlet and javax.servlet.http), then your environment is not set correctly. Go back and re-run setEnv.sh.

Congratulations, you have just written your first Java servlet. Before you can run it though, you must first package it, and deploy it. These steps are described below.

Packaging your servlet 1: directory structure

Java servlets execute as part of a web server. You cannot run or test them from the command line. The web server you will use to run your servlet is the web server built in to the application server (WebLogic). To "run" your servlet, you will access a URL in your web browser. This is quite similar to running a CGI program, or running a PHP script.

Before you can install your servlet into the application server, it needs to be packaged properly. Servlets are part of what J2EE calls 'web applications', and web applications should be packaged in a Web Application Archive file, or WAR file.

A WAR file is basically a compressed zip file that contains all parts of your web application. The parts may include:

• static web site files (HTML, GIF, JPEG, CSS, etc) • Java servlets • a deployment descriptor (described later)

Importantly, when you package your application as a WAR file, it must follow a particular directory structure. Starting at the same directory where your HelloWorldServlet.java file is, run the following commands. Note that the directory names are case-sensitive, so be careful to type them correctly.

mkdir WEB-INF mkdir WEB-INF/classes

Your compiled Java servlet class files must be placed in the WEB-INF/classes directory. When you compiled your HelloWorldServlet earlier, you just put the .class file in the same directory as the .java file. You'll need to fix that now.

rm *.class javac -d WEB-INF/classes HelloWorldServlet.java

Page 63: J2EE Weblogic Documentation

63

Note the use of the '-d' option to javac, which allows you to specify the output directory (where the .class files go).

Packaging your servlet 2: deployment descriptor

As mentioned above, a WAR file contains static HTML (etc) files, Java servlet classes, and a deployment descriptor. The next step is for you to create a deployment descriptor.

A deployment descriptor is an XML file describing the properties of your 'web application'. When your web application includes servlets, the deployment descriptor file describes the name of each servlet, and what URL should be used to invoke the servlet.

In the case of web applications, the deployment descriptor is contained in a file called web.xml, and it must be placed in the WEB-INF directory.

Edit the web.xml file now, e.g.

vi WEB-INF/web.xml

(or use the text editor of your choice). Into the web.xml file, copy the following text:

<?xml version="1.0" ?><web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"><web-app> <servlet> <servlet-name>HWServlet</servlet-name> <servlet-class>HelloWorldServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HWServlet</servlet-name> <url-pattern>/HW</url-pattern> </servlet-mapping> </web-app>

Points to note about the definitions in web.xml:

• servlet-name can be any name you choose. It does not have to be the same as the filename in which the servlet class is stored. Every servlet referenced in your web.xml must have a unique servlet-name within that one web.xml file.

• servlet-class specifies the name of the Java class file containing the compiled servlet code.

• url-pattern specifies the URL by which you want users to be able to execute your servlet. In the example shown above, the url-pattern is "/HW", so the URL that will be used to invoke the servlet will look like http://hostname:7001/HelloWorldApp/HW

Page 64: J2EE Weblogic Documentation

64

Packaging your servlet 3: static HTML files

Your WAR file can also include static HTML files, as well as images (GIF, JPEG), style sheets (CSS), and any other static files you would expect to find on a web server.

In the WAR file, these files must be placed outside the WEB-INF directory. Any files not in the WEB-INF directory can be accessed through the web browser. Any files that are inside the WEB-INF directory (including your web.xml deployment descriptor, and your servlet class files) will be protected, and not accessible to users over the web.

Let's create a static HTML file called index.html to go inside your WAR file. It can go in the top-level directory of your web application (i.e. the directory that has the WEB-INF subdirectory in it).

Use a text editor to create index.html with the following contents:

<HTML> <BODY> <H1>My first WAR file</H1> <P> Run my <A HREF="HW">Hello World servlet</A>. </P> </BODY> </HTML>

Packaging your servlet 4: final check

When creating WAR files, it is very important that everything is in the correct directory. So before we actually create the WAR file, take a moment to check when you view your directory hierarchy, it looks something like the following:

$ ls -1F HelloWorldServlet.java WEB-INF/ index.html $ ls -1F WEB-INF classes/ web.xml $ ls -1F WEB-INF/classes HelloWorldServlet.class

i.e. the directory tree structure should look like:

Page 65: J2EE Weblogic Documentation

65

- index.html - HelloWorldServlet.java / WEB-INF - web.xml / classes - HelloWorldServlet.class

Note that it is not essential to have your Java source code file as part of the WAR file, but it is convenient to keep all the files together.

Packaging your servlet 5: create the WAR file

Finally, you are ready to create your WAR file. Run the following command, which will create a file called HelloWorldApp.war in the parent directory of where you execute it from.

jar cf ../HelloWorldApp.war *

In the above command, the "c" means "c"reate a WAR file.

Now view the contents of your WAR file to ensure that the file was created correctly. Run the following command to list the WAR file contents:

jar tf ../HelloWorldApp.war

In the above command, the "t" means to show the "t"able-of-contents of the WAR file.

The output from the previous command should show something like:

META-INF/ META-INF/MANIFEST.MF HelloWorldServlet.java WEB-INF/ WEB-INF/classes/ WEB-INF/classes/HelloWorldServlet.class WEB-INF/web.xml index.html

The META-INF directory and the MANIFEST.MF file are automatically added by the jar utility. You can ignore them.

Deploying your web application

Now that you have a WAR file, you can "deploy" it to the web server. Deployment is the process of installing an application.

Page 66: J2EE Weblogic Documentation

66

In WebLogic, there are a variety of ways you can deploy an application. The simplest is just to copy your WAR file into your WebLogic server's "autodeploy" directory.

cp ../HelloWorldApp.war ~/weblogic/autodeploy

You can do this when the server is running. The server checks the contents of the autodeploy

directory every few seconds, and when it sees a new WAR file, or one with an updated timestamp, it automatically deploys (or redeploys) it.

Testing your web application

If you have followed the steps above exactly, try accessing your application through the following URL:

http://localhost:7001/HelloWorldApp/

It should show you the contents of your index.html file. If you click on the link to your servlet, it should execute your servlet and display the servlet's "Hello World" message.

Note that when you deployed your WAR file into WebLogic, it created a virtual directory under the root of your web server with the same name as your WAR file. So the name you choose for your WAR files is important, because the WAR filename will become part of the URL.

Reflection

Take note of what was required to write a single servlet, package it in a WAR file, and deploy it to the web server. Note the commands, and the directory structure used.

When you go to create your second servlet, you might find it easier to set up the directory structure first before beginning to write any Java source code. You will also probably find it convenient to copy your web.xml file and simply edit the values inside.

You might even like to create yourself a Makefile, or a shell script which automates the process of compiling, packaging and deploying your WAR file.

Page 67: J2EE Weblogic Documentation

67

Module: JSP

Lab exercise - Hello World JSP

JavaServer Pages is quite similar in purpose to servlet code. However the big difference is that JSP code is embedded inside a HTML web page rather than executed as a separate program. So this exercise involves creating a HTML web page with some embedded Java code.

Level of Difficulty: 1 (easy) Estimated time: 15 minutes Pre-requisites:

• Completed the 'Servlets' labs • Be comfortable with running static HTML and servlets under Eclipse

A HelloWorld JSP

There are many approaches to developing servlets and JSPs. You can create/edit SP's using vi (or notepad) and develop/package a WAR file by hand or use a code generator like XDoclet to automatically build your WAR file structure.

We will cover the middle ground and will use an IDE like Eclipse/Workshop which has 'wizards' and templates to assist us to generate JSP's and WAR files. This fairly trivial introduction lab will get you started...

1. Ensure that Weblogic server is not running since we will start this from within Workshop for Weblogic.

2. Startup Workshop for Weblogic as usual and open our labs project from the Servlet lab.

3. Use Right Mouse Button -> New -> JSP to create a file called HelloWorld.jsp. Note that the "Create new Java Server Page" Wizard automatically highlights the webcontent directory. This is the root of your web application. Choose the New JSP file (html) template which should open an editor window with a skeletal JSP (much like the static html exercise). Edit the file to match the following contents:

(changes are in italics) <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!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=ISO-8859-1">

Page 68: J2EE Weblogic Documentation

68

<title>My First JSP page</title> </head> <body> <h1>My first JSP page</h1> <p> <% out.println("Hello JSP World"); %> </p> </body> </html>

Note the following points:

o The Java code is embedded between the tags <% and %> This is called a JSP scriptlet.

o There is an implicit object called out available in every JSP page that you can use without pre-declaring. Think of it as a "built-in" object. This object is basically of type java.io.PrintWriter. Servlets that you created also used a PrintWriter, but in a servlet, you had to explicitly create the PrintWriter object, e.g.

o PrintWriter out = request.getWriter(); o out.println("Hello Servlet World");

In a JSP page, you can use the out object without needing to create an instance of it, as an instance is implicitly always available in every JSP page.

o You do not need to compile your JSP page. 4. Run your new JSP by doing the usual Right Mouse Button, Run As -> Run On server.

Once your server is running, you can also view the JSP in a web browser, by viewing a URL like the following. Note that the first part of the URL path is the context root name (in our case, labs), but this can also be the WAR filename if you exported the project as a WAR file and copied it to the autodeploy directory.

5. http://localhost:7001/labs/HelloWorld.jsp

When the web server loads your JSP file, there will be a delay of up to a few seconds. What is actually happening is that the JSP file you created is being compiled automatically into a servlet (yes, a servlet!). The web server will then execute the servlet it has generated from your JSP, and keep a cached copy of the generated class file so that it doesn't need to recompile the JSP on subsequent requests.

So although there is a delay, it only happens once (or rather, only once each time you modify the JSP file).

6. If you do any subsequent changes in Eclipse, the changes should be visible immediately in the browser. HOWEVER, if you had exported and deployed a WAR file, you will need to rebuild/export and redeploy the WAR file to reflect the changes.

Creating a subfolder (subdirectory)

Page 69: J2EE Weblogic Documentation

69

1. Create a subdirectory (subfolder or subcontext in web terminology) by selecting webcontent then pressing Right Mouse Button -> New -> Folder

Let's call this images

2. Now you can create more JSP or HTML files into this directory, but for this example, we will demonstrate how to import files from the filesystem. Select the images folder and click Right Mouse Button -> Import

Expand General, then choose -> File System

You can then type in a file name or use the Browse button to find one. Let's browse to /pub/aip/images and select yellowstar.gif

You can now see this file in your WebContent/images directory and can refer to this in your JSP

3. Modify your JSP to reference this image ie: add the line

<img src="images/yellowstar.gif">

(note that we do not put a / in front of images. This is because the file must be relative to the context ie: labs)

Make sure you create the subfolder under the webcontent folder. If you have the wrong directory (eg: Java Resources), bad things will happen:

1. The file will not be accessible from the web pages 2. The file may not be exported into the WAR file. So be careful. 3. Also note that the folder and filenames are Case sensitive!

4. Try it out. If running under Eclipse, you normally don't need to redeploy or even do Run As -> Run on Server. Just open the browse (or refresh the current page) to see the changes appear dynamically!

5. Finally, add a link in your index.html page to this JSP (if you don't have an index.html file, create it, this is normally the default home page of your web application!

Page 70: J2EE Weblogic Documentation

70

Module: JSP

Lab exercise - JSP and form parameters

Just as servlets can access parameters from HTML forms, so can JSPs. This lab demonstrates how, and also introduces JSP declarations and expressions.

Level of Difficulty: 2 (moderately easy) Estimated time: 20 minutes Pre-requisites:

• Completed the Hello World JSP lab exercise

More implicit objects in JSP

In the Hello World JSP exercise, you saw the use of one of the JSP implicit objects called out. Now it's time to introduce two more implicit objects:

request Encapsulates all information about the request that was sent by the web browser. It is of type javax.servlet.http.HttpServletRequest

response Encapsulates all information about the response that will be sent back to the web browser. It is of type javax.servlet.http.HttpServletResponse

These should seem familiar. In a servlet, when you implemented a doGet() or doPost() or service() method, the method implementation took two parameters - one of type HttpServletRequest and the other of type HttpServletResponse.

In JSP, you do not have to declare the request and response objects before use - they are implicitly available.

Reading form parameters in JSP

Now that you know about the existence of the request implicit object, reading form parameters should be easy - the Java code has exactly the same syntax as you used for servlets, e.g.

<%! String formvalue; %> <% formvalue = request.getParameter("newvalue"); %>

Page 71: J2EE Weblogic Documentation

71

JSP declarations, scriptlets and expressions

Look again at the code from above:

<%! String formvalue; %> <% formvalue = request.getParameter("newvalue"); %>

Notice that this time the tag used to indicate the start of the first block of Java code was <%! This sequence indicates that the enclosed block of Java code forms a JSP declaration, not a scriptlet.

A JSP scriptlet (as used in the Hello World JSP example) can contain any arbitrary Java code. However a JSP declaration can only contain declarations. Inside a declaration block, you can declare variables, and you can declare functions. Code within a declaration block must never generate any output.

It's time to introduce yet another kind of JSP code block - a JSP expression. Assume that you wanted to print out (into the web page) the value that the user had entered into the "newvalue" field, as shown above. In the above code, we created a Java variable called "formvalue" which holds the data we need.

A JSP expression is used purely for displaying the value of a variable (or any Java expression). It only generates output. It should not be used to do any other kind of processing.

So to print out the value of the "formvalue" variable, you can use the following JSP syntax:

<%= formvalue %>

This will embed into the output of the JSP page the contents of the "formvalue" variable. Notice that for a JSP expression, the starting tag is <%=

Putting the example of the JSP declaration and JSP expression together, you might have a JSP file with the following code in it:

<%! String formvalue; %> <% formvalue = request.getParameter("newvalue"); %> ... other HTML code ... The value entered was: <%= formvalue %>

JSP block Start

tag Can contain

declaration <%! Variable and method declarations, nothing else. In particular, the code

Page 72: J2EE Weblogic Documentation

72

must not generate any output

expression <%= A Java expression that evaluates to a single value, which will be printed out into the surrounding web page

scriptlet <% Arbitrary Java code. This is the most general of the three, as you can basically put any Java code you wish inside the tags

The exercise - changing background colours

Modify your HelloWorld JSP to process input from a HTML form. This form will allow users to select a background colour from a drop-down list. When the JSP loads, it sets the HTML background colour to the user's choice.

You should create a JSP file called ColourChooser.jsp with a form that looks like:

<%! ??? %> <body bgcolor="..."> <form action="ColourChooser.jsp" method="post"> <select name="mycol" size="4"> <option selected="selected" value="red">red</option> <option value="blue">blue</option> <option value="green">green</option> <option value="yellow">yellow</option> </select> <p><input type="submit" name="submit" value="Change Colour"/> </p> </form> </body>

Note that the action of the form points to ColourChooser.jsp, i.e. it points to itself. The form has a single input field, named "mycol".

At two points in the above listing, there is a ???? and a ... Your task is to fill in the two blanks and solve the problem.

In your first solution, you should use both JSP declarations and expressions, rather than trying to do everything in a scriptlet.

[Aside: If you want to be clever, after getting a basic solution working, think about changing your code to check whether the value of the form parameter was null, and if so, using some appropriate default colour. This will require a scriptlet, because you cannot put a Java "if" statement inside either a declaration or an expression.]

Test your JSP by simply typing in the url eg: http://localhost:7001/labs/ColorChooser.jsp

Don't forget to add a link to this JSP to your index.html file.

Page 73: J2EE Weblogic Documentation

73

Module: JSP

Lab exercise - JSP and sessions

JSPs can also access information from sessions. JSPs and servlets can use session information interchangeably - they have the same interface to it. This lab illustrates how to access session information in a JSP, and as an aside, shows how to import Java class libraries for use in a JSP.

Level of Difficulty: 3 (requires some thought) Estimated time: 30 minutes Pre-requisites:

• Completed the JSP and form parameters lab exercise

Accessing sessions in JSP

You have seen already how to access sessions in a servlet. Accessing sessions in a JSP is almost identical - actually it's even simpler because you don't have to create your own instance of a HttpSession object - one is implicitly available.

Let's review the JSP implicit objects you already know about, and introduce a new one, called session.

Implicit

object Java Type Purpose

out javax.servlet.jsp.JspWriter (like a PrintWriter)

Use the print() or println() methods for generating output that will be sent back to the browser

request javax.servlet.http.HttpServletRequest Used to access information about the HTTP request (from the browser)

response javax.servlet.http.HttpServletResponse Used to set information that becomes part of the HTTP response (sent to the browser)

session javax.servlet.http.HttpSession Used to get and set attributes associated with the current session

Using the implicit session object is quite similar as its use in servlets, e.g.

• Storing an object into the session: • Integer counterval = new Integer(105);

• session.setAttribute("sessioncounter", counterval);

Page 74: J2EE Weblogic Documentation

74

• Retrieving an object from the session: • Integer newcounterval = session.getAttribute("sessioncounter");

Using Java class libraries in JSP

Sometimes you want to access classes in one of the standard Java class libraries, or perhaps you want to import a class library you wrote yourself. In a Java servlet, you would normally put an "import" statement near the top of your Java source file, but what about JSP?

JSP has a special syntax for importing, using what's called a JSP directive.

<%@ page language="java" import="java.util.*" %>

Note the new syntax again - this time the start tag is <%@ which indicates that this is a JSP directive. JSP directives are like instructions to the compiler. In this case, we are telling the compiler that the language embedded in this page is Java, and that we would like to import the java.util.* library.

You can add more than one import by seperating each package with a , eg: import="java.util.*,java.io.*"

Now you have seen four ways of embedding JSP information into a web page: declarations, expressions, scriptlets and directives. Each has a different starting tag.

The exercise - storing a history of background colours

Modify your ColourChooser.jsp file to store a history of all background colours the user has chosen in the current session. Make it so that the list of colours previously chosen is displayed at the bottom of the web page, underneath the form.

Hints:

• The basic idea is to use a java.util.Vector object to store the list of colours. Recall that a Vector is stores a set of values, and acts like a potentially infinite list of items. Forgotten how to use a Vector? Go read the API documentation at http://java.sun.com/j2se/1.4/docs/api/ and the Java platform tutorial

You can, if you wish, use another data structure that comes with the Java 2 Collections framework, like a java.util.LinkedList or java.util.ArrayList, but make sure you use a synchronized version. The API docs tell you how. A Vector is good enough for what we are doing however.

Page 75: J2EE Weblogic Documentation

75

• Each time the user selects a colour (i.e. each time the page is reloaded), retrieve your Vector from the session and add a new item onto the end of it.

• Note that you will need to use a JSP directive to import the java.util.Vector class before you can use it.

• The following code snippet may help. • <%! Vector colourhistory; %>

• <%

• colourhistory = (Vector) session.getAttribute("colhist");

• if (session.isNew() || colourhistory == null) {

• colourhistory = new Vector();

• session.setAttribute("colhist", colourhistory);

• }

• %>

Java 5 adds Generics to the Java Language. If you wish, you can convert your code to be made type safe by declaring colourhistory as Vector<String> (along with modifying the rest of the code to suit generics. Note that you may get a warning on the cast to (Vector) which can be safely ignored.

• Hint: You can print out the Vector directly using the <%= colourhistory %> JSP expression instead of using an Enumeration to loop through this.

Page 76: J2EE Weblogic Documentation

76

Module: JSP

Lab exercise - JSP and sessions

JSPs can also access information from sessions. JSPs and servlets can use session information interchangeably - they have the same interface to it. This lab illustrates how to access session information in a JSP, and as an aside, shows how to import Java class libraries for use in a JSP.

Level of Difficulty: 3 (requires some thought) Estimated time: 30 minutes Pre-requisites:

• Completed the JSP and form parameters lab exercise

Accessing sessions in JSP

You have seen already how to access sessions in a servlet. Accessing sessions in a JSP is almost identical - actually it's even simpler because you don't have to create your own instance of a HttpSession object - one is implicitly available.

Let's review the JSP implicit objects you already know about, and introduce a new one, called session.

Implicit

object Java Type Purpose

out javax.servlet.jsp.JspWriter (like a PrintWriter)

Use the print() or println() methods for generating output that will be sent back to the browser

request javax.servlet.http.HttpServletRequest Used to access information about the HTTP request (from the browser)

response javax.servlet.http.HttpServletResponse Used to set information that becomes part of the HTTP response (sent to the browser)

session javax.servlet.http.HttpSession Used to get and set attributes associated with the current session

Using the implicit session object is quite similar as its use in servlets, e.g.

• Storing an object into the session: • Integer counterval = new Integer(105);

• session.setAttribute("sessioncounter", counterval);

• Retrieving an object from the session: • Integer newcounterval = session.getAttribute("sessioncounter");

Page 77: J2EE Weblogic Documentation

77

Using Java class libraries in JSP

Sometimes you want to access classes in one of the standard Java class libraries, or perhaps you want to import a class library you wrote yourself. In a Java servlet, you would normally put an "import" statement near the top of your Java source file, but what about JSP?

JSP has a special syntax for importing, using what's called a JSP directive.

<%@ page language="java" import="java.util.*" %>

Note the new syntax again - this time the start tag is <%@ which indicates that this is a JSP directive. JSP directives are like instructions to the compiler. In this case, we are telling the compiler that the language embedded in this page is Java, and that we would like to import the java.util.* library.

You can add more than one import by seperating each package with a , eg: import="java.util.*,java.io.*"

Now you have seen four ways of embedding JSP information into a web page: declarations, expressions, scriptlets and directives. Each has a different starting tag.

The exercise - storing a history of background colours

Modify your ColourChooser.jsp file to store a history of all background colours the user has chosen in the current session. Make it so that the list of colours previously chosen is displayed at the bottom of the web page, underneath the form.

Hints:

• The basic idea is to use a java.util.Vector object to store the list of colours. Recall that a Vector is stores a set of values, and acts like a potentially infinite list of items. Forgotten how to use a Vector? Go read the API documentation at http://java.sun.com/j2se/1.4/docs/api/ and the Java platform tutorial

You can, if you wish, use another data structure that comes with the Java 2 Collections framework, like a java.util.LinkedList or java.util.ArrayList, but make sure you use a synchronized version. The API docs tell you how. A Vector is good enough for what we are doing however.

• Each time the user selects a colour (i.e. each time the page is reloaded), retrieve your Vector from the session and add a new item onto the end of it.

• Note that you will need to use a JSP directive to import the java.util.Vector class before you can use it.

Page 78: J2EE Weblogic Documentation

78

• The following code snippet may help.

<%! Vector colourhistory; %> <% colourhistory = (Vector) session.getAttribute("colhist"); if (session.isNew() || colourhistory == null) { colourhistory = new Vector(); session.setAttribute("colhist", colourhistory); } %>

Java 5 adds Generics to the Java Language. If you wish, you can convert your code to be made type safe by declaring colourhistory as Vector<String> (along with modifying the rest of the code to suit generics. Note that you may get a warning on the cast to (Vector) which can be safely ignored.

• Hint: You can print out the Vector directly using the <%= colourhistory %> JSP expression instead of using an Enumeration to loop through this.

Module: JSP

Lab exercise - Web authentication

Page 79: J2EE Weblogic Documentation

79

In web applications, you will often need to restrict access to parts of your web site. The J2EE specification has 2 basic types of authentication - Declarative and Programmatic.

This lab will examine how to use the Declarative method. In later labs, you will have the opportunity to use a Programmatic method.

In this lab, you will be creating users, a security role and restricting access to the HelloWorld JSP to that user.

Level of Difficulty: 2 (moderately easy) Estimated time: 30 minutes Pre-requisites:

• Completed the JSP Parameters lab exercise • Running the Weblogic server - either through the Eclipse/Workshop IDE or from the

command line

HTTP Basic Authentication

HTTP Basic authentication is the oldest and one of the most commonly used forms of authentication on the web. From a user's perspective, he/she attempts to visit a web page, but before the page is displayed, has to enter a username and password into a popup dialog box of the web browser. After entering correct credentials, the requested page is displayed.

Traditionally, basic authentication of web servers is set up as part of the web server configuration. However with web applications, the authentication can be specified on a per-application basis, by describing the authentication requirements in the application's deployment descriptor (web.xml file).

Three elements are required in the web.xml file: <login-config>, <security-role> and <security-

constraint>. login-config specifies some global parameters for the application, security-role declares the names of users (roles) used by the application, while security-constraint specifies which file(s) should be protected and which users have access.

Finally, the actual creation of the user (username and password) is done within the web application server (e.g. WebLogic) using its management console.

Setting up security roles in WebLogic

In J2EE applications, the descriptor file for the web application (web.xml) will contain the security declarations for the types of groups of users who can access the application.

In this lab, we will create a group called "hellousers". A group is merely a set of users, and maps directly to a role.

1. Open the WebLogic Server Console 2. Click on Lock & Edit in the top left menu. 3. In the left side menu, click Security Realms 4. Choose myrealm 5. Select the Users and Groups tab

Page 80: J2EE Weblogic Documentation

80

6. Select the Groups pane (this is just below the Users and Group line) 7. Create a new group by selecting New

Enter the name hellousers and a short description. Leave the provider as DefaultAuthenticator

8. hellousers should now be in the list of groups.

Creating users in WebLogic

1. At the top of the page, click the Users pane 2. Click New and enter a name such as student, and enter a suitable description and password.

(you must enter the password twice!)

Note that Weblogic enforces a minimum password size. Later on (not NOW!) you can change this in the Securiy Realms -> myrealm -> Providers -> DefaultAuthenticator -> Configuration | Provider Specific -> Minimum Password Length panel.

3. Now select the new user you created. 4. You should then select the Groups tab

You should see several groups here, including hellousers in the Available window.

Select hellousers and press the right-arrow button to move this into the Current Groups window.

Click Save to update this.

5. If you wish, you can add many other users, just ensure that they are also members of the hellousers group if you want them to access the Hello JSP

6. 7. Finish off with Release Configuration in the top left menu

Configuring the hello JSP web application for security

You will need to modify the Deployment Descriptor (ie: web.xml file) to enable security.

You can either update the web.xml file directly in the source editor (note that using Ctrl-space will show you the allowed elements in the current cursor position), or you can use the design tab to let the XML editor assist you. You right mouse button click and add a child element.

Add the following tags into the web.xml file after the </welcome-file-list> tag.

<security-constraint> <web-resource-collection> <web-resource-name>Hello world</web-resource-name> <description>The Hello world application</description> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint>

Page 81: J2EE Weblogic Documentation

81

<description>These users can use hello JSP</description> <role-name>hellousers</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>Hello World Application</realm-name> </login-config> <security-role> <description>Hello JSP users</description> <role-name>hellousers</role-name> </security-role>

What do the parameters mean?

<login-config>

login-config specifies the authentication mechanism and the realm for authentication.

We have used code>BASIC for basic HTTP authentication. The realm refers to the scope of the username and password that are supplied - typically each application will have a different realm so that the credentials supplied for one application are not valid for another. The realm name can be any string of text you choose.

You can only specify login-config once within your web.xml file (i.e. each web application can have at most one login method).

<security-role>

security-role declares the name of a role referenced by this application. It has a purely declarative role.

You can have as many security-role elements as you need - one for each different role your application requires.

<security-constraint>

security-constraint specifies a set of pages to protect within the web application, and which users should be permitted access.

In web-resource-collection you define a url-pattern of the pages you wish to protect. By specifying /*, we have declared that all pages in the Hello World application are protected. /P>

In auth-constraint you define a list of users (or more correctly, roles) who are permitted access. The <role-name> element may occur multiple times if you want multiple roles to have access. Each role name should be declared elsewhere in the same web.xml file in a <security-role> element.

Page 82: J2EE Weblogic Documentation

82

The security-constraint element basically limits access to the specified url-pattern so that only the listed roles (users) have access.

You may have many CODE>security-constraint elements in your web.xml file if you have different parts of your application that need to be accessed by different sets of users.

Map the roles to groups

Weblogic now requires you to map these 'roles' to groups. Previous versions (such as Weblogic 8.1) automatically did this.

For EACH project, update the Weblogic Deployment Descriptor weblogic.xml to do this mapping.

Modify the Weblogic Deployment Descriptor (weblogic.xml) by adding the following elements:

<wls:security-role-assignment> <wls:role-name>hellousers</wls:role-name> <wls:principal-name>hellousers</wls:principal-name> </wls:security-role-assignment>

The <role-name> is the name of the role to be used by your web application

The <principal-name> is the name of the group to which this role will apply to. Note that you can map users to this principal as well. Repeat the whole security-role-assignment block for each role and principal assignment. You can map more than one principal to the same role name.

Note: You can ask weblogic to do this automatically via the weblogic Administration Console. ie:

• Lock&Edit, select Security Realms • On myrealm -> Configuration -> General page -> deselect "Combined Role Mapping

Enabled" • Expand Advanced -> • Check Roles and Policies = "All web applications and EJBs",

When Deploying Web Applications or EJBs = "Initialize roles and policies from DD" • Release Configuration to save • You may need to Stop and Restart weblogic to enable this configuration setting.

Hint: Use the Servers tab at the bottom of the Eclipse screen & select the server & press the red square to stop. Press the Green arrow to start.

Now Weblogic will automatically create the equivalent of the above weblogic.xml descriptor... and you won't need to modify the weblogic.xml descriptor again..

Accessing authentication credentials in servlets/JSP

From within a servlet or JSP, you can determine the username that was used to authenticate by calling the getRemoteUser() method on the HTTPServletRequest object.

Page 83: J2EE Weblogic Documentation

83

In your HelloWorld.jsp file, add the following lines to see who is the current user

<p>The following user is logged in: <% String user = request.getRemoteUser(); if (user == null) { user = "-none-"; } out.println(user); %>

If the web application wasn't protected, then the getRemoteUser() method will return null.

You can also check to see if the user is in a particular role via the isUserInRole()

<% if (request.isUserInRole("hellousers")) { out.println("Is a member of hellousers"); } else { out.println("Is not a member of hellousers"); } %>

Don't forget to repackage your .WAR f file and copy it into the applications directory for redeployment.

Further reading

WebLogic specific security information can be found at http://e-docs.bea.com/wls/docs100/security/thin_client.html#wp1037337

Module: JSP

Lab exercise - Using a JavaBean

Page 84: J2EE Weblogic Documentation

84

So far, all the JSP code you have written has been embedded into the web page itself. If there is a large amount of code, the page can get quite messy, as you might imagine. Also, sometimes you need to reuse the same functionality in different pages.

JSP pages can make use of your own Java class files, as helper classes, if you wish. However the preferred option is for JSP pages to use JavaBeans to encapsulate reusable functionality. A JavaBean is just a "special" Java class. Note that a JavaBean is NOT the same thing as an Enterprise JavaBean. This lab exercise takes you through the process of creating and deploying your own JavaBean, and using it in a JSP page.

Level of Difficulty: 4 (moderately difficult) Estimated time: 45 minutes Pre-requisites:

• Completed the JSP and sessions lab exercise

Why use JavaBeans?

JavaBeans are Java's "client-side" component model. Typical uses of JavaBeans are in creating components for use in GUIs (for example the Swing libraries use JavaBeans as their underlying model). Remember that a component is just a collection of Java classes that presents a single public interface to other objects.

While EJBs need to execute in the context of an application server, client-side JavaBeans can be instantiated and used by any Java application or applet (or servlet, or JSP). Even though JSPs are not generally thought of as a client-side technology, JavaBeans have been adopted as the component model for use in JSPs. As we will see later, JSPs are a form of client in J2EE applications - JSPs are clients of EJBs.

JavaBeans are used in JSPs to avoid having large amounts of code embedded in the web page itself. This increases the potential for code reuse, and provides a good separation of design tasks (performed by a web designer) and programming tasks (performed by a programmer).

What are JavaBeans?

A JavaBean is simply a normal Java class that follows certain design patterns. In this context, a design pattern is a basically a naming convention that you must follow when creating a JavaBean.

Here we will only consider one basic design pattern used in JavaBeans - using getter and setter methods for properties. For more information on more complex design patterns used in JavaBeans, see a JavaBeans tutorial, such as the one from Sun - http://java.sun.com/products/javabeans/docs/javaBeansTutorial-Nov97/javabeans/

Page 85: J2EE Weblogic Documentation

85

Since JavaBeans represent data of some kind it needs to be serializable ie: able to be converted to some portable, transferable format. Therefore, JavaBeans have to implement the serializable interface.

Creating your JavaBean

For this exercise, assume we are going to use a JavaBean to represent a person. The attributes/properties of this person consist of only a name and a favourite colour.

1. The first step is to create a new Java project. Select New -> Project.. -> Java Project. Call this project mybeans

2. The next step is to create a package. You should be familar with packages, but briefly speaking this is simply a way to organise your Java classes (technically packages also influence the scope of variables and method visibility on all classes in a package). A more pragmatic view of a package is that it simply appears like a subdirectory! Recall that there are many packages in Java by default such as java java.util & so on.

So let's create a simple package called myapp. This is basically a subdirectory called myapp !!

Select mybeans, and Right Mouse Button -> New -> Package & enter myapp as the package name. Note that the source folder is actually mybeans. After Finishing our wizard, note that there is a new "myapp" folder.

3. Next, we will create a Java class skeleton to hold our JavaBean. If we Right Mouse Button -> New -> Class, we will be prompted by a wizard to create a new Java Class

Enter myapp for the package name.(or alternatively, click the Browse button and select MyApp - note that there is a (default package) folder which represents "no package" or the top of your Java hierarchy.

Enter a Person as the name of the class and click the Add button in the Interfaces section

You should get a Interfaces selection window. Start typing Serializable (and note the typeahead assist to return Serializable (java.io)) then press OK

4. Now we are going to use the ability of the Eclipse IDE to generate code for us. Modify the generated Java class file as follows (basically we just added the declarations in italics.

package myapp; import java.io.Serializable;

Page 86: J2EE Weblogic Documentation

86

public class Person implements Serializable { private String name; private String favecolour; }

Note that you may get a yellow warning light bulb icon which if you hover your cursor over it mentions that the class does not declare a static final serialVersionUID field. Don't worry about this, we will let Java use the default (which is system generated).

Now let's get Eclipse to generate the getters and setters.

Click on the top menu and choose Source -> Generate getters and setters. (You could also select the two declaration lines above then press Right Mouse Button -> Source -> Generate Getters and setters)

You will get a Generate Getters and Setters wizard appearing. You can select the individual variable to generate code for using the check boxes and if you expand the field names you can see the default methods declarations. Note the other options - Insertion Point and Sort by. These just help you keep your source code nice and tidy. You can also generate a default Method Comment which generates JavaDoc style comments for you. Select All, then OK to finish

Note the careful choice of method names. The methods are in pairs - one getter and one setter method. They are also case-sensitive - the word "get" and "set" must be in lower case, and the next character (the start of the property name) must be in upper case. So for example the methods getName() and setName() together implement a JavaBean property called "name" (in this case, the property name is all lower case - the first uppercase 'N' is converted to lower case when you go to use it as a property). Your code now looks somewhat like this

package myapp; import java.io.Serializable; public class Person implements Serializable { private String name; private String favecolour; public String getFavecolour() { return favecolour; } public void setFavecolour(String favecolour) { this.favecolour = favecolour; } public String getName() { return name; } public void setName(String name) { this.name = name; }

}

Page 87: J2EE Weblogic Documentation

87

While you are getting used to the Source code generation facilities of Eclipse, why not experiment here and try things like Source -> Generate Element Comment, Source -> Format, Source -> Correct Indentation etc?

Congratulations, you now have a JavaBean class

Packaging your JavaBean

A manifest file specifies that this class is in fact a JavaBean. Note that reading the source code of the class, there is nothing special about it that reveals that it is in fact a JavaBean. See http://java.sun.com/docs/books/tutorial/deployment/jar/manifestindex.html for information about the manifest file

We will need to create our own manifest file in order to let Java (and other tools) know that this module is a Java Bean module.

• Select mybeans, right mouse button -> New -> file called manifest. • Add the following contents • Manifest-Version: 1.0

• Name: myapp/Person.class Java-Bean: True

Note that there is a blank line at the end of the file.

We repeat each Name/Java-Bean lines for each Java bean we are declaring in our project.

• Because we would like our JavaBean to be a reusable asset for our project work, we will simply Export the file to a Jar file.

Choose Right Mouse button -> Export -> Java -> JAR

This brings up a wizard to generate a Jar package and the various options to generate a JAR file. For the moment, we will choose to Export java source files - this isn't strictly necessary since sometimes we don't want others to see our source code.

Select a destination file - let's call it mybeans.jar in and place this into some external development directory.

Click next which gives us the packaging options window. Click next to get the Manifest window.

Now choose Use existing manifest from workspace and Browse to the manifest file we created earlier.

• We can manually check the contents of the JAR file by using the following command from a terminal:

Page 88: J2EE Weblogic Documentation

88

• jar tvf mybeans.jar

The table-of-contents should look like the following:

0 Tue Aug 21 00:00:00 EST 2007 META-INF/ 113 Tue Aug 21 00:00:00 EST 2007 META-INF/MANIFEST.MF 552 Tue Aug 21 00:00:00 EST 2007 myapp/Person.class 408 Tue Aug 21 00:00:00 EST 2007 myapp/Person.java

Congratulations, phase one is complete. You have built a JavaBean.

Creating your JSP page

Once the JavaBean has been created, and placed in a JAR file in the WEB-INF/lib directory, creating the JSP file that accesses the JavaBean is easy.

You need to copy the jar file you created earlier into the labs project. Put the file into the WebContent / WEB-INF / lib subdirectory.

Create a JSP file called FaveColour.jsp with the following contents and test it.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <jsp:useBean id="fred" class="myapp.Person" scope="session" /> <jsp:useBean id="jane" class="myapp.Person" scope="page" /> <jsp:setProperty name="fred" property="name" value="Fred Jones" /> <jsp:setProperty name="fred" property="favecolour" value="blue" /> <jsp:setProperty name="jane" property="name" value="Jane Chan" /> <jsp:setProperty name="jane" property="favecolour" value="red" /> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>My Java Bean Test</title> </head> <body> <p>The favourite colour of <jsp:getProperty name="fred" property="name" /> is <jsp:getProperty name="fred" property="favecolour" /> . </p> <p>The favourite colour of <jsp:getProperty name="jane" property="name" /> is <jsp:getProperty name="jane" property="favecolour" /> . </p> </body> </html>

Page 89: J2EE Weblogic Documentation

89

Adding new properties

To test that you have grasped the use of JavaBeans, modify the Person bean and add another property called "emailAddr". Modify your JSP pages accordingly.

Hint: It may be easier to export the Java Bean jar file directly into the labs / WebContent /

WEB-INF / lib directory.

You can also investigate modifying labs to directly access the mybeans project as a utility library (we will talk about this later)

Beans and sessions

Note that in the above JSP code, the "fred" bean was defined with scope "session", while the "jane" bean was defined with scope "page".

The "fred" bean, with all of its stored values, will be automatically stored in the HttpSession object. To retrieve it in another page, you just use the same code, and it will be automatically retrieved from the session, complete with its previously set values.

<jsp:useBean id="fred" class="myapp.Person" scope="session" />

To test the persistence of beans across sessions, make a second copy of the JSP file you created above. Now in the copy, delete all of the "setProperty" actions.

To test, first access the original JSP file (the one with the "setProperty" actions). Then access the second JSP file (the one without the "setProperty" actions). What do you notice?

Page 90: J2EE Weblogic Documentation

90

Module: JSP

Lab exercise - Using Struts

Level of Difficulty: 4 (moderately difficult) Estimated time: 30 minutes Pre-requisites:

• Completed the Javabean lab exercise

Adding support for Struts

Workshop for Weblogic (unlike Standard Eclipse WTP) has some support for Struts. Do to this, you need to add the "Struts" 1.2 facet to your project.

• Right Mouse Button click on your project, then press Properties • You should see a property called "Project Facets" - note that this has Dynamic Web Module

2.4, JSTL 1.1 and Java 5 (plus maybe others) • Click on Add/Remove Project Facets and check Struts. Ensure that version 1.2 is listed.

The main change to your application is that there is now a shared library called "Weblogic J2EE library [Struts 1.2] in the Labs -> Java Resources -> Libraries folder on your project. This also enables some support for the Struts configuration and validation xml files and tag libraries.

You now need to modify your web.xml to support struts. To do this you need to edit your Deployment Descriptor (web.xml) by adding the following tags:

<servlet> <servlet-name>Struts Action Servlet</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>

and

<servlet-mapping> <servlet-name>Struts Action Servlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

in the appropriate spots in your deployment descriptor, web.xml. (sample exists in /pub/aip/struts/lab/WEB-INF/web.inc )

Page 91: J2EE Weblogic Documentation

91

Our Lab example

We are going to create a simple application that records a persons name and favourite colour, much like the servlet and JSP labs. However, we will use several struts features to show you how to create a simple MVC application using Struts.

Basically we will only have a few 'states' at first - the welcome page (index.jsp), the list Persons page (listPerson.jsp), the Add person page (createPerson.jsp) and finally a reset state (which demonstrates a state with no actually JSP, we re-use the index page).

To transition between these 'states', we will use the following actions (which translate mostly to a URL consisting of /action.do

index

Action Action Class Comments JSP file if

successful

index

This has links to the 3 main actions of this

application, and also

displays messages to the user.

/index.jsp

listPerson ListPersonAction.java Checks if there a 'people' attribute in the /listPerson.jsp

Page 92: J2EE Weblogic Documentation

92

session, if not, sets an error

createPerson

This is a 'forward' which invokes the

createPerson.jsp, which displays

the input form. The submit action is

addPerson.do.

Note that when we add validation, this form

will be re-invoked if validation

fails.

/addPerson.do

addPerson AddPersonAction.java

This is called by the createPerson.jsp form

when the "submit"

button is pressed. It then creates the Person

bean and stores it in the

"database"

/index.jsp

resetPerson ResetPersonAction.java

This bean just deletes the 'person' attribute

from the session

& leaves a message for the main page.

/index.jsp

Struts Configuration

The next step is to create a Struts configuration file to match the above configuration.

We have set up a struts example in the /pub/aip/struts/lab directory.

• Import into WebContent\WEB-INF: WEB-INF\struts-config.xml • import into WebContent: index.jsp, createPerson.jsp and listPerson.jsp • import into Java Resources\src: src\* (this includes myapp.* classes &

ApplicationResources.properties

Try it and see how it works

Struts layout

Take a look at the files in this directory. Note that this Struts application doesn't have standardised messages and has no error checking and validations.

You can find the java source in the src directory.

Take special note of the ApplicationResource.properties file - this contains the strings which our struts application uses.

The struts configuration files can be found in the WEB-INF directory.

Modifying struts

Page 93: J2EE Weblogic Documentation

93

Your job is to create some validation rules that make name and color required. For hints, look at the /pub/aip/struts/lab.answers directory. Note that we created a validation.xml file! Note that validation-rules.xml comes with the default Struts configuration, you don't need to modify this!

We also have a copy of the Eclipse/Workshop projects for each step to take: struts1 is the same as the lab, struts2 has basic validation, struts3 has validation with Javascript.

Steps to take

First step: Change WEB-INF/struts-config.xml

Change references of org.apache.struts.action.DynaActionForm to org.apache.struts.validator.DynaValidatorForm (This subclass of DynaActionForm handles validation via the /WEB-INF/validation.xml and validation-rules.xml files)

Add validate="true" to <action path="/addPerson"

Add the validator plugin ie:

<!-- plugins --> <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> </plug-in>

2nd Step: Edit createPerson.java

• change import of DynaActionForm to import org.apache.struts.validator.DynaValidatorForm; • change cast from (DynaActionForm) to (DynaValidatorForm) near line 37

You can check the steps by comparing the directory /pub/aip/struts/struts1 and /pub/aip/struts/struts2

Optional Step: Add error highlighting to CreatePerson.jsp

• add the attribute errorStyle="background-color: red" to the <html:text elements.

Build & Test this

Optional Step: Add Cancel button to CreatePerson.jsp

This allows us to cancel even if we fail validation (since this can get you into a loop!)

• Add <html:cancel> to CreatePerson.jsp (just after the <html:reset>) • Add the following to the <action path="/addPerson" element in struts-config.xml

<set-property property="cancellable" value="true"/> <forward name="cancelled" path="/index.jsp"/>

Optional Step: Add Javascript validation

Page 94: J2EE Weblogic Documentation

94

• Simply add <html:javascript formName="personForm" dynamicJavascript="true" /> to createPerson.jsp

• Add onsubmit="return validatePersonForm(this);" to the <html:form element

You can also see that we have 2 versions of the createPerson.jsp file in the lab.answers. createPerson_no_javascript.jsp doesn't have javascript validation and will highlight the error field in red.

More tasks

How about change the color selection to be a drop down menu? Radio buttons? Selection list? Use the appropriate Struts tag instead of the HTML one

One neat trick Struts provides is the ability to dynamically generate Selection/Menu/Radio buttons from a java Collection class. See the Struts reference on how to do this.

References

Weblogic 10 has Apache Struts 1.2.9 support built in. You can read the reference guide at: http://struts.apache.org/1.2.9/

Module: JDBC

Lab exercise - Oracle Familiarisation - command line version

Page 95: J2EE Weblogic Documentation

95

In this module, we will be writing Java programs that connect to a database server, issue queries, and update information. Before looking at the Java syntax, it is useful to take a moment to become familiar with the Oracle database server we will mostly be using. Some basic knowledge of databases is assumed, however no detailed technical knowledge is expected as the queries we will be performing are very basic.

Level of Difficulty: 1 (easy) Estimated time: 15 minutes Pre-requisites:

• None

Setting up your Oracle account

The faculty provides an Oracle database server on a machine called smaug.it.uts.edu.au. In order to administer this database, you will need to modify your profile to include certain environment variables and will need to update your default PATH with the oracle database code

Add the following to the end of your .bashrc file.

# oracle setup export ORACLE_HOME=/opt/Oracle10g-client export PATH=$PATH:/opt/Oracle10g-client/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/Oracle10g-client/lib

You should have been provided with an Oracle userid. If not, ask your tutor for the id and password.

Your default oracle database (also called SID) is called ell

This means the JDBC URL will be jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell

Creating an SQL command file

Each person will have an Oracle database account set up which will contain your own database tables, separate to everyone else's. However initially, your Oracle account will be blank, so the first task is to create a test table.

When working with Oracle, we will be using a command-line interface that Oracle calls SQL*Plus. In this command-line interface, you can enter SQL statements to create tables, insert data, and issue queries. However if you have a complex sequence of SQL commands to enter, it is best to create a command file, with the sequence of commands. Command files are also useful if you later want to delete your data and recreate your tables in their "initial" state.

A command file is just a plain text file containing SQL commands. You create and edit it using a normal text editor.

Page 96: J2EE Weblogic Documentation

96

Create a text file called addressbook.sql using a text editor, and enter the following contents. Substitute your own data if you prefer.

DROP TABLE addressbook; CREATE TABLE addressbook ( name VARCHAR(30) PRIMARY KEY, address VARCHAR(50), email VARCHAR(50), extn DECIMAL(4,0), birthday DATE ); -- note that dates are strings normally in the yyyy-mm-dd -- formats for SQL92 eg:mysql, pointbase etc -- oracle only accepts dd-mon-yyyy format, you need to use the non-standard -- TO_DATE() function to convert other date strings to Oracle format -- However, Oracle JDBC driver does accept the JDBC escape format eg: -- {d 'yyyy-mm-dd'} INSERT INTO addressbook VALUES ('chris','CB10.04.226', '[email protected]', 7938, '01-jan-2001' ); -- Note: we use the Oracle specific TO_DATE(string, format) function INSERT INTO addressbook VALUES ('Maolin','CB10.04.260', '[email protected]', 7858, TO_DATE('30.12.1990','DD.MM.YYYY')); INSERT INTO addressbook VALUES ('Wayne','CB10.04.230', '[email protected]', 7991, TO_DATE('04/29/1992','MM/DD/YYYY')); SELECT * FROM addressbook;

Points to note:

• Oracle SQL commands are not case sensitive. Case only matters when you are entering literal strings (between quotes).

• When you first enter Oracle's command-line mode, by default it does not actually save any of your changes until you exit. This is often not a good thing. By using the "set autocommit on" command, it forces Oracle to save your changes after each command. You should always set autocommit on, unless you are experienced with Oracle and wish to do manual commits.

• Single quotes must be used around strings, not double. • Comments start with two dashes (--). You can also use C-style comments. You should

not mix comments in with your SQL statements. Each single SQL command should be uninterrupted, and the comments can be placed between SQL commands.

• VARCHAR is a string data type which can contain a VARiable number of CHARacters, up to the specified maximum.

• DECIMAL is a data type for representing numbers, both with and without fractions. In this case we want a fixed-point number with four digits before the decimal point (integer part), and zero digits after the decimal point (fraction part). If you were

Page 97: J2EE Weblogic Documentation

97

storing monetary values, you might choose a data type of DECIMAL(8,2) for example, allowing for 2 digits of precision after the decimal point.

• Oracle has a non-standard representation of DATE, which only accepts strings in the format of 'DD-MON-YYYY' where MON is a 3 character string representing the month eg: JAN = January. You can use the Oracle-only TO_DATE() function to convert from a string in many date formats using a format string such as 'YYYY-MM-DD'.

Starting SQL*Plus

The next step is to enter Oracle's command-line interface and run your command file.

The version of Oracle installed at the faculty provides 2 main user interfaces

• A command-line client called sqlplus which can access the faculty Oracle database server from your workstation

• A web based client called iSQL*Plus. This can be found at http://smaug.it.uts.edu.au:7777/isqlplus Note that you need to enter ell for the Connection Identifier if you use the iSQL*Plus web page

We will use the command line version for this lab.

1. Logon to your workstation. If you have just edited your .bashrc with the Oracle

variables, you will need to close the terminal and restart it to ensure that the

variables are set. 2. Change directory to the directory in which you saved your SQL command file created

above. 3. At your Unix shell prompt, run the SQL*Plus command as follows. Please note that

you should use the Oracle username and password that you were assigned.

The faculty provides an alias that allows you to remotely access the Oracle server, smaug.it.uts.edu.au. This is called ell_smaug. To use this, we pass a parameter to the sqlplus command that looks like userid@ell_smaug (where userid is your ORACLE userid).

workstation:~$ sqlplus userid@ell_smaug SQL*Plus: Release 9.2.0.1.0 - Production on Mon Mar 29 17:10:28 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Enter password: xxxxxx Connected to: Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options JServer Release 9.2.0.1.0 - Production SQL>

Page 98: J2EE Weblogic Documentation

98

Your prompt has now changed to SQL>. You are no longer at your Unix shell, but are in Oracle's command-line database interface. All the commands you type at this prompt should be SQL or Oracle-specific commands.

Running your SQL command file

From the SQL*Plus prompt, type the following command, which instructs Oracle to load and execute the contents of your command file.

start addressbook.sql;

Running ad-hoc SQL queries and SQL*Plus commands

While in the SQL*Plus environment, you can also run arbitrary SQL queries and other valid SQL*Plus commands. Try the following commands, at the SQL*Plus prompt. Note that each command ends with a semi-colon. If you forget the semi-colon, SQL*Plus will go into multi-line editing mode. This is okay, just enter a semi-colon and press enter to finish the command.

select * from addressbook; describe addressbook; select table_name from user_tables; drop table addressbook; start addressbook.sql;

Quick SQL*Plus Tutorial

There is also a quick SQL*Plus tutorial which summarises the few commands you will need to use Oracle in this subject.

Feel free to experiment until you are comfortable with SQL*Plus.

Changing your password

You can change your password by typing the following SQL command from within sqlplus:

password

If you use the web interface, use the Preferences > Change Password menu instead

Page 99: J2EE Weblogic Documentation

99

Disconnecting from SQL*Plus

When you are ready to leave SQL*Plus, use the quit command. If you are making changes to the database regularly, you might like to keep a window with SQL*Plus open in the background.

SQL> quit Disconnected from Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options JServer Release 9.2.0.1.0 - Production

Oracle Tools

You can also use a browser based version of Sqlplus via http://smaug.it.uts.edu.au:7777/isqlplus Conveniently, this works remotely from home via a normal browser!

Oracle Documentation

There is some Oracle documentation available online. This can be found at http://www.oracle.com/pls/db92/db92.homepage

Module: JDBC

Page 100: J2EE Weblogic Documentation

100

Lab exercise - Oracle Familiarisation - Workshop for Weblogic version

In this module, we will be writing Java programs that connect to a database server, issue queries, and update information. Before looking at the Java syntax, it is useful to take a moment to become familiar with the Oracle database server we will mostly be using. Some basic knowledge of databases is assumed, however no detailed technical knowledge is expected as the queries we will be performing are very basic.

Level of Difficulty: 1 (easy) Estimated time: 15 minutes Pre-requisites:

• None

Setting up your Oracle account

The faculty provides an Oracle database server on a machine called smaug.it.uts.edu.au. In order to administer this database, you will need to modify your profile to include certain environment variables and will need to update your default PATH with the oracle database code

Add the following to the end of your .bashrc file.

# oracle setup export ORACLE_HOME=/opt/Oracle10g-client export PATH=$PATH:/opt/Oracle10g-client/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/Oracle10g-client/lib

You should have been provided with an Oracle userid. If not, ask your tutor for the id and password.

Your default oracle database (also called SID) is called ell

This means the JDBC URL will be jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell

Setting up your Workshop project

You will need to add the Oracle JDBC jar file into your project build classpath. To do this, you need to Right Mouse Button -> Properties and select Java Build Path. (Alternative: Right Mouse Button -> Build Path -> Add external Archives )

Choose the Libraries tab and Select Add External Jars. Browse to /opt/bea10/wlserver_10.0/server/lib and select ojdbc14.jar

Creating an SQLpage file

Page 101: J2EE Weblogic Documentation

101

Each person will have an Oracle database account set up which will contain your own database tables, separate to everyone else's. However initially, your Oracle account will be blank, so the first task is to create a test table.

Eclipse/Workshop for Weblogic provides an editor for creating SQL scripts. Later versions have content assists and wizards, but the version currently installed does not provide this feature.

You can create the SQL files in your project by using the Right Mouse Button -> New ->

Other -> Data -> SQL scrapbook page

Let's create one called addressbook.sqlpage using the following text.

DROP TABLE addressbook; CREATE TABLE addressbook ( name VARCHAR(30) PRIMARY KEY, address VARCHAR(50), email VARCHAR(50), extn DECIMAL(4,0), birthday DATE ); -- note that dates are strings normally in the yyyy-mm-dd -- formats for SQL92 eg:mysql, pointbase etc -- oracle only accepts dd-mon-yyyy format, you need to use the non-standard -- TO_DATE() function to convert other date strings to Oracle format -- However, Oracle JDBC driver does accept the JDBC escape format eg: -- {d 'yyyy-mm-dd'} INSERT INTO addressbook VALUES ('chris','CB10.04.226', '[email protected]', 7938, '01-jan-2001' ); -- Note: we use the Oracle specific TO_DATE(string, format) function INSERT INTO addressbook VALUES ('Maolin','CB10.04.260', '[email protected]', 7858, TO_DATE('30.12.1990','DD.MM.YYYY')); INSERT INTO addressbook VALUES ('Wayne','CB10.04.230', '[email protected]', 7991, TO_DATE('04/29/1992','MM/DD/YYYY')); SELECT * FROM addressbook;

Points to note:

• Oracle SQL commands are not case sensitive. Case only matters when you are entering literal strings (between quotes).

• Single quotes must be used around strings, not double. • Comments start with two dashes (--). You can also use C-style comments in one line

/* */. You should not mix comments in with your SQL statements. Each single SQL command should be uninterrupted, and the comments can be placed between SQL commands.

Page 102: J2EE Weblogic Documentation

102

• VARCHAR is a string data type which can contain a VARiable number of CHARacters, up to the specified maximum.

• DECIMAL is a data type for representing numbers, both with and without fractions. In this case we want a fixed-point number with four digits before the decimal point (integer part), and zero digits after the decimal point (fraction part). If you were storing monetary values, you might choose a data type of DECIMAL(8,2) for example, allowing for 2 digits of precision after the decimal point.

• Oracle has a non-standard representation of DATE, which only accepts strings in the format of 'DD-MON-YYYY' where MON is a 3 character string representing the month eg: JAN = January. You can use the Oracle-only TO_DATE() function to convert from a string in many date formats using a format string such as 'YYYY-MM-DD'.

Creating a Database Connection

The next step is to run the SQL page. You can do this via the Right Mouse Button -> Run

SQL command. This should open up a Select Connection wizard.

• Select Create New Connection • Choose a database manager - in this case, choose Oracle -> 10. You then add the

following connection details: o JDBC Driver: Other o Database: ell o JDBC Driver Class: oracle.jdbc.driver.OracleDriver o Class location: /opt/bea10/wlserver_10.0/server/lib/ojdbc14.jar o Connection URL: jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell o Enter your oracle userid and password in the User Information box o You can then Test Connection to check your details. Press Next to continue o The database connection wizard can filter out different schemas from the

database connection - since the oracle server contains possibly hundreds of students entries, you should choose to narrow this list down to your own schemas. On the Filter wizard, Select Expression and Name "starts with the

characters". In the entry field, enter your Oracle userid in UPPER CASE.

(unfortunately, this is case sensitive). o Press Finish to complete.

You should then see a Data Output window appear in the lower pane. Note that there now is a Database Explorer view appearing too (If not, you can select Window -> View ->

Database Explorer from the main menubar)

Note that for each command that was executed, you will get a status line and SQL Editor box showing relevant messages & results.

You can clear this by pressing Right Mouse Button -> Delete All to clear the results.

You can also follow the above setup sequence to create new connections from the Database Explorer view by Right Mouse Button click on the Connections icon.

Running your SQL command file

Page 103: J2EE Weblogic Documentation

103

Any time you are in an SQL Scrapbook page you can test an individual SQL statement by highlighting (selecting) the relevant SQL statement and then using the Right Mouse Button -> Run SQL command

Note that only valid SQL commands will work here. Do not use SQL*PLUS commands here (such as set autocommit on, password, describe addressbook etc).

Exploring your Database

The Database Explorer allows you explore your database. If you select the Database Explorer view, notice that there is a + symbol alongside the ell connection? Expand this and you should see ell -> + Schemas (Filtered).

If you don't see the +, then you probably have an incorrect filter (Choose Right Mouse Button -> Filter, then correct the filter - normally this should be an UPPER CASE userid. You can optionally turn off filters by selecting the Disable Filter checkbox).

Expanding this further you will see + tables, then your addressbook table.

The neat feature of Database Explorer is that you can drill down in further details (such as column definitions, indexes etc).

If you select table (eg: ADDRESSBOOK) and pressing Right Mouse Button -> Data you can:

• Edit the table in a spreadsheet - this lets you view, update, add, delete rows in the table

• Load - load data from text files (eg: CSV files) • Extract - save data to a text file

Try adding, updating and deleting records from the addressbook table.

Page 104: J2EE Weblogic Documentation

104

Finally, save the data by Extract'ing the records to a text file.

Disconnecting

When you wish to disconnect from the database, switch to the Database Explorer window and select the connection (this will be called ell by default). Press Right Mouse Button -> Disconnect

Page 105: J2EE Weblogic Documentation

105

Module: JDBC

Lab exercise - Hello World JDBC

JDBC is the Java API for accessing databases. Eventually we will use JDBC for connecting the business logic parts of our application to the necessary databases. But first we begin at the beginning - with a Hello World example. This exercise is to create a simple command-line application that connects to a database.

Level of Difficulty: 1 (easy) Estimated time: 20 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Completed the Oracle familiarisation lab exercise

A HelloWorld JDBC application

Because we are creating a standalone application, you do not need a WAR file, and we will not be installing it into the application server. It also does not really matter which directory you create this program in.

Create the following Java class & change the oracle_userid oracle_password to your

Oracle userid and password!!

import java.sql.*; public class HelloWorldJDBC { private static final String dbdriver = "oracle.jdbc.driver.OracleDriver"; private static final String dburl = "jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell"; private static final String dbuser = "oracle_userid"; // change to your id private static final String dbpass = "oracle_password"; public static void main (String [] args) { try { // Load the driver and create connection Class.forName(dbdriver); Connection conn = DriverManager.getConnection(dburl, dbuser, dbpass); // Create a statement and execute the query Statement stmt = conn.createStatement(); stmt.executeQuery("select * from addressbook"); // Get the result set

Page 106: J2EE Weblogic Documentation

106

ResultSet rs = stmt.getResultSet(); // Loop through and print out the values while (rs.next()) { System.out.print(rs.getString(1) + ","); System.out.print(rs.getString(2) + ","); System.out.print(rs.getString(3) + ","); System.out.print(rs.getLong(4) + ","); System.out.println(rs.getString(5)); } // now release the connection. conn.close(); } catch (Exception e) { // If anything goes wrong, print the Exception message e.printStackTrace(); } } }

To connect to the database, two essential pieces of information are required (other than the username and password):

• JDBC driver class - the name of a Java class that knows how to communicate with the particular kind of database you are connecting to. You will need to specify a different driver class for each kind of database you wish to connect to.

• JDBC URL - a URL that specifies which database to connect to. JDBC URLs always start with the protocol "jdbc:", but the format of the remainder of the URL differs depending on the kind of database you are connecting to (i.e. each driver class has its own URL format).

In the case of Oracle, the URL includes the driver type ("thin"), the hostname ("smaug.it.uts.edu.au"), the port number ("1522") and the database name ("ell").

Running in Workshop

First you have to load the Oracle JDBC library. To do this, select the project, Right Mouse

Button -> Build Path -> Add External Archives then navigate to /opt/bea10/wlserver_10.0/server/lib and select ojdbc14.jar (in Windows: c:\bea\wlserver_10.0\server\lib)

Note: You should pick the appropriate database driver jar file if you are using another database eg: mysql-comnector-java-commercial-5.0.3.jar for mysql

To test your application, click Right Mouse Button -> Run As -> Java Application

The output should appear in the Console.

Running from the Command Prompt

Page 107: J2EE Weblogic Documentation

107

To test your application, compile it using javac (hint: did you remember to run wlenv to set your classpath?) and then run it using the command-line Java interpreter:

java HelloWorldJDBC

Notes

Note that hardcoding the JDBC URL, userid and password is not good practice to follow. You would be better off storing these as seperately as parameter files.

Module: JDBC

Page 108: J2EE Weblogic Documentation

108

Lab exercise - JDBC in a JavaBean

This exercise demonstrates one way of using a JavaBean for data access. In this example, we use a JavaBean to issue arbitrary SQL commands on a database. The JavaBean is quite generic - however it does have the database details hard-coded!!! (don't do this in real life :-).

Level of Difficulty: 2 (moderately easy) Estimated time: 20 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Completed the Hello World JDBC lab exercise

JDBC in a JavaBean

This time we are creating a JavaBean. We will also create a small program to test the JavaBean before we try and use it in a JSP. This is an example of unit testing, which is currently seen as a good software engineering approach.

Create the following Java class. This is the JavaBean.

package myapp; import java.sql.*; import java.util.*; // All JavaBeans must be Serializable public class OracleBean implements java.io.Serializable { private static final String dbDriver = "oracle.jdbc.driver.OracleDriver"; private static final String dbURL = "jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell"; /* Defining the attributes. Notice that they are all declared private. They cannot (and must not) be accessed directly from other objects, or it would violate the JavaBean rules. */ private String dbUser; private String dbPass; private Connection conn; public void connect() throws ClassNotFoundException, SQLException { if (dbUser != null) { Properties props = new Properties(); props.setProperty("user", dbUser); props.setProperty("password", dbPass); Class.forName(dbDriver);

Page 109: J2EE Weblogic Documentation

109

this.conn = DriverManager.getConnection(dbURL, props); } } public void close() throws SQLException { this.conn.close(); } public ResultSet query(String sql) throws SQLException { Statement s = conn.createStatement(); return (s.executeQuery(sql)); } public int update(String sql) throws SQLException { Statement s = conn.createStatement(); return (s.executeUpdate(sql)); } /* get/set the dbUser property */ public String getDbUser() { return this.dbUser; } public void setDbUser(String dbUser) { this.dbUser = dbUser; } /* get/set the dbPass property */ public String getDbPass() { return this.dbPass; } public void setDbPass(String dbPass) { this.dbPass = dbPass; } }

Notice that this JavaBean has two properties: dbUser and dbPass. These must be set at runtime before calling the connect() method.

A unit test for the JDBC JavaBean

Now we need to unit test the JavaBean.

Add the following main() method to your JavaBean. Vary the SQL query if you wish, to see different results. You can also test updating by using the o.Update() method. Now you can test the bean by using Right Mouse Button -> Run As -> Java Application

public static void main (String [] args) throws ClassNotFoundException, SQLException { OracleBean o = new OracleBean(); o.setDbUser("oracle_userid"); o.setDbPass("oracle_password"); o.connect(); ResultSet r = o.query("SELECT * FROM addressbook"); while (r.next()) { System.out.print(r.getString(1) + ","); System.out.print(r.getString(2) + ","); System.out.print(r.getString(3) + ",");

Page 110: J2EE Weblogic Documentation

110

System.out.print(r.getLong(4) + ","); System.out.println(r.getString(5)); } }

Module: JDBC

Page 111: J2EE Weblogic Documentation

111

Lab exercise - JDBC in a JavaBean in a JSP

Now that you have a JavaBean created to connect to the database, you can use it inside your JSP.

Level of Difficulty: 2 (moderately easy) Estimated time: 20 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Completed the JDBC in a JavaBean lab exercise

Adding JSP

Now that you have a JavaBean, it is time to use it in a JSP. Below is a starting point for a JSP.

<%@ page language="java" contentType="text/html" import="java.sql.*, myapp.*" %> <jsp:useBean id="mydb" class="myapp.OracleBean" scope="request" /> <%! ResultSet rs = null; %> <jsp:setProperty name="mydb" property="dbUser" value="oracle_userid" /> <jsp:setProperty name="mydb" property="dbPass" value="oracle_password" /> <HTML> <HEAD> <TITLE>My JDBC JavaBean Test</TITLE> </HEAD> <BODY> <% mydb.connect(); rs = mydb.query("SELECT * FROM addressbook"); while (rs.next()) { %> <P> <%= rs.getString("name") %> <%= rs.getString("address") %> <%= rs.getString("email") %> <%= rs.getLong("extn") %> <%= rs.getString("birthday") %> </P> <% } %> <% mydb.close(); %> </BODY> </HTML>

Page 112: J2EE Weblogic Documentation

112

Notice how the majority of the database code is removed from the JSP and placed in the JavaBean. The JSP should really only be printing out information from the JavaBean. In this case we are using a JSP Model 1 architecture (no central controller), therefore the JSP itself does contain some business logic (setting the properties on the bean, and also the SQL query).

Improving formatting

Notice that the database output in the above example is not well formatted.

Use a HTML table to display the data.

Better Solution

Note that we have still hard-coded references to Oracle and JDBC in the bean

A better solution could be to hide the implementation even further by using the Data Access Object pattern.

To do this, you need to create a Interface with common "CRUD" access methods such as create, read, update, delete and find. This should deal with a JavaBean that represents the object you are working with.

In our case, we can update the Person object from earlier labs by adding address details (such as address, email, extn and birthday).

We then create a PersonDAO class which has the following methods.

void createPerson( Person) Person readPerson(String name) // since primarykey is name. Could also pass a Person object with name as key // this effectively does select * from addressbook where name = 'name' Person updatePerson(Person) // this would do update addressbook set .. where name = Person.name // note that we might have to put special processing for changing name void deletePerson(Person) // this would do delete from addressbook where name = Person.name // alternatively, could pass the name since this is the primary key Collection<Person> findAll() // does a select * from addressbook Collection<Person> findByName() // does a select where name=name - note that this is the same as readPerson() This PersonDAO will use the OracleBean to query and update the database.

We then change the JSP to use this PersonDAO bean. We then call PersonDAO. findAll() to get the collection.

The best thing about this is that you can use Expression Language eg: ${person.name} and also use the EL automatic understanding of Collection classes.

Try creating PersonDAO and Person and changing this JSP.

Page 113: J2EE Weblogic Documentation

113

Module: JDBC

Lab exercise - Connection Pools and Data Sources

Establishing database connections is a very time consuming part of an application. Typically the database runs on a different server, so there is network delay added on top of the time it takes for the connection to be set up. One way to improve performance of applications that use databases is to use connection pooling. This is described more below.

Level of Difficulty: 4 (moderately difficult) Estimated time: 40 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Completed the JDBC in a JavaBean in a JSP lab exercise

JDBC Connection Pools

The basic concept is that because establishing database connections takes so much time, applications that use databases can be made more efficient by preventing them from having to establish a new database connection each time they run. Instead, the idea is to have a pool of connections pre-established so that when the application runs, it can reuse one of the existing connections.

The pool of pre-existing connections is provided by the container in which the application executes. In our case, the connection pool will be provided by the web application server. When an application (servlet/JSP, and later EJB) needs to connect to a database, it asks the container to give it one of the pooled connections.

Connection Pools provide an efficient way to reuse database connections. However they do not make it easy to dynamically reconfigure where a particular application should get its data from. In an effort to isolate the database details from the application even further, JDBC uses the concept of a Data Source.

When your application wishes to connect to a database, it will ask the application server for a data source. Inside the application server, each data source is mapped to a particular connection pool. To change which database an application retrieves its data from means only changing the data source configuration in the application server - no source code changes are required.

This is best practice - you SHOULD use data sources in your production code.

Setting up a Connection Pool & Data Source in WebLogic

Because the connection pool & data source is managed by the container, you need to configure it in the container, not in your application. To set up a connection pool & data source in WebLogic, you need to use the web-based management console.

Page 114: J2EE Weblogic Documentation

114

In the management console, use the menu on the left to locate "Services", then "JDBC" and then "Data Sources".

Lock & Edit , then select "New" on the "Data Sources (filtered)" table.

Fill in the following details:

1. JDBC Data Source properties: o Name = thinOracleDataSource o JNDI name: thinOracleDataSource o Database type = Oracle o Database driver: *Oracle's Driver (thin)

Note: Use the pull down menu to get the list of drivers to use. Note: Do not use the "*BEA's Oracle Driver .."!

o [NEXT] o (leave defaults) o [NEXT]

2. Transaction Options o Database name: ell o Hostname = smaug.it.uts.edu.au o Port = 1522 o Enter your Oracle Database user name & password

Note that this is the same information you needed inside your earlier JDBC code examples. But now instead of putting it in your Java source code, you are configuring it declaratively within the application server.

o [NEXT] 3. Connection Properties 4. Test Database Connection

o You can now test this connection via the [Test Configuration] button Note that webLogic has generated the following settings:

Driver Classname = oracle.jdbc.driver.OracleDriver & URL = jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell

o [NEXT] o Choose AdminServer & click [Finish] to create the JDBC data source. o Initial Capacity = 1 o Maximum Capacity = 2 o Capacity Increment = 1

This tab is used for performance tuning. You can adjust the number of pooled connections, etc, to suit the size of your application, and capacity of your database.

o Click "[Save]" o Activate changes o Click on the [Activate Changes] on the top left menu to make the changes active o Usually you don't need to restart the server. However, read the green message

response to check if you do need to restart weblogic or not. 5. Customising the connection settings

o You can now select the thinOracleDataSource from the Data Sources table.

Page 115: J2EE Weblogic Documentation

115

o Choose the Configuration - Connection Pool tab & set the following defaults:

When your server restarts, watch the messages in the shell window where you start it running. If there is an error in connecting to the database, it will show up as a Java exception in this window.

Verifying your Connection Pool and Data Source

You should have already verified your connection pool is working when you restarted your server. If there were JDBC error messages when the server was starting, then it means your connection pool is not properly setup.

To verify your data source, in the management console, use the menu to go to "Servers", then "AdminServer". Choose the link to "View JNDI tree". You should see your data source name appear in the resulting web page. If your data source name does not appear, then there is a problem with the setup of your data source (or connection pool). JNDI will be explained separately.

The exercise

Now that the JDBC Data Source is available, you can use it from within your Java code.

The goal of the exercise is to modify the JavaBean you created earlier to use the JDBC data source to establish the connection.

package myapp; import java.sql.*; import javax.sql.*;

import javax.naming.*; import java.util.*; // All JavaBeans must be Serializable public class DataSourceBean implements java.io.Serializable { private String dbDataSource; private Connection conn; public void connect() throws ClassNotFoundException, SQLException, NamingException { Context ctx = new InitialContext();

// Lookup using JNDI name.

DataSource ds = (DataSource) ctx.lookup(dbDataSource);

conn = ds.getConnection(); } public void close() throws SQLException { conn.close(); }

Page 116: J2EE Weblogic Documentation

116

public ResultSet query(String sql) throws SQLException { Statement s = conn.createStatement(); return (s.executeQuery(sql)); } public int update(String sql) throws SQLException { Statement s = conn.createStatement(); return (s.executeUpdate(sql)); } /* get/set the dbDataSource property */

public String getDbDataSource() { return this.dbDataSource; }

public void setDbDataSource(String dbDataSource) {

this.dbDataSource = dbDataSource;

} }

Notice now how all the database connection details (JDBC driver name, JDBC URL, username, password) are removed from the Java code, because they are managed by the application server. This also means that this bean is now completely database independent. The same Java code can be used regardless of whether the database used is Oracle, Informix, Ingres, etc.

When this JavaBean executes, it will ask the application server to provide a DataSource, and the application server will allocate one of the available database connections to this JavaBean for as long as it needs it. When the JavaBean closes the connection, the connection is returned to the pool and available for other applications.

Testing your new bean

To test your new bean, you will need to modify your JSP code to reflect the properties of the new bean. This is left up to you.

Page 117: J2EE Weblogic Documentation

117

Module: JDBC

Tutorial - Using other databases with Weblogic 10

JDBC is a generic API that can be used for accessing any kind of database given the appropriate drivers. The lab exercises in this module are written to use Oracle. This is a brief explanation of how to convert the examples from using Oracle to using other JDBC databases

Weblogic 10 comes with some preinstalled commerical JDBC drivers. See http://edocs.bea.com/wls/docs100/jdbc_admin/third_party_drivers.html for a definitive list and how to use them.

Weblogic 10 also has a "universal" driver (called "Type 4 JDBC Drivers", also known as the BEA drivers) which were written by Merant for BEA. See http://edocs.bea.com/wls/docs100/jdbc_drivers/jdbcsupt.html for how to use them

You can also use other databases if they have a JDBC driver written for them. See http://cayenne.apache.org/doc/database-support.html for a pretty good list of vendor JDBC drivers.

Here is brief table of what drivers are installed by default. Note that these are already in the pre-defined Weblogic classpath so you don't have to specifically add these jar file into your classpath when running your WAR or EJB file.

However, do note that Workshop for Weblogic/Eclipse WTP does not automatically add these files to your project build path properties. You can find most of these files in the /opt/bea10/wlserver_10.0/server/lib directory.

Driver

Name Jar file Class Name URL

Oracle

10g

(Thin

client

Driver)

ojdbc14.jar oracle.jdbc.OracleDriver jdbc:oracle:thin:@server:1521:db

Sybase

jConne

ct 4.5,

5.5,

and 6.0

jConnect.jar

, jconn2.jar,

jconn3.jar

com.sybase.jdbc.SybDriver

com.sybase.jdbc2.jdbc.SybD

river

com.sybase.jdbc3.jdbc.SybD

river

jdbc:sybase:Tds:server:port/db

MySQ

L 5.0.x

mysql-

connector-

java-

commercial

-5.0.x-

com.mysql.jdbc.Driver

org.gjt.mm.mysql.Driver jdbc:mysql://server:port/db

Page 118: J2EE Weblogic Documentation

118

bin.jar

Pointba

se 5.1

pbclient51.j

ar

pbembedde

d51.jar

com.pointbase.jdbc.jdbcUni

versalDriver

jdbc:pointbase:server://server:port/db

jdbc:pointbase:embedded:db

Weblo

gic

type 4

drivers:

IBM

DB2

8.2/9.1,

Informi

x, MS

SQL

server

2000/2

005,

Oracle

9g,

10g,

Sybase

12.5/15

.1

wlbase.jar,

wlutil.jar - -

wldb2.jar weblogic.jdbc.db2.DB2Driv

er jdbc:bea:db2://server:port;DatabaseName=db

wlinformix.

jar weblogic.jdbc.informix.InformixDriver

jdbc:bea:informix://server:port;informixServer=s

erver;databaseName=db

wlsqlserver.

jar

weblogic.jdbc.sqlserver.SQL

ServerDriver jdbc:bea:sqlserver://server\\instance

wloracle.jar weblogic.jdbc.oracle.Oracle

Driver jdbc:bea:oracle://server:port;SID=db

wlsybase.jar weblogic.jdbc.sybase.Sybase

Driver jdbc:bea:sybase://dbserver:port;SID=db

JDBC

ODBC

bridge

Built into

Java 1.4 &

later

versions.

sun.jdbc.odbc.JdbcOdbcDriv

er jdbc:odbc:odbc-dsn-name

If you want to use the following databases (and corresponding JDBC drivers), you need to download them and place them into your classpath.

Derby

derbyclient.

jar

org.apache.derby.jdbc.Client

Driver

org.apache.derby.jdbc.Embe

ddedDriver

jdbc:derby://server:port/db

Sqlite

sqlitejdbc.ja

r org.sqlite.JDBC

jdbc:sqlite:/path/to/database.db

jdbc:sqlite://path/to/database.db

Page 119: J2EE Weblogic Documentation

119

sqlite.jar SQLite.JDBCDriver jdbc:sqlite:/:memory:

PostGr

es

postgresql-

8.3*.jdbc3.j

ar

org.postgresql.Driver jdbc:postgresql://server:port/db

Step 1 - (Optional) Making WebLogic load the JDBC driver

Do this step ONLY if WebLogic does not have an existing JDBC driver (eg: for Apache Derby)

Assuming you have downloaded the appropriate database client code and JDBC driver, your next step is to place the JDBC driver (normally a JAR file) into the Weblogic classpath.

You can do this in three ways.

• Option 1: copy the driver into the default Java classpath (ie: the JRE_HOME/lib/ext ie: /opt/bea10/jrockit_150_06/jre/lib/ext ). This is NOT RECOMMENDED because this is not portable and often you will not have root/administrator access to change these directories anyway.

• Option 2: Copy the jar files into the WEB-INF/lib directory (or into your EAR). This is portable, but during development you will still need to place the JAR file into your classpath.

• Option 3: You can change the default Weblogic setup in your domain to include the JAR file into the default classpath (assuming you have set up the wlenv alias). To do this:

• Edit your $DOMAIN_HOME/bin/setDomainEnv.sh and add the line: EXT_PRE_CLASSPATH=path/to/driver.jar

(where $DOMAIN_HOME is your domain directory eg: ~/weblogic, and path/to/driver.jar is the path to the JDBC JAR file)

• Add this just after the WL_HOME= line. (Windows version: edit setDomainEnv.cmd and add SET EXT_PRE_CLASSPATH=path\to\driver.jar )

• This is safer than editing the startWeblogic.sh command directly.

Step 2 - changing the parameters

Now that WebLogic can load the JDBC driver, you need to be able to change the code examples to refer to the new database driver rather than Oracle. You need to change any occurrence of the driver class and the matching URL. For example, for MySql, make the following changes:

• JDBC driver class oracle.jdbc.driver.OracleDriver --> eg: Mysql: com.mysql.jdbc.Driver

Page 120: J2EE Weblogic Documentation

120

• JDBC URL Oracle: jdbc:oracle:thin:@smaug.it.uts.edu.au:1522:ell --> eg: Mysql: jdbc:mysql://localhost/mydb

Step 3 - change Oracle specific SQL

• change any Oracle specific SQL (eg date formatting) to SQL92 formats. IF you used the recommended JDBC escape sequence for dates eg: { d '2001-12-30'} instead of the Oracle date format eg: '30-dec-2001', then you need to make no changes.

Module: JDBC

Tutorial - ODBC example

Page 121: J2EE Weblogic Documentation

121

Microsoft Windows provides a universal interface to database & database-like services under windows called ODBC. For example, there are ODBC drivers for Microsoft Access, Excel spreadsheets, SQL Server and so on. There is a unix equivalent (unixODBC) on linux and solaris (and other unixes as well).

Java 1.4 upwards provides JDBC driver called the Sun JDBC-ODBC bridge. This driver is provided in the default rt.jar library.

Driver class: sun.jdbc.odbc.JdbcOdbcDriver

URL format: jdbc:odbc:odbc-dsn-name

where odbc-dsn-name is the name of an existing ODBC Data Source Name (DSN) on the local computer. This syntax will vary depending on the ODBC provider. Our example will use Microsoft Access.

IMPORTANT NOTE: This driver is not thread-safe and should not be used in production. Weblogic 10 does not allow you to use this driver for EJB's (though it will work for servlets and JSP's)

For more details, read on ...

Creating an ODBC DSN

Windows ODBC works on the concept of data sources. Each data source has a name, called the DSN or Data Source Name. Before you can access a database via ODBC, it should have a DSN set up for it. Each DSN refers to one particular database that can be accessed via ODBC.

Let's assume you want to allow your servlets/JSPs to connect to a Microsoft Access database. ODBC data sources can connect to a variety of underlying file types including Access, Excel and plain text files.

Here are the steps:

1. Create your database. Open up Microsoft Access with a blank database, create one table with a few columns, and add a couple of rows of data.

2. Open up the ODBC Control Panel: o Windows 2000/XP: "Start" menu -> "Settings" -> "Control Panel" ->

"Administrative Tools" -> "Data Sources (ODBC)" 3. Move to the "System DSN" tab and click the "Add" button. 4. Choose the "Microsoft Access Driver (*.mdb)". 5. Enter a name for the DSN. It can be any name you choose, but should start with a

letter and for simplicity should only contain alphanumeric characters. The DSN name should somehow relate to the database name or its contents. Optionally enter a description as well if you wish.

6. Under the word "Database", click on the "Select" button and locate the Microsoft Access database (.mdb file) you created earlier.

7. Click "OK" in all the windows and your new DSN is created.

Page 122: J2EE Weblogic Documentation

122

Accessing the ODBC DSN from a Java program

The key lines of Java code that differ between databases are loading the appropriate JDBC driver, and specifying the database URL.

For accessing an ODBC DSN, the following are the two key lines:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); ... conn = DriverManager.getConnection("jdbc:odbc:mydsn");

where you replace mydsn by the name of the ODBC DSN for your database.

Here is some example code you can download and try. It assumes you have a DSN actually called "mydsn" and that in your database there is a table called "test".

Use your right-mouse button to save these to a local file.

• odbctest.java A simple command-line application to test JDBC-ODBC.

• ODBCServlet.java A servlet which connects to an ODBC data source.

• odbctest.war A WAR file containing a (mostly) generic database access servlet and the appropriate web.xml init-param's for it to connect to an ODBC data source. To extract individual files, use the command: jar xvf odbctest.war

Module: JDBC

Tutorial - Oracle SQL*Plus

Page 123: J2EE Weblogic Documentation

123

For working with an Oracle database, it is often convenient to use Oracle's command-line interface to the database. This is the Oracle-specific program called SQL*Plus.

For the definitive SQL*Plus guide, see:

• Oracle documentation at http://dragon.it.uts.edu.au:9700/iplus/help/us/toc.htm

Running SQL*Plus

1. Log in to the Oracle database server. This is a Unix machine called dragon.it.uts.edu.au. Connect with either ssh or telnet (ssh preferable). Use your regular Faculty login and password (Unix login). You will be placed in your Unix home directory (same as charlie/sally, and your X: drive on PCs).

2. Run the SQL*Plus program: 3. sqlplus

4. Enter your Oracle username and password. This is not the same as your Unix login. 5. You will now be at the SQL*Plus prompt. Here you can enter SQL statements, and SQL*Plus

commands.

Useful SQL*Plus commands

Firstly, note that generally, commands in SQL*Plus should be terminated by a semi-colon (;).

Secondly, if you press Enter in the middle of a command, Oracle will prompt you to enter another line that is part of the same command - you can spread a command over multiple lines. The command will be executed when you type a semi-colon. Each time you press Enter, Oracle will prompt you by showing you the current line number that you are entering.

Using command files

Rather than typing complex commands directly into the SQL*Plus interface, create a file containing the commands, and then run the command file in SQL*Plus. This also means if the database data is lost for any reason, you can easily restore it to your chosen "initial" state.

Example:

start mycommandfile.sql;

or:

@ mycommandfile.sql;

You can include comments in your command file either using C-style comments /* ... */ or comments starting with two dashes (--). The C-style comments must be placed on a line of their own and not inside any block of SQL.

Page 124: J2EE Weblogic Documentation

124

SQL*Plus also includes commands for saving the current edit buffer (SAVE) to a file and loading a file into the current edit buffer (GET).

Committing changes

In SQL*Plus, the default behaviour is not to commit changes to the database until you explicitly request it. Until changes are committed, they are not visible to other users (including JDBC accesses).

There are two commands that may help:

commit;

will commit changes manually. Or:

set autocommit on;

will change the autocommit behaviour for the current SQL*Plus session so that changes are automatically committed after each SQL command.

Examining table structures

The DESCRIBE command can show the structure of a table, e.g.

describe mytable1;

Running Unix commands

To run a Unix command from within the SQL*Plus interface, just prefix the command with the keyword HOST, e.g.

host ls host pico mycommandfile.sql host vi mycommandfile.sql

Running SQL commands

In general, you will want to run SQL commands in SQL*Plus (preferably from a command file).

If you need SQL help, here is a quick SQL refresher with lots of examples.

Module: JDBC

Page 125: J2EE Weblogic Documentation

125

Tutorial - Quick SQL Refresher

The examples shown below are based on the Oracle dialect of SQL. Other databases use slightly different syntax in some places (usually the available data types, and built-in functions).

For the definitive Oracle SQL reference, see:

• Oracle documentation http://www.oracle.com/pls/db92/db92.homepage

SQL SELECT statement

Basic queries

General format:

SELECT column-list|* FROM table-name-list WHERE condition-list ORDER BY column-list;

Firstly, here is how to retrieve all data from a table:

SELECT * FROM mytable;

You can retrieve specific columns (but all rows) from a table:

SELECT mycol1, mycol2 FROM mytable;

WHERE clause

You can limit which rows are returned according to some criteria:

SELECT * FROM mytable WHERE mycol1 > 100;

Here is an example that limits with several conditions:

SELECT * FROM mytable

Page 126: J2EE Weblogic Documentation

126

WHERE mycol1 > 100 AND mycol2 = 'hello world' AND mycol3 IS NOT NULL;

Note that the phrases "IS NULL" and "IS NOT NULL" are special ways to check if a particular column contains a NULL value, as distinct from having an empty value (e.g. the empty string "")

Also note that single quotes are used around strings in SQL, and a single equals sign is used to test equality.

LIKE operator

You can use the LIKE operator to do pattern matching. Within a pattern, you can use an underscore (_) to match exactly one character, and a percent sign (%) to match zero or more characters. For example:

SELECT * FROM mytable WHERE mycol1 LIKE 'SM_TH%';

This pattern will match SMITH, SMYTH, SMITHSON, SMYTHE, etc. Any single character can be placed between the M and T, and zero or more characters may follow the H.

Built-in Functions

You can apply an aggregate function to a column - e.g. counting the number of rows:

SELECT COUNT(*) FROM mytable WHERE mycol1 > 100;

Here is a different function - maximum value in a column. There are lots of functions available.

SELECT MAX(mycol1) FROM mytable;

Sorting

You can sort the result by a particular column:

Page 127: J2EE Weblogic Documentation

127

SELECT mycol1, mycol2 FROM mytable ORDER BY mycol2;

Here is more complex sorting. Sort by "mycol2" in descending order followed by "mycol1" in ascending order (the default):

SELECT mycol1, mycol2 FROM mytable ORDER BY mycol2 DESCENDING, mycol1;

Joining tables

If you want a single query to retrieve data that is in multiple tables, you can join the tables. To join two tables you list both table names in the FROM clause, and you include (at least) one join condition in the WHERE clause. A standard join condition should specify that a column in one table equals a different column in another table.

For example, consider the following example tables and SQL query.

Table: PERSON

PersonID Surname Firstname

1 Brookes Wayne

2 Johnson Chris

Table: ORDERS

OrderID PersonID OrderValue

1 2 $99.99

SELECT person.surname, orders.ordervalue FROM person, orders WHERE orders.personid = person.personid;

This query would return one row, with the values "Johnson", "$99.99".

Note that the join condition is used to specify on which column the two tables should be joined.

Page 128: J2EE Weblogic Documentation

128

Subqueries

Sometimes you want to test membership in a set of values. For example, using the example tables above, you might want a list of the names of all customers who have placed an order:

SELECT surname, firstname FROM person WHERE personid IN ( SELECT personid FROM orders );

The subquery is the one in parentheses. You can negate the condition if you want to see a list of all customers who have not placed an order. Note that the subquery stays the same, just the IN operator becomes NOT IN:

SELECT surname, firstname FROM person WHERE personid NOT IN ( SELECT personid FROM orders );

The subquery should return only one column of data.

SQL CREATE/DROP statements

Basic table creation

General format:

CREATE TABLE table-name ( col-name-1 data-type-1, col-name-2 data-type-2, col-name-3 data-type-3 );

For example:

Page 129: J2EE Weblogic Documentation

129

CREATE TABLE mytable1 ( mycol1 VARCHAR(20), mycol2 NUMBER(4,2), mycol3 DATE );

If a column is not allowed to contain NULL values, you can specify that it should be NOT

NULL. If the data in a column must be guaranteed to uniquely identify rows within the table, you can declare it as a PRIMARY KEY. For example:

CREATE TABLE mytable1 ( name VARCHAR(20) PRIMARY KEY, height NUMBER(4,2), dateofbirth DATE NOT NULL );

To remove a table definition, and all the data in it, use the DROP statement. Note: you will receive no warning, and no second chance!

DROP TABLE mytable1;

SQL INSERT/DELETE statements

The INSERT/DELETE statements are for adding and deleting rows in an existing table.

Inserting rows

General format:

INSERT INTO table-name VALUES ( col-1-value, col-2-value, col-3-value );

An example:

INSERT INTO table-name VALUES (

Page 130: J2EE Weblogic Documentation

130

'Wayne', 123, TO_DATE('2001-01-01', 'YYYY-MM-DD'), NULL );

Notes on data types:

• Strings are enclosed in single quotes • Numbers are not enclosed by any characters • Dates need to be converted from strings into the DATE type using the Oracle TO_DATE()

function • A null value for a column can be specified with the keyword NULL (no quotes)

Deleting rows

The syntax of the SQL DELETE statement is quite similar to the SELECT statement, except no column-list is used.

You can delete all data in a table as follows:

DELETE FROM mytable1;

You can selectively delete rows by adding a WHERE clause, with the same syntax as for a SELECT, e.g.:

DELETE FROM mytable1 WHERE mycol1 LIKE '%ayn%';

SQL UPDATE statements

The SQL UPDATE statement is for updating existing data within a table.

General format:

UPDATE table-name SET column-name = value WHERE condition-list;

Here's a simple example - update the orders table and set every row to have the OrderValue set to 10.

Page 131: J2EE Weblogic Documentation

131

UPDATE orders SET ordervalue = 10;

The next example only updates certain rows in the table - not all of them. To do this, a WHERE clause is used, with the same syntax as for an SQL SELECT.

UPDATE orders SET ordervalue = 10 WHERE personid > 99;

You can update multiple columns at once if you need to, e.g.:

UPDATE orders SET ordervalue = 10, personid = 0 WHERE personid > 99;

Module: RMI

Lab exercise - RMI client/server application

Page 132: J2EE Weblogic Documentation

132

This lab exercise shows you how to create a simple RMI application in a non-J2EE context.

Level of Difficulty: 1 (easy) Estimated time: 45 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly

Overview of RMI

RMI is Java's Remote Method Invocation. It allows objects in different Java Virtual Machines to communicate, by allowing one object to invoke a method on another object that is remotely located. Typically these objects are executing on different machines, but not necessarily. RMI is Java's implementation of Remote Procedure Call (RPC), a well-established computing paradigm for building distributed applications.

RMI is a client/server protocol. In a J2EE setting, RMI may be used in a number of places:

• a servlet calling a method on an EJB • one EJB calling a method on another EJB • a (non-web) Java client calling a method on an EJB

This exercise demonstrates none of these. While RMI can be (and is) used in J2EE applications, it can also be used by non-J2EE applications that wish to communicate. For now, we will use "pure" RMI, not in a J2EE context.

Development Process

Because RMI uses a client/server architecture, you need to create both a client program and a server program. Because there are many steps in developing a pure RMI application, it is important to follow the correct sequence of steps, as outlined below.

1. Define the remote interface. The "remote interface" is where you decide what kind of service(s) your server is going to offer to its clients. The remote interface is a Java interface that defines a set of method signatures that the server will implement, and that the clients can call. The remote interface is shared by both clients and the server.

2. Implement the RMI server. This is a Java class that implements all the methods you defined in your remote interface. This is where you write the code for what the server is going to do.

3. Generate RMI skeletons and stubs. RMI has a special pre-processor that will automatically generate some of the low-level communications code for you. The autogenerated code is called stubs (for the client's part) and skeletons (for the server's part).

4. Implement an RMI server registration class. The class you created above when you implemented the RMI server only implements the

Page 133: J2EE Weblogic Documentation

133

business logic methods. You also need a class to actually make your server run (i.e. one you can execute from the command line - with a main() method). This is the server registration.

5. Implement an RMI client. The final step is to implement a client class that will connect to your server.

Creating a simple RMI application

Step 1 - Define the remote interface

The remote interface is a Java interface declaration, containing a list of methods (signature only) that you want your clients to be able to invoke.

Create and compile the following Java source file.

/** The remote interface - both the client and the server share a common view of this interface. */ import java.rmi.*; public interface HelloWorld extends Remote { String sayit() throws RemoteException; }

Points to notice:

• Clients will only be able to invoke one method on the server - the method is called sayit(), and it takes no arguments and returns a String.

• The interface extends Remote (java.rmi.Remote). All remote interfaces must do this. • The method declares that it may throw a RemoteException. All methods in a remote

interface must declare this. A RemoteException may be thrown by the underlying infrastructure if anything goes wrong with the communication between the client and server.

• Although it is not clearly shown here, both the parameters and the return type of remote methods must be Java classes that implement the java.io.Serializable interface.

Step 2 - Implement the remote methods

This is the server-side class that implements the remote interface. It must provide public method implementations for all methods defined in the remote interface. The server class may define other methods, but only the ones listed in the remote interface can be invoked over the network by clients.

Page 134: J2EE Weblogic Documentation

134

Create and compile the following Java source file.

/** Class that implements the RMI server */ import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class HelloWorldImpl extends UnicastRemoteObject implements HelloWorld { // Implementation must have an explicit constructor // in order to declare the RemoteException exception public HelloWorldImpl() throws RemoteException { super(); } // Method implementation public String sayit() throws RemoteException { System.out.println("Got another request - returning result!"); return ("Hello World!"); } }

Points to notice:

• The class name has "Impl" appended to its name to indicate that this is the server implementation. This is a commonly used naming convention.

• The class extends UnicastRemoteObject. This is standard for a server that you will start up manually from the command-line (as opposed to one that is started automatically on demand, which is slightly more complex).

• The class implements HelloWorld. i.e. it implements the remote interface, which implies all of the Java semantics associated with the "implements" keyword.

• We must declare a default constructor (i.e. one with no arguments) even if you don't need to do anything special, because the constructor method must declare the possibility of throwing a RemoteException. An RemoteException might be thrown by the underlying RMI support library, not by your code itself.

• In the implementation of our remote method - sayit() - we do two things. The System.out.println statement will cause the server to print a message in its window (on the server machine). The return statement will return a String message back to the client's machine.

Step 3 - Generate the RMI skeletons and stubs

After you have compiled both the remote interface and the implementation class, you can use a tool to automatically generate some of the low-level code that deals with network communication. These are called stubs (client-side) and skeletons (server-side).

Page 135: J2EE Weblogic Documentation

135

From the command prompt, run the following command from the build directory ie: where the compiled classes are located.

rmic HelloWorldImpl

rmic stands for "RMI compiler". Notice that you specify the name of the implementation class (without any file extension).

After running this command, you will notice some extra files have been generated.

Note that the build directory in the Eclipse workshop lab is in the project/build/classes

Step 4 - Write an RMI server registration class

Notice that in the implementation class above, there is no main() method. So how do you run it? The answer is that you don't.

The next task is to create a Java class whose purpose is to start the server running. When you go to run your RMI server, it is this class that you execute.

Create and compile the following Java source file.

/** This is the server registration class. It has a main method (command-line application) and creates a server instance and registers it with the RMI registry. */ import java.rmi.Naming; public class HelloWorldServer { public static void main (String [] args) { try { // create instance of remote object System.out.println("Creating instance of server object ..."); HelloWorld hw = new HelloWorldImpl(); // bind remote object to naming service System.out.println("Registering object with the RMI registry ..."); Naming.rebind("rmi://localhost:1099/HelloWorldService", hw); System.out.println("Registered!"); } catch (Exception e) { e.printStackTrace(); } } }

Points to notice:

• The registration class as a main() method. It is a Java application.

Page 136: J2EE Weblogic Documentation

136

• It creates an instance of the server implementation class (called "hw"). • It registers the instance ("hw") with a name service, and assigns it a human-readable

name ("HelloWorldService").

So far we haven't mentioned a name service. The idea is that when a client starts executing, it needs to know how to find where the server is. One way would be to hard-code the server's location into the client's code, but this is not very flexible. You could have the client read the server's location out of a configuration file, but this is not very dynamic (if the server moves to a different machine, someone has to update the configuration file).

A name service maps from simple, text-based, human-readable names into Java remote object references (i.e. a reference to a Java object running on a remote server). When a server starts executing, it advertises itself on the name service. When a client starts up, it queries the name service to find out where the server is. This way the client only has to know how to contact the name service, and from there it can find all different kinds of servers.

• Exceptions must be handled (try...catch). When you call Naming.rebind(), a number of different exceptions may be thrown - MalformedURLException, RemoteException, AccessException. In this example, we catch all of them at once and just print out a message. Obviously in a real application you would want some better error handling!

Step 5 - Implement an RMI client

Finally, it's time to implement the client application. This could be a GUI client, but to keep it simple, we will just use a command-line client application.

Create and compile the following Java source file.

/** The RMI client which looks up the object in the name server, retrieves a reference and invokes the sayit() method. */ import java.rmi.Naming; public class HelloWorldClient { public static void main (String [] args) { try { System.out.println("Looking up service in RMI registry ..."); HelloWorld hw_obj = (HelloWorld) Naming.lookup( "rmi://localhost:1099/HelloWorldService"); System.out.println("Calling remote method ..."); String hw_text = hw_obj.sayit(); System.out.println(hw_text); } catch (Exception e) {

Page 137: J2EE Weblogic Documentation

137

e.printStackTrace(); } } }

Points to note:

• When we do a lookup operation on the name service, we pass in a human-readable name (disguised as part of a URL), and what we get back is a Java object reference that we can store in a variable (hw_obj).

• The type of hw_obj is HelloWorld - i.e. the remote interface. The remote interface contains information that is shared by both the server and client.

• We can then call the sayit() method on the hw_obj object. Notice that it looks just like a local method call.

• Exceptions must be handled in the client application as well. In particular, if something goes wrong with the communication, the client may have to handle a RemoteException.

Running the HelloWorld example

As well as needing to run the RMI client and the RMI server, you also need to execute the name service - the "RMI registry". The registry needs to be run first, then the server, and finally the client.

Running the RMI registry

The RMI registry is a simple name service that comes supplied with the J2SE SDK.

Rmiregistry MUST be able to locate the interface and implementation and stub/skeleton class files. This means that you should either modify your CLASSPATH to include the compiled classes directory and/or change the current directory to the classes directory.

(You may have to also add . into your classpath for this to work)

Assuming your CLASSPATH is set correctly, you can run it by typing:

rmiregistry &

rmiregistry will listen at port 1099. You can change this by specifying the port number as an argument to rmiregistry.

Note that you can only run ONE copy of rmiregistry per port. This is why setting the CLASSPATH is a better solution.

Running your server

Remember that you run the server registration class, not the server implementation class.

Page 138: J2EE Weblogic Documentation

138

Run the server registration class:

java HelloWorldServer

Running your client

In this example, we will run the client and server on the same machine for simplicity. However they will be running in separate Java Virtual Machines, which is the key point.

Open a new window, set your environment correctly, and run the client:

java HelloWorldClient

True distribution

In theory, you can run the RMI registry, the server and the client all on different machines. However, note the following:

• Both the server registration and the client have the hostname of the RMI registry hard-coded. If you run the registry on a different machine, you need to adjust the code to the new location.

• The server needs access to the Java classes for the remote interface, the server implementation class, the server registration class and the auto-generated skeleton classes.

• The client needs access to the Java classes for the remote interface, the client implementation class and the auto-generated stub classes.

• The RMI registry needs access to the Java class for the remote interface.

Next step ...

Now that you have followed a step-by-step walkthrough, the next step is to be a bit more independent.

Modify the example above to include a new remote method that will add together two integers (i.e. it takes two integer arguments, and returns an integer result).

This will involve changing the remote interface, and then re-running all the subsequent steps.

Page 139: J2EE Weblogic Documentation

139

Module: JNDI

Lab exercise - overview

The laboratory exercise for this module is to query an LDAP server and display a set of attributes from a directory.

Level of Difficulty: 1 (easy) Estimated time: 20 minutes Pre-requisites:

• none

Page 140: J2EE Weblogic Documentation

140

About LDAP and directory structures

Basically Lightweight Directory Access Protocol (LDAP) is a generic method of accessing directory style information eg: address books but can be used for other purposes too, such as Microsoft Active Directory manages all shared objects and security information in a Microsoft Domain.

An LDAP-style directory is a hierarchical tree of objects, where the root of the tree normally is what's called a "Base DN" (Base Distinguished Name)

Each entry in the tree:

• Is an instance of one or more ObjectClasses (such as Person) • Has some attributes. Each attribute has a name and a data type (eg: string, number etc) • Has a unique identifier called a Distinguished Name (dn). Often this is a concatenation of

attributes such as uid (userid), organisation etc.

All of these ObjectClasses and Attributes are defined in a schema. Luckily there are standards which define some standards for directories such as X.500 compatible address books (which the vast majority of LDAP servers support).

Be aware that an LDAP server can manage many independent tree's, each with different Base DN's.

Security and LDAP

LDAP directories are also often used for Authentication. UTS uses a common single signon for email, library access, workstation access etc.

To do this you need to 'bind' to the directory server with your userid and password. We can't do this in our lab since this access is restricted but normally you would pass your own "distinguished name" and password to LDAP to authenticate your password.

By default, we will use 'anonymous' access.

Accessing an LDAP Directory from the command line

We don't have any LDAP searching tools on the Linux workstations, so you will need to logon to charlie for this exercise

You can search for a person using the UTS staff directory. To do this, we will use the following command

ldapsearch -h host -p port -b base_dn -s scope filter attributes

The parameters are:

host the hostname of the LDAP server

Page 141: J2EE Weblogic Documentation

141

port the TCPIP port - defaults to 389

base_dn

the "top of the tree" ie: where to start the search from. You must have this option, there is

no default.

The UTS staff directory base_dn is: o=UTS

scope

one of: base, one, sub. Base means only at the top level, one means only 1 level down to

search, sub means all subcontexts ("subdirectories"). You can leave this out since this

defaults to sub

filter

This is the search string. It should meet RFC2254 syntax. eg:

(cn=christopher wong) would search for the "Common Name"="christopher wong"

(sn-=wong) would search for "Surname"=wong

(sn=*wong*) would search for "Surname" containing "wong"

The valid operators are:

= equal >= bigger than (including alphabetic order eg: c > b) <= less than ~= approximately equal (soundex search so sn~=wong would also return wang, wing, etc)

You can have logical "and" "or" and "not" filters by prefixing these criteria with a & | ! character. eg:

(& (sn=wong)(givenName=christopher) ) --> returns all christoper wong's (| (sn=wong)(sn=brookes)) --> returns all wong's & brookes's (& (sn=wong) (! (givenName=christopher) ) ) --> returns all wong's except those whose given names is christopher

The hard part is getting the bracketing correct....

attributes

This is a list of what attributes to return. The default is to return all.

rfc2256 has a huge list of what attributes are available. Common ones to use are: cn (common name), dn (distinguished name ie: primary key), sn (surname), givenName, initials, title, description, o (organisation), ou (organisation unit), objectClass, c (country code), street, telephoneNumber

Example search

ldapsearch -h ldap.uts.edu.au -b o=UTS '(sn=wong)'

Try do a search for a person by "Common Name" ie: the cn attribute. See if you can find your tutor's name in it.

Page 142: J2EE Weblogic Documentation

142

How about restrict the attributes to just sn, givenName, telephoneNumber, mail ?

A good tutorial about LDAP can be found at http://edutechwiki.unige.ch/en/LDAP and Introduction to LDAP (SAGE) http://quark.humbug.org.au/publications/ldap/ldap_tut.html

Module: JNDI

Lab exercise - LDAP programming

The laboratory exercise for this module is to query an LDAP server and display a set of attributes from a directory.

Level of Difficulty: 1 (easy) Estimated time: 45 minutes Pre-requisites:

• LDAP Overview lab

Page 143: J2EE Weblogic Documentation

143

• Run 'wlenv' to set your environment correctly

An example first

The following Java source code is for a complete JNDI application that queries the main UTS LDAP server (which holds details of all UTS staff). It is a standalone Java application to be compiled and run from the command line.

Try it out. Compile it for yourself and run it by typing:

java JNDITest brookes

Then study the source code to understand how it works. Use this as a basis for the exercise below. (note: to do this under eclipse, you need to run the class with a parameter ie: Use Run As -> Run. Then select JNDITest as the Main Class, and on the (x=) Arguments tab, enter the Program Argument as brookes)

Source code:

• JNDITest.java

Accessing an LDAP Directory from a web application

Write a set of web application components (JSPs and/or servlets) that allow the user to display all the LDAP attributes for a person in the LDAP directory shown below. The user should be able to search based on the person's name ("cn" attribute).

To do this, you should create a DirContext and then perform a search operation on it.

The LDAP directory to use is shown below:

Host name: ldap.uts.edu.au

Port: 389

Base DN: o=UTS

No username or password is required (anonymous login).

Page 144: J2EE Weblogic Documentation

144

Module: JNDI

Tutorial - Looking up Weblogic LDAP

Weblogic has an embedded LDAP server which provides 2 services

1. A naming services for objects such as data sources and EJB's 2. A directory service for the security domains, such as the default admin userid

Viewing internal LDAP objects

• Go to the Weblogic console: • Choose Environment -> servers & select AdminServer • Click on the "View JNDI Tree"

This will pop up a new window showing the existing JNDI objects. Notice that your thinOracleDataSource should appear here.

Clicking on this would result in viewing the details such as the Binding Name (thinOracleDataSource), the actual class name (something like weblogic.jdbc.common.internal.rmiDataSource) and a ToString representation

The neat thing about LDAP and JNDI is that you can bind any serializable Java object to the directory, so in theory, you could bind stuff like java.lang.String 's into the directory & so on.

Setting up Weblogic LDAP for external access

Normally Weblogic is setup not to allow external access to the embedded LDAP directory server - there is a randomly generated bind password and anonymous bind is turned off.

We will change this to allow anonymous access.

• To allow this, go into the weblogic console, Lock & Edit

Page 145: J2EE Weblogic Documentation

145

• Go to Domain (ie: weblogic) -> Security tab -> Embedded LDAP. • In the Credential field, enter a new admin password (eg: weblogic) & confirm • Also select Anonymous Bind Allowed ** (not recommended for security reasons) • You will have to restart the Weblogic server to update these changes

See managing the Embedded LDAP server (http://edocs.beasys.com/wls/docs100/secmanage/ldap.html) for information

Using the Weblogic Embedded LDAP directory server

Now you can use the weblogic embedded LDAP directory to view users in myrealm

The parameters you need to use for LDAP are:

• hostname: your weblogic server (if you are running this from charlie, you need to know your workstation host name)

• port: 7001 • base dn: dc=domain (where domain is your weblogic domain). In our labs this is:

dc=weblogic • bind DN: cn=Admin (this is the -D option on ldapsearch) • password: weblogic (you get prompted for this in ldapsearch. You could use the -w

option to hard code this)

eg:

ldapsearch -h workstation.it.uts.edu.au -p 7001 -D cn=Admin -w weblogic -b dc=weblogic (cn=weblogic)

would return details about the user called weblogic

You could also use the same information when you write JNDI Java programs.

Just set the JNDI environment hashes Context.SECURITY_PRINCIPAL to "cn=Admin" & Context.SECURITY_CREDENTIALS to "weblogic" (or whatever your password is)

If you are using a jndi.properties file to hold this, the property keys are:

java.naming.security.principal=cn=Admin java.naming.security.credentials=weblogic

Page 146: J2EE Weblogic Documentation

146

Module: EJB

Lab exercise - Stateless Session Bean - Manual technique

In this lab exercise, we create your first Enterprise JavaBean. It will be a stateless session bean.

Level of Difficulty: 2 (moderately easy) Estimated time: 60 minutes Pre-requisites:

• Run wlenv to set your environment correctly • Start your WebLogic server running in the background

Overview of EJB

Page 147: J2EE Weblogic Documentation

147

Enterprise JavaBeans implement the business logic of a J2EE application. Each EJB, or "bean", is a component, i.e. it is treated as a single, logical entity that presents a public interface defining its methods that can be accessed.

EJBs are deployed into an application server (in this context, also known as an "EJB container"). In our case, this is WebLogic. Note that WebLogic contains both a web server (for servlets/JSPs) and an application server (for EJBs). Logically they are separate, even though they are implemented in the same product. An application server contains a collection of EJBs. The application server provides a lot of support for the EJBs that it hosts.

There are different kinds of EJBs. These are discussed in more detail in the lecture, but for now suffice to say that in this exercise we will be creating an EJB Session Bean. A session bean is a transient kind of EJB that is created when a client requests it, and is destroyed when the client is finished (i.e. it lasts for one "session"). To be more specific, we will be creating a Stateless Session Bean, which means that during a single session with a client, the bean does not maintain any internal state information.

The basic model of a stateless session bean is that it is a component with a set of public business-logic methods, and the methods are all independent of each other. One method should not rely upon any other method having previously been called.

In this example, the client of our EJB will be a servlet (the presentation tier calling methods on the business-logic tier).

Development Process

Just as there were many steps in developing an RMI application, there are also many steps in developing and deploying an EJB. It is important to follow the correct sequence of steps, as outlined below.

1. Create the Remote interface. The "Remote interface" is where you decide what kind of service(s) your EJB is going to offer to its clients. The remote interface is a Java interface that defines a set of method signatures that the EJB will implement, and that the clients can call. The remote interface defines your business logic methods. The remote interface is shared by both clients and the EJB implementation.

2. Create the Home interface. We have already seen the Remote interface which contains business logic methods. The "Home interface" of an EJB session bean contains methods for creating a new instance of the bean. Clients first obtain a reference to a bean's home interface, and from the home interface, can create one or more instances of the bean itself.

3. Create the EJB implementation class. Naturally you need to create a Java class which provides the implementation of your business-logic methods (and some others, as we will see).

4. Write the EJB deployment descriptor. Recall how web applications (in a WAR file) required an XML deployment descriptor? EJBs also require a deployment descriptor, that provides instructions to the EJB container as to how the EJB should be deployed.

Page 148: J2EE Weblogic Documentation

148

5. Package the EJB into a JAR file. Web applications are packaged in WAR files. EJBs are packaged in JAR files. They are basically the same concept.

6. Generate stubs and skeletons. Next we use an "EJB compiler" tool that will take the JAR file created in the previous step, and will generate stubs and skeletons for the EJB, and will also compile all the Java source code. The EJB compiler will also check the syntax of your XML deployment descriptor. This is quite similar to running "rmic" (the RMI compiler) to generate stubs and skeletons when creating pure RMI applications, except now it is a different tool.

7. Deploy the EJB into an application server. The JAR file containing your EJB must be deployed before it can be invoked, in the same way as WAR files must be deployed before your servlets/JSPs can be invoked.

8. Create an EJB client - a servlet. You cannot directly run your EJB and see results immediately. First you need to create a client program that will invoke the business-logic methods on the EJB, and display some results. In this exercise, we will create a servlet as our EJB client, but note that the client could be a servlet, a JSP, a standalone Java application, or even another EJB.

9. Copy EJB stubs + home/remote interface classes to the WEB-INF/classes directory of

your WAR file. Recall that in RMI, the client needed access to the Java classes for the interface and the stubs. The same is true for EJB - an EJB client must have access to these classes. In the case of a servlet client, that means we need to copy some of the EJB's class files into the servlet's WAR file.

10. Create the WAR file and deploy. This step is just the normal process of packaging and deploying a Java servlet.

Creating an EJB stateless session bean

Step 0 (Optional)- Using Eclipse/Workshop

You can use Eclipse to create the following files.

1. To do so, create a new EJB Project. 2. Create a new -> project -> , select Show All Wizards, type in EJB in the filter text & select

EJB Project 3. Change the configuration from Weblogic EJB Project Facets to Custom & enter a project

name 4. When in the Project Facets wizard, ensure Weblogic EJB Extension is not selected.

Step 1 - Create the Remote interface

The Remote interface is a Java interface declaration, containing a list of methods (signature only) that you want your clients to be able to invoke.

Create and compile the following Java source file.

package myapp; import java.rmi.*; import javax.ejb.*; public interface HelloWorld extends EJBObject {

Page 149: J2EE Weblogic Documentation

149

public String hello(String name) throws RemoteException; }

Points to notice:

• Clients will only be able to invoke one method on the server - the method is called hello(), and it takes 1 string argument and returns a String.

• The interface extends EJBObject (javax.ejb.EJBObject). All EJB remote interfaces must do this.

• The method declares that it may throw a RemoteException. All methods in a remote interface must declare this. A RemoteException may be thrown by the underlying infrastructure if anything goes wrong with the communication between the client and server. This is the same as for RMI.

• Although it is not clearly shown here, both the parameters and the return type of remote methods must be Java classes that implement the java.io.Serializable interface.

Step 2 - Create the Home interface

The Home interface is also a Java interface declaration, containing a list of methods (signature only) that your clients can invoke. However the home interface has a special function. Before clients can access the business-logic methods of your EJB (i.e. the ones defined on the Remote interface), they must first obtain a Home interface, and from the Home interface, create an instance of the EJB. Every EJB must have both a Home and a Remote interface.

Create and compile the following Java source file.

package myapp; import java.rmi.*; import javax.ejb.*; public interface HelloWorldHome extends EJBHome { public HelloWorld create () throws RemoteException, CreateException; }

Points to notice:

• To create an instance of the EJB, clients will call a method named create() that takes no arguments, and returns an object whose type is that of the Remote interface.

• You could define more than one create method if you wish, as long as each one you define takes a different set of arguments.

• The interface extends EJBHome (javax.ejb.EJBHome). All EJB home interfaces must do this.

• The method declares that it may throw a RemoteException and/or a CreateException. All "create" methods in a home interface must declare this. Either of these exceptions may be thrown by the underlying infrastructure if anything goes wrong during the creating of the EJB.

Page 150: J2EE Weblogic Documentation

150

Step 3 - Create the EJB implementation class

This is the class that actually implements the EJB methods. It must provide public method implementations for all methods defined in the Remote interface. It must also implement all the create methods defined on the Home interface (except they are renamed slightly to ejbCreate()). The EJB implementation class may define other methods, but only the ones listed in the remote interface can be invoked over the network by clients.

Create and compile the following Java source file. If using Eclipse, you don't need to compile as this is done automatically.

package myapp; import javax.ejb.*; public class HelloWorldBean implements SessionBean { SessionContext sessionContext; // SessionBean methods public void setSessionContext (SessionContext sc) { this.sessionContext = sc; } // Argument list must match create() method // in HelloWorldHome interface public void ejbCreate() { } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } // Now our business logic methods public String hello(String name) { return ("Hello, " + name); } }

Points to notice:

• The class implements SessionBean (javax.ejb.SessionBean). All EJB session beans must do this. Notice though that this class does not implement the Remote interface we defined earlier. This is different to an RMI implementation class.

• The methods in the bean can be divided into two kinds: o standard session bean methods

these include setSessionContext(), plus all the methods whose names start with ejb (ejbCreate(), ejbRemove(), ejbActivate(), ejbPassivate()). These methods are defined by the javax.ejb.SessionBean interface.

Page 151: J2EE Weblogic Documentation

151

o business logic methods these are the methods you you defined in your Remote interface. In this example there is only one.

• The EJB container (e.g. application server, i.e. WebLogic) will pass to us a SessionContext object. We store that object in case we later want to access some facilities of the EJB container itself.

Step 4 - Write the EJB deployment descriptor

Just like packaged web applications (WAR files) needed a deployment descriptor, so too do packaged EJBs. In fact, EJBs will need two deployment descriptors.

One is a J2EE standard deployment descriptor that will be the same regardless of which application server you use (WebLogic, WebSphere, JBoss, etc). This one goes in a file called ejb-jar.xml.

The other is a container-specific deployment descriptor - its syntax will be different depending on which product you use to deploy your EJB. This one goes in a file called weblogic-ejb-jar.xml.

EJB deployment descriptors are placed into a subdirectory called META-INF. Note that this is different to the directory name you used for WAR files (which was WEB-INF).

Create the following file as ejb-jar.xml in a subdirectory called META-INF.

<?xml version="1.0"?> <ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"> <enterprise-beans> <session> <ejb-name>HelloWorld</ejb-name> <home>myapp.HelloWorldHome</home> <remote>myapp.HelloWorld</remote> <ejb-class>myapp.HelloWorldBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>HelloWorld</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>

Page 152: J2EE Weblogic Documentation

152

Secondly, create the following file as weblogic-ejb-jar.xml in the same META-INF directory as your other deployment descriptor.

<?xml version="1.0"?> <!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd"> <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>HelloWorld</ejb-name> <stateless-session-descriptor> <pool> <max-beans-in-free-pool>100</max-beans-in-free-pool> </pool> </stateless-session-descriptor> <jndi-name>ejb/HelloWorld</jndi-name> </weblogic-enterprise-bean> </weblogic-ejb-jar>

Step 5 - Package the EJB into a JAR file

EJBs are packaged in JAR files, which are created using the jar command. The syntax is exactly the same as when you created WAR files.

If running Eclipse, you can do the following steps by using the Right Mouse Button ->

Export -> EJB Jar file option.

Before creating the JAR file, check that the files are in the correct directories. There is one directory for the Java package that the classes are in, and the other directory is META-INF.

/myapp - HelloWorld.class - HelloWorld.java - HelloWorldHome.class - HelloWorldHome.java - HelloWorldBean.class - HelloWorldBean.java / META-INF - ejb-jar.xml - weblogic-ejb-jar.xml

Run the jar command from this directory as follows:

jar cf ../HelloEJB.jar *

Page 153: J2EE Weblogic Documentation

153

Step 6 - Generate stubs and skeletons

With RMI, you have to run a tool that generates stubs and skeletons for the RMI application. For EJB you also have to run a tool that generates stubs and skeletons, however it is a different tool.

WebLogic uses a tool called appc. This tool takes either a JAR or EAR file as input. The syntax is as follows.

cd .. java weblogic.appc HelloEJB.jar

If you have errors in your JAR file (for example, incorrect directory structure, invalid syntax in the deployment descriptor), appc will usually alert you.

Step 7 - Deploy the EJB into an application server

The process of deploying an EJB is identical to deploying a web application. You just copy the JAR file into the "applications" subdirectory of your WebLogic installation.

cp HelloEJB.jar ~/weblogic/autodeploy

Watch the WebLogic server window to see if there were any errors during deployment.

If the EJB was deployed successfully, you will find its name will appear in the JNDI tree of your WebLogic server. Open a management console, and go to "Servers", "myserver", then move to the "Monitoring" tab and choose "View JNDI tree". Your EJB name should appear with a purple dot next to it. This indicates that your EJB is advertising itself in the name service as being available to clients.

Step 8 - Copy EJB stubs + home/remote interface classes to the WEB-INF/classes directory of your

WAR file

Just as with RMI, the "client" (in this case a servlet) needs access to the stub files generated by ejbc.

Because the client is packaged separately from the EJB, the stubs need to be manually copied from the ejbc-generated output into the servlet's WAR file.

Change directory into the WEB-INF/classes directory of your WAR file, and run the following JAR command that will extract the contents of the EJB JAR file into the WEB-INF/classes directory. This will make sure the compiled stubs and compiled home/remote interfaces are available to the client. Note that it will also make other, unnecessary, classes available to the client, but we ignore those now for simplicity.

cd WEB-INF/classes

Page 154: J2EE Weblogic Documentation

154

jar xvf /mypath/HelloEJB.jar

You will need to change /mypath/ to represent the directory path of where you have placed your EJB JAR file.

! ALTERNATIVELY could just just copy the entire jar file into the WEB-INF/lib directory

Step 9 - Create an EJB client - a servlet

Here we will use a Java servlet as the client to our EJB. You should create your WAR file directory structure in a different place to where you created the JAR file for your EJB. The WAR file and the JAR file are completely independent.

Create and compile the following Java source file.

import myapp.*; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import javax.naming.*; import javax.rmi.PortableRemoteObject; import java.util.*; public class HelloWorldServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); out.println("----------------------------------------"); try { Context ctx = new InitialContext(); out.println("Got context"); HelloWorldHome hwsh; Object ref = ctx.lookup("ejb/HelloWorld"); hwsh = (HelloWorldHome) PortableRemoteObject.narrow( ref, HelloWorldHome.class); out.println("Got home interface"); HelloWorld hws = hwsh.create(); out.println("Created EJB"); out.println(hws.hello("chris")); } catch (Exception e) { e.printStackTrace(out); } out.println("----------------------------------------"); } }

Page 155: J2EE Weblogic Documentation

155

Remember that the compiled servlet class must go in the WEB-INF/classes subdirectory.

Also note that the servlet will not compile unless you have the directory "." (which means the current directory) in your CLASSPATH. The WebLogic setEnv.sh script does not automatically put "." in your CLASSPATH, so you may have to add it manually if you have not already. In a text editor, open the file ~/weblogic/bin/setDomainEnv.sh, and search for the line that starts "CLASSPATH=...". In this line, add "." to the list of directories.

You could also equally place the EJB lookup & execution code (basically the entire try-

catch block!) into a scriptlet in a JSP.

This way you do not have to compile the servlet.

Regarding the servlet code itself, notice the sequence of operations for the client:

1. Create an InitialContext so we can look up a name service, to find the EJB. No parameters are supplied when we create the InitialContext so we will use the name service supplied by the container (WebLogic), which is what we want in this case.

2. Look up the "JNDI name" of the EJB. Recall that when you created the EJB, you specified its JNDI name in the weblogic-ejb-jar.xml deployment descriptor. That is the name that we use here to perform the lookup. If the lookup is successful, we will be returned with a Java object of type HelloWorldHome - i.e. the EJB's Home interface.

3. Now that we have a reference to the Home interface, we can call the create() method which will give us a reference to the EJB itself (i.e. its Remote interface).

4. Finally, now that we have a reference to the EJB's Remote interface, we can call business logic methods of the EJB as defined on the Remote interface (in this case the method hello()).

This may seem a slightly strange process. Just remember that first we obtain a reference to the EJB's Home interface, and from that we create an instance of the EJB which returns an instance of the EJB's Remote interface.

Step 10 - Create the WAR file and deploy

Now that you have created your servlet, and copied the stubs and interfaces so they are accessible to the servlet, you can create the WAR file for the servlet, and deploy it to WebLogic.

The process is the same as you have used for creating and deploying WAR files in the past.

Note that you will need to create a web.xml file in the WEB-INF directory for the servlet. There is nothing special about this web.xml file - it will be the same as you have created before.

To deploy your WAR file, copy it to the "autodeploy" subdirectory of your WebLogic installation.

Page 156: J2EE Weblogic Documentation

156

Running the HelloWorld EJB example

To test your application, open a web browser window, and enter the URL of your servlet into the Location field. If all goes well, your servlet will execute, and will make a remote method call to the EJB that is executing in the application server.

Next step ...

Now that you have followed a step-by-step walkthrough, the next step is to be a bit more independent.

Modify the example above to include a new remote method that will add together two integers (i.e. it takes two integer arguments, and returns an integer result).

This will involve changing the remote interface, and then re-running all the subsequent steps.

Module: EJB

Lab exercise - Using Eclipse + Xdoclet to generate EJB

In this lab exercise, you will use Eclipse + Xdoclet to create an Enterprise JavaBean.

Level of Difficulty: 2 (moderately easy) Estimated time: 60 minutes Pre-requisites:

• Run wlenv to set your environment correctly • Start your WebLogic server running in the background

Rapid code development

One of the biggest complaints about Enterprise JavaBeans as implemented by the J2EE specification is the complexity of generating what seems like fairly straight forward business component development.

Page 157: J2EE Weblogic Documentation

157

This issue resulted in the development of competing frameworks such as Spring MVC, Object-Relational Mapping systems such as Hibernate and Java Data Objects, where developers bypass the whole EJB infrastructure entirely.

Sun recognised this by creating 2 new standards - the Java Persistence API (which front ends ORM systems such as Hibernate) and the EJB 3.0 specification (which uses Java 5 annotations to 'tag' classes and methods as Enterprise Java Beans)

Using EJB 3.0 would be a simpler technique than using EJB 2.1, however, this is not implemented in the J2EE 1.4 specification and is a fundamental part of Java Enterprise Edition 5.

Most Java application servers &/or tooling are not yet fully certified at the Java EE 5 spec, so we will concentrate on EJB 2.1 coding.

One technique similar to EJB 3.0 is to use Java 5 annotations or Javadoc-style annotations in our code and let code generators create most of the tedious steps required to generate EJB's.

In our environment, there are 2 main ways to do this

1. Use the proprietary WebLogic workshop "ejbgen" tool.

2. Use the open source (and popular) Xdoclet tool

Using Weblogic Workshop EJBgen

See the tutorial called "Using EJBGen"

Using Eclipse & XDoclet

Xdoclet ( http://xdoclet.sourceforge.net ) is an open source product designed to remove most of the tedium when developing EJB's.

The original product was called ejbdoclet but this tool is now generic and supports many other technologies such as Servlets, Hibernate, Spring & so on and has large support for major Application server vendors such as IBM and BEA WebLogic.

XDoclet is designed to be run using Apache ANT, a Java 'make' tool. You normally create a build.xml file with various XDoclet specific 'tasks'.

You then create Plain Old Java Object (POJO) classes which implement the business logic. You don't need to create tonnes of extra class files and deployment descriptors, everything is in one source file!!

Using Eclipse Web Tools Project reduces the workload significantly further by providing templates and wizards to generate more code.

Use the following steps to re-create the previous stateless session bean lab.

Page 158: J2EE Weblogic Documentation

158

Step 1: Create the project and settings for Xdoclet development

Create a new EJB project by: new -> select Show All Wizards, , type EJB in the filter text & select EJB Project

In the New EJB Project wizard: enter project name (HelloEJB), & change Configurations (EJB Project with XDoclet)

Page 159: J2EE Weblogic Documentation

159

[Next] On the Project Facets wizard, ensure EJBDoclet (Xdoclet) selected & version 1.2.3 (use dropdown on 1.2.3 to get this)

Page 160: J2EE Weblogic Documentation

160

[FINISH]

You now need to set up the project's XDoclet settings

From the project menu, Right Mouse Button -> Properties -> Xdoclet -> ejbdoclet ->

select weblogic

Page 161: J2EE Weblogic Documentation

161

This will ensure that the Xdoclet generator will execute the weblogic specific tasks. Note that if you are using, say, JBoss, you would also select the JBoss task to generate the JBoss specific deployment descriptors.

Step 2 - Create a new Session Bean

First step is to create a package. Use New -> Package & call the package myapp

To create a new EJB, select:

New -> Xdoclet Enterprise JavaBean

(or you may have to use New -> Other -> EJB -> Xdoclet Enterprise JavaBean)

If you get a message "Annotation provider definition is not valid", please select the preferences link

Page 162: J2EE Weblogic Documentation

162

You will need to set up Xdoclet provider preferences:

• Make sure Enable xdoclet builder is checked. • Xdoclet Home: /pub/ajpcpe/xdoclet, • Select version: 1.2.3

You will also have to check the XDoclet settings AGAIN! (this is a known bug in the XDoclet wizard)

• Expand the Xdoclet menu on the left & select the ejbdoclet preferences. • Ensure the Weblogic task is ticked (you can also select other tasks if you are using non-

weblogic application servers such as JBoss)

Page 163: J2EE Weblogic Documentation

163

Once you do this step, you should not have to do this again for any further Enterprise Java Bean creation.

Creating the bean

After the previous setup set has been completed, you should be back to Create Enterprise Java Bean wizard.

• Ensure Session Bean is selected & press [NEXT]

• Select or enter a package name eg: myapp Add a class name eg: HelloBean. Leave superclass as Object. & press [NEXT]

• The next window will display some more parameters for the EJB. Adjust EJB name, description, & display name as necessary.

** IMPORTANT ** Make the JNDI name ejb/Hello (you could leave this as the default, but the standard is to have the ejb beans

under the ejb subcontext) Leave State Type = Stateless & Transaction Type: Container Press [FINISH] to build your EJB

Page 164: J2EE Weblogic Documentation

164

You should then see the HelloBean.java file in the code editor and some messages in the console about Xdoclet.

It runs through various stages such as Init, Ejbdoclet. This is actually generating all the class files and deployment descriptors.

Note: if you don't see the "Running <weblogic/>" Generating weblogic-ejb-jar.xml message, you have failed to follow the Weblogic task setup above.

Step 3: Enhancing the Enterprise JavaBean

f you look in the ejbModule folder of your EJB project, you should see in the myapp package the following files

Hello.java REMOTE interface Hello EJBObject = declarations

HelloBean.java IMPLEMENTATION SessionBean + business methods

HelloHome.java HOME interface EJBHome

HelloLocal.java LOCAL interface EJBLocalObject = declarations

HelloLocalHome.java LOCALHOME interface EJBLocalHome

HelloUtil.java Utility class helper class eg: getHome()

We will only change HelloBean.java. Everything else is Generated!! To add business methods, edit the HelloBean source file class with the business method like in the session bean lab.

Look for the automatically generated method called foo

Notice that there is a special javadoc tag in front called @ejn.interface-method view-type="remote"

/** * * <!-- begin-xdoclet-definition --> * @ejb.interface-method view-type="remote" * <!-- end-xdoclet-definition --> * @generated * * //TODO: Must provide implementation for bean method stub */ public String foo(String param) { return null; }

Page 165: J2EE Weblogic Documentation

165

These tags are what XDoclet uses to generate code with. By default, this means XDoclet will generate a declaration of this method (foo()) in the Remote interface.

If you change the view-type from remote to both then XDoclet will generate the business method into both the remote and local interfaces.

For our exercise, let's change this method to the same as the stateless session lab:

/** * * <!-- begin-xdoclet-definition --> * @ejb.interface-method view-type="both" * <!-- end-xdoclet-definition --> * @generated * */ public String hello(String name) { return ("Hello, " + name); }

Notice that when you change any code in this file, XDoclet will automatically re-build the files.

To stop this behaviour, you need to click on the main toolbar, select Project & de-select Build Automatically. However, be careful, since you will need to build manually if you don't build automatically. Do this via the RMB -> Run XDoclet command.

Step 4: Deploy the bean

There are 4 main ways to do this (assuming the server is running)

• (1) From Workshop, right click on the Server (BEA Weblogic Server v10.0 @ localhost) in the Servers view and click "add and remove projects". You then choose the EJB and select Add & [finish] This deploys the bean on the server

• (2) You can Export the bean to a Jar file. Select the EJB project, RMB -> Export -> Export

as EJB Jar file. Copy the resultant JAR file into the weblogic/autodeploy directory

• (3) From the weblogic console, use the [Lock & Edit] & choose Deployment -> Install

option to upload the JAR file from step 2.

• (4) You can create an EAR project file which has project dependencies on it (containing the lab Web project & the EJB project) You then use step 1 to add the EAR project to weblogic -OR- use Export -> Export as EAR file. This EAR file can then be deployed by copying to the weblogic/autodeploy directory or via the Weblogic console Deployments - install option

Step 5: Creating the client:

Page 166: J2EE Weblogic Documentation

166

This is pretty much the same steps as the Stateless Session Bean lab.

Let's use a JSP to test this EJB.

You need to create a JSP into an existing Dynamic Web project with the following code in it.

<%@page import="myapp.*, javax.naming.*, javax.rmi.*" %> <% Context ctx = new InitialContext(); String jndi_name = "ejb/Hello"; out.println("Got context"); HelloHome hwsh; out.println("Looking for JNDI name " + jndi_name); Object ref = ctx.lookup(jndi_name); hwsh = (HelloHome) PortableRemoteObject.narrow( ref, HelloHome.class); out.println("Got home interface"); Hello hws = hwsh.create(); out.println("Created EJB"); out.println(hws.hello("mate")); %>

A Better way - using the XDoclet xxxutil class

XDoclet generates a utility class called bean_nameUtil.java to make your life easier. This provides a method called getHome() which replaces all the context lookups etc.

This code implements a "Service Locator" pattern and can even cache the bean lookups to make your code very efficient.

<% HelloHome h = HelloUtil.getHome(); Hello bean = h.create(); out.println(bean.hello("mate")); %>

A lot simpler eh?

Your client code will need to have access to the myapp.Hello & myapp.HelloHome classes.

You have 2 options:

(1) copy the EJB jar file exported earlier (helloEJB.jar) to WebContent->WEB-INF->lib (The problem with this solution is that you need to update the jar whenever you change the EJB) (2) Set your Dynamic Web Project to have a "J2EE Dependency". You select your Web project (eg: lab) & RMB-> Properties, J2EE Modules Dependencies

-> Select (helloejb) Jar module]

Page 167: J2EE Weblogic Documentation

167

This will result in the .jar file being placed into the WEB-INF/lib directory at deployment time automatically!!

Note: Normally you only need the Hello, HelloHome (& helloUtil) (& maybe the HelloLocal* equivalents) classes, but we will be lazy and import the whole lot.

Step 6: Running the client

Run as usual. (select the web project , RMB -> Run As -> Run on Server). Normally most changes will get automatically deployed, as long as there is a dependency between the web project and the EJB project.

Note: when you look at the web project on the server view, you now see a + symbol next to the web project. Expanding this shows the EJB bean jar

Problems you may encounter

You may need to re-deploy the EJB if you make any changes to the signatures of the bean methods or add new beans into the EJB project.

Sometimes you Workshop does not correctly re-deploy changes into the dependent J2EE projects (such as your Web project).

To fix this, re-do step 4 above.

Next step ...

Now that you have followed a step-by-step walkthrough, the next step is to be a bit more independent.

Modify the example above to include a new remote method that will add together two integers (i.e. it takes two integer arguments, and returns an integer result).

This will involve changing the remote interface, and then re-running all the subsequent steps.

Page 168: J2EE Weblogic Documentation

168

Module: EJB

Lab exercise - CMP Entity Bean- manually

In this lab exercise, we create an Entity EJB that uses Container Managed Persistence (CMP).

Level of Difficulty: 4 (moderately difficult) Estimated time: 90 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Start your WebLogic server running in the background • Completed Stateless Session Bean exercise

Overview of Entity Beans

In the last exercise, you successfully created a stateless session bean. Recall that session beans are transient beans created to perform some task on behalf of a client. However the goal of this exercise is to create an entity bean. Entity beans represent data in the application.

Each instance of an entity bean corresponds to an individual instance of an entity. So for example, if your application has an entity bean called 'Person', and your application knows about 2 people, Mary and Joe, you will have two instances of the Person entity bean.

Entity beans must be persistent. That means that an entity bean must survive even if the application server is shut down or crashes. This implies that the data associated with an entity bean must be stored permanently, either in a database, or in a file on disk, or using some other form of persistent storage.

Commonly, entity beans map to database records. In a simple example, one entity bean corresponds to one row in a relational database table.

There are two ways to implement the persistence requirement of entity beans. One way is to use a relational database for the persistent storage of entity data, and let the container (application server) manage the mapping between attributes in your entity bean and columns in the database table. This is called Container Managed Persistence (CMP). The other alternative is to write the Java code to save and load the entity bean data yourself. This is called Bean Managed Persistence (BMP).

CMP is easier to implement (less code to write), but it can only be used in very simple cases. BMP is the more general kind of entity bean, but requires more programming effort.

Also note that we will focus entirely on EJB 2.0. Many books and examples on the web may use EJB 1.1. One of the main areas of difference between these versions of the EJB standard is the handling of CMP entity beans. Be careful that you only follow instructions for EJB 2.0!

Page 169: J2EE Weblogic Documentation

169

Development Process

The development process for an entity bean is almost identical to that of creating a session bean. The steps are listed below as a reminder, and the differences between session and entity beans noted.

1. Create the Remote interface. 2. Create the Home interface.

Provide a create() method if you want users to be able to create new entities (add a new row to the database). Provide a remove() method if you want users to be able to permanently remove entities (delete a row from the database). Provide one or more findXXX() methods, including the mandatory findByPrimaryKey() method.

3. Create the EJB implementation class. You will need to declare abstract get/set methods for each of the CMP fields your bean will use.

4. Write the EJB deployment descriptor. In addition to the ejb-jar.xml and weblogic-ejb-jar.xml deployment descriptors, you will also need to create a third deployment descriptor file for a CMP bean, typically called weblogic-

cmp-rdbms-jar.xml. 5. Package the EJB into a JAR file. 6. Generate stubs and skeletons. 7. Deploy the EJB into an application server. 8. Create an EJB client for testing - a session bean.

Servlets/JSPs should not invoke methods on an entity bean directly, but rather should access entities via session beans. This means that the client of an entity bean should always be a session bean.

Creating an EJB CMP Entity bean

Step 0 - Check your database table

This example assumes that you have an Oracle database table called addressbook as described in the earlier JDBC exercises. If you do not have this table, you will need to create it before continuing.

Step 1 - Create the Remote interface

Create and compile the following Java source file.

package addressbook; import java.rmi.*; import javax.ejb.*; public interface Person extends EJBObject {

Page 170: J2EE Weblogic Documentation

170

String summary() throws RemoteException; }

Points to notice:

• Here we define one business logic method in addition to the methods that will be used to access the fields of the addressbook (name, address, etc).

Step 2 - Create the Home interface

Create and compile the following Java source file.

package addressbook; import java.rmi.*; import javax.ejb.*; import java.util.Collection; public interface PersonHome extends EJBHome { public Person create (String name, String address, String email, String extn, String birthday) throws RemoteException, CreateException; public Person findByPrimaryKey (String name) throws RemoteException, FinderException; public Collection findByEmail (String email) throws RemoteException, FinderException; }

Points to notice:

• We allow clients to create new addressbook entries, but we do not allow them to delete any entries (there is no remove() method defined).

• We allow clients to search for a person in two ways: by name (the primary key), in which case the finder method returns an instance of the Person object, or by email, in which case the finder method returns a java.util.Collection of primary keys that represent the records that match the search criteria.

Step 3 - Create the EJB implementation class

Create and compile the following Java source file.

package addressbook; import javax.ejb.*; public abstract class PersonBean implements EntityBean { private EntityContext entityContext;

Page 171: J2EE Weblogic Documentation

171

// EntityBean methods public void setEntityContext (EntityContext ec) { this.entityContext = ec; } public void unsetEntityContext () { this.entityContext = null; } // Argument list must match create() method // in PersonHome interface public String ejbCreate(String name, String address, String email, String extn, String birthday) throws CreateException { setName(name); setAddress(address); setEmail(email); setExtn(extn); setBirthday(birthday); return null; } public void ejbPostCreate(String name, String address, String email, String extn, String birthday) throws CreateException { } public void ejbRemove() throws RemoveException { } public void ejbActivate() { } public void ejbPassivate() { } public void ejbLoad() { } public void ejbStore() { } // Now the abstract methods for CMP fields abstract public String getName(); abstract public void setName(String name); abstract public String getAddress(); abstract public void setAddress(String address); abstract public String getEmail(); abstract public void setEmail(String email); abstract public String getExtn(); abstract public void setExtn(String extn); abstract public String getBirthday(); abstract public void setBirthday(String birthday); // Now our business logic methods public String summary() {

Page 172: J2EE Weblogic Documentation

172

String result = getName() + " " + getExtn() + "\n"; return (result); } }

Points to notice:

• The class implements EntityBean, not SessionBean. • The class has methods setEntityContext() and unsetEntityContext(). • The parameter list of ejbCreate() must match the parameter list defined in the Home

interface. • The ejbCreate() method returns the type of the primary key, but when it actually returns

at the end of the function, it returns a null value. Note that the type is different to what is returned by the create() method in the Home interface (the one that the client calls). The create() method on the home interface returns the type of the EJB remote interface (i.e. the EJB type). It seems strange that ejbCreate() returns a different type of value to create(), but it is the correct way to do it, according to the EJB specification!

• There is now a method called ejbPostCreate() with the same parameter list. ejbPostCreate() is called by the container after the successful creation of a new entity bean.

• There are abstract method declarations for each of the CMP fields. • The whole class itself is also declared abstract because of the abstract methods.

Step 4 - Write the EJB deployment descriptor

Now there are three deployment descriptors.

Create the following file as ejb-jar.xml in a subdirectory called META-INF.

<?xml version="1.0"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <enterprise-beans> <entity> <ejb-name>Person</ejb-name> <home>addressbook.PersonHome</home> <remote>addressbook.Person</remote> <ejb-class>addressbook.PersonBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.String</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>PersonBean</abstract-schema-name> <cmp-field> <field-name>name</field-name> </cmp-field> <cmp-field> <field-name>address</field-name> </cmp-field>

Page 173: J2EE Weblogic Documentation

173

<cmp-field> <field-name>email</field-name> </cmp-field> <cmp-field> <field-name>extn</field-name> </cmp-field> <cmp-field> <field-name>birthday</field-name> </cmp-field> <primkey-field>name</primkey-field> <query> <query-method> <method-name>findByEmail</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> <![CDATA[SELECT OBJECT(p) FROM PersonBean AS p WHERE p.email = ?1]]> </ejb-ql> </query> </entity> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>Person</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>

Secondly, create the following file as weblogic-ejb-jar.xml in the same META-INF directory as your other deployment descriptor.

<?xml version="1.0"?> <!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN" "http://www.bea.com/servers/wls600/dtd/weblogic-ejb-jar.dtd" > <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>Person</ejb-name> <entity-descriptor> <entity-cache> <max-beans-in-cache>1000</max-beans-in-cache> </entity-cache> <persistence> <persistence-type> <type-identifier>WebLogic_CMP_RDBMS</type-identifier>

Page 174: J2EE Weblogic Documentation

174

<type-version>6.0</type-version> <type-storage> META-INF/weblogic-cmp-rdbms-jar.xml </type-storage> </persistence-type> <persistence-use> <type-identifier>WebLogic_CMP_RDBMS</type-identifier> <type-version>6.0</type-version> </persistence-use> </persistence> </entity-descriptor> <jndi-name>ejb/Person</jndi-name> </weblogic-enterprise-bean> </weblogic-ejb-jar>

Finally, create the following file as weblogic-cmp-rdbms-jar.xml in the same META-INF directory as your other deployment descriptors.

<?xml version="1.0"?> <!DOCTYPE weblogic-rdbms-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB RDBMS Persistence//EN' 'http://www.bea.com/servers/wls600/dtd/weblogic-rdbms20-persistence-600.dtd'> <weblogic-rdbms-jar> <weblogic-rdbms-bean> <ejb-name>Person</ejb-name> <data-source-name>thinOracleDataSource</data-source-name> <table-name>addressbook</table-name> <field-map> <cmp-field>name</cmp-field> <dbms-column>name</dbms-column> </field-map> <field-map> <cmp-field>address</cmp-field> <dbms-column>address</dbms-column> </field-map> <field-map> <cmp-field>email</cmp-field> <dbms-column>email</dbms-column> </field-map> <field-map> <cmp-field>extn</cmp-field> <dbms-column>extn</dbms-column> </field-map> <field-map> <cmp-field>birthday</cmp-field> <dbms-column>birthday</dbms-column> </field-map> </weblogic-rdbms-bean> </weblogic-rdbms-jar>

Also notice that this XML file refers to details relating to the database. In particular, the table name, and the field names.

Page 175: J2EE Weblogic Documentation

175

It also refers to the Data Source that the EJB should use for connecting. The XML file above assumes that you already have a data source created in your WebLogic management console called thinOracleDataSource. If you do not already have this data source, you must create it before trying to deploy or use this EJB.

Remainder ...

The remainder of the steps are the same as for creating a stateless session bean.

Before you attempt to deploy your Person EJB, be sure to use the WebLogic management console to set up a JDBC Data Source, and associated Connection Pool. Refer to the JDBC notes to recall how.

For now, you can use a servlet as a test client for the entity bean (although in a real application, servlets generally would not call an entity bean directly). If you reuse your servlet from the stateless session bean exercise, you will need to change the following points:

• the import statement, to specify the correct package name; • the class names; • the JNDI name to look up - it should match the JNDI name specified in the weblogic-

ejb-jar.xml file; • the home interface method used to get a reference to the EJB. In a session bean, the

client calls the create() method. In an entity bean, the client probably needs to call the findByPrimaryKey() method with the right type of argument, or another "finder" method. Recall that with entity beans, calling create() will actually add a row to the database;

• the business logic method (the remote interface method).

Refer to the course notes, the EJB 2.0 specification from Sun Microsystems, and the API documentation for assistance.

Module: EJB

Page 176: J2EE Weblogic Documentation

176

Lab exercise - CMP Entity Bean-using Eclipse + XDoclet

In this lab exercise, we create an Entity EJB that uses Container Managed Persistence (CMP).

Level of Difficulty: 4 (moderately difficult) Estimated time: 90 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Start your WebLogic server running in the background • Completed Stateless Session Bean exercise • Complete the Entity Bean exercise

Entity Beans using XDoclet

Unlike the previous exercise, we will use Eclipse WTP and XDoclet to generate most of the code you need to write an entity bean. Even though XDoclet can make writing Entity beans easier, it is still a tedious process to write and annotate a JavaBean which represents your table row.

Development Process

The good news for using rapid development tools is that Eclipse can read your database tables and generate an appropriate xxxBean class with most of the common attributes and annotations pre-set for you.

Once we have our xxxBean class generated, we then tailor the class to modify the datasource name, add getData() if you want to use the XDoclet generated value objects, add business methods, add finders and any other customisations that might be needed.

Creating an EJB CMP Entity bean

Check your database table

This example assumes that you have an Oracle database table called addressbook as described in the earlier JDBC exercises. If you do not have this table, you will need to create it before continuing.

Creating the Container Managed Bean

Assuming we are using the existing EJB project, create a new bean by using New -> EJB ->

Xdoclet Enterprise Bean

* Select Container Managed Bean [Next]

* Select the package (myapp), & name "AddressBookBean" [Next]

Page 177: J2EE Weblogic Documentation

177

* On the CMP Entity Bean wizard, change the name of the generated Schema from AddressBookSCHEMA to AddressBook & you can choose "usecase:" Import Attributes

from table (or you can "Define new Attributes" if you want to do the next part by hand!). (leave the default for the moment)

* Now choose the JDBC Connection that you set up in the Oracle Lab. This would have been called "ell" [Next]

* Assuming that you can connect (or reconnect if prompted with your Oracle userid and password), you can choose the your addressbook table in the CMP Attributes Wizard in the following Step * Select the dropdown in the Table field. You will need to type in your fully qualified table name (normally your oracleuserid.addressbook) to get the correct table name. (I think there is a bug in Eclipse WTP 1.5 which lists ALL the tables in the oracle database, hence the need to filter it down to your own schema)

Page 178: J2EE Weblogic Documentation

178

This should result in the list of columns you defined in the JDBC lab, eg:

[FINISH] when complete.

* Note that XDoclet will run and will create many files, hopefully including the weblogic-ejb-jar.xml & weblogic-cmp-rdbms-jar.xml deployment descriptors. If these don't appear, you should check your XDoclet preferences to ensure that weblogic was selected as a checked task.

The files generated should be:

AddressBook.java (remote Interface)

AddressBookBean.java (The main IMPLEMENTATION) AddressBookCMP.java AddressBookData.java (a Data Transfer/value object/javabean) AddressBookHome.java (home interface) AddressBookLocal.java AddressBookLocalHome.java AddressBookUtil.java (utility classes - in particular, getHome() )

You will need to edit the AddressBookBean.java file to change the various Xdoclet attributes.

For weblogic deployments, you need to change the line with:

Page 179: J2EE Weblogic Documentation

179

* @weblogic.data-source-name ${data.source.name} * <!-- end-xdoclet-definition --> * @generated

to

* @weblogic.data-source-name thinOracleDataSource * * @generated

When you save, this should automatically restart xdoclet.

Just to check, edit the META-INF/weblogic-cmp-rdbms-jar.xml file to see the data-source-name is thinkOracleDataSource and that the correct table name is there.

Look at the generated code.

• Note that AddressBook is just like an ordinary JavaBean with getters/setters for the properties of an addressbook bean

• AddressBookBean is similar, except for bean management methods such as ejbCreate(), ejbLoad(), ejbRemove(), ejbStore() & so on. Note that the generator has created a @ejb.finder called findAll() which basically dumps the whole table!

• AddressBookCMP extends AddressBookBean and adds the method getData(), which is used to obtain the AddressBookData value object.

• AddressBookData is just a plain old Javabean. However, note that there are 2 methods generated for you - equals() and hashCode(). These are useful if you have a Collection of AddressBookData (especially Sets) or just want to compare beans by content (rather than by reference!)

• AddressBookHome & AddressBookLocalHome classes contain the methods used to find beans such as findByPrimaryKey() & findAll() as well as the usual create() method.

• Finally, AddressBookUtil contains utility methods, of which only the getHome() & getLocalHome() methods are useful.

• You can update AddressBookBean to add any extra business methods you wish. Xdoclet will automatically run when you save these edits.

Creating a custom ejbCreate() method.

* When editing AddressBookBean you will notice that there is a TODO task on the ejbCreate() method code.

* It is highly recommended that you COPY this entire create method by adding parameters to populate the fields & leave the default null ejbCreate() method alone.

* Add the following code AFTER the existing ejbCreate() method. Note that it is ESSENTIAL to keep the comments in the right spot (ie: before the Javadoc comment before ejbPostCreate()

Page 180: J2EE Weblogic Documentation

180

/** * * <!-- begin-user-doc --> * The ejbCreate method. * <!-- end-user-doc --> * * <!-- begin-xdoclet-definition --> * @ejb.create-method * <!-- end-xdoclet-definition --> * @generated */ public java.lang.String ejbCreate( String name, String address, String email, java.math.BigDecimal extn, java.sql.Date birthday ) throws javax.ejb.CreateException { // begin-user-code setName(name); setAddress(address); setEmail(email); setExtn(extn); setBirthday(birthday); // EJB 2.0 spec says return null for CMP ejbCreate methods. return null; // end-user-code }

You could optionally also create yet another ejbCreate() method passing an AddressBookData object as the parameter (since this is the Value Object representing AddressBook objects).

This is necessary since when you create an entity bean, you are actually performing an INSERT into TABLE VALUES(... ).

Since you need to have the values populated before you can insert into the table, you have to somehow pass the values to the ejbCreate() method!!!!

Creating Other methods in AddressBookBean

You can also add business methods like you did with the Session bean to AddressBean. However, these should be closely related to the purpose of the Entity Bean - related to the business data!!!

Add the following to allow you to automatically obtain a JavaBean (AddressBookData) which you can treat as a Data Transfer Object instead of passing tonnes of parameters to various business methods.

/** * Provides access to the generated getData() method of the generated * CMP class. * @ejb.interface-method */ public abstract AddressBookData getData();

Page 181: J2EE Weblogic Documentation

181

A very useful debugging method to add is print()

/** * print of a string version of the entity bean * @ejb.interface-method view-type="both" * */ public String print() { return "Name=" + getName() + ",Address=" + getAddress() + ",Email=" + getEmail() + ",Extn=" + getExtn() ",Birthday=" + getBirthday(); }

* Xdoclet should automatically run and re-generate the java files & deployment descriptors. If not, select EJB project & RMB -> Run Xdoclet

* Do note that AddressBook.java also lists these 2 methods - getData() & print().

* Finally, the AddressBookData.java bean does not list any of the business methods we just defined (print()). This is because the sole purpose of AddressBookData is to encapsulate data, not business logic. (do note that it does provide a toString() method, which looks very much like our print() method!!)

Deploying it

Since you added this entity bean into the existing helloEJB lab, your bean will be automatically deployed and updated when you run the lab web project. Otherwise, follow the same instructions for session beans

* Note: when you update an EJB lab in Workshop, this is rebuilt but not automatically redeployed dynamically. You need to use Run As -> Run on Server on the DEPENDENT web project to force the redeployment.

* Note: If there are any problems deploying, sometimes it is best to select the server, RMB -> Add and Remove Projects then to remove the EJB project, and re-add it

* Note: if you get a warning about "The web project build path contains classes or jars which are not inside the standard <WebAppRoot>/WEB-INF/classes, you can safely ignore this message since we are using Weblogic Shared Libraries.

Client code.

Your code will look similar to the session Bean exercise except now you can deal with the create(), findByPrimaryKey() & findAll() methods

Here is a sample code which looks up a row in the table by primary key (the name field)

<h1>This searchs AddressBook CMP by name</h1> <%

Page 182: J2EE Weblogic Documentation

182

AddressBookHome h = AddressBookUtil.getHome(); AddressBook bean = h.findByPrimaryKey("chris"); // does a select %> <ol> <li>Name=<%=bean.getName() %> <li>Address=<%=bean.getAddress() %> <li>Email=<%=bean.getEmail() %> <li>Extn=<%=bean.getExtn() %> <li>Birthday=<%=bean.getBirthday() %> </ol>

It is not good practice to call the Entity bean directly to retrieve the table columns. The better way is to use a Value Object - AddressBookData is appropriate and pre-generated for you.

So you should add AddressBookData ab = bean.getData(); & thence refer to this object instead of bean (ie: ab.getName() ) etc. AddressBookData is an ideal object to pass to your JSP and to save in your sessions as an attribute. It can be accessed quite nicely via the JSL EL.

Here is a sample code which creates a new row in the database

<% AddressBookHome h = AddressBookUtil.getHome(); try { AddressBook bean = h.create("sam", "Sydney", "[email protected]", java.math.BigDecimal.valueOf(1234L), java.sql.Date.valueOf("1990-07-01") ); out.println("Bean created"); out.println("key=" + bean.getName()); } catch (Exception e) { out.println("<b>ERROR: "); out.println(e.getMessage()); // return to JSP e.printStackTrace(); // debug to console }

And here is a sample which lists all records in the database

<% AddressBookHome h = AddressBookUtil.getHome(); AddressBook bean; java.util.Collection list = h.findAll(); // does a select * for (Object i : list) { bean = (AddressBook) i; %> <ol> <li>Name=<%=bean.getName() %> <li>Address=<%=bean.getAddress() %> <li>Email=<%=bean.getEmail() %> <li>Extn=<%=bean.getExtn() %> <li>Birthday=<%=bean.getBirthday() %> </ol> <% } %>

Page 183: J2EE Weblogic Documentation

183

More things to do

You can add your own custom Finders, which will be automatically generated for you

Edit the AddressBookBean & locate the xdoclet comment that starts with @ejb.finder

You can create your own query by adding the following line after it

* @ejb.finder * query="SELECT OBJECT(a) FROM AddressBook as a WHERE a.email like ?1" * signature="java.util.Collection findByEmail(java.lang.String email)" *

Deploy as usual. Create a JSP which uses the above method.

Facade patterns

It's best practice not to have entity beans called in a JSP. This is for both seperation of concerns and the violation of the MVC pattern.

The better way is to have a Session bean acting as a facade in front of the entity bean. This allows us to both unit test, seperate the database code from the presentation code and improve efficiency.

The simplest way to do this is to just add code to the facade which invokes the entity bean! (much like what you used for a servlet/jsp)

Here's an example.

In the earlier Session Bean EJB, create a new xdoclet method with the following signature

/** * * <!-- begin-xdoclet-definition --> * @ejb.interface-method view-type="both" * <!-- end-xdoclet-definition --> * @generated * */ public String facade(String param) { try { AddressBookHome h = AddressBookUtil.getHome(); AddressBook bean = h.findByPrimaryKey(param); return bean.print(); } catch (Exception e){ return (e.getMessage()); } }

I'm assuming that the session bean and entity bean are in the same EJB project here.

Then to call it just use the session bean as normal (ctx.lookup etc) but call bean.facade() instead to invoke the entity bean via the session bean.

Page 184: J2EE Weblogic Documentation

184

What's neat is that the JSP has no idea that they are calling a database lookup. The session bean could actually just cache beans that have already been read.

An even better pattern is to use a "Business Delegate" pattern and hide the session bean from the JSP as well. This is just a POJO which hides all references to EJB's (eg: caches the lookup, etc) from the caller.

Essentially this is just moving any reference to JNDI, lookups, PortableRemoteObject.narrow(), Home & Bean methods etc into a seperate class &/or method...

What if the EJB's are in seperate projects?

You have to create EJB references in the session bean.

This normally exists in the ejb-jar.xml and weblogic-ejb-jar.xml files, but Xdoclet makes this easy to setup.

Edit the sessionBean source code and use the @ejb.ejb-ref and @weblogic.ejb-reference-description tags, for example, in HelloBean.java:

* @ejb.ejb-ref * ejb-name="AddressBook" * * @weblogic.ejb-reference-description * jndi-name="ejb/AddressBook" * ejb-ref-name="ejb/AddressBook" *

This will update the ejb-jar.xml and weblogic-ejb-jar.xml deployment descriptor files with the required references

Refer to the course notes, the EJB 2.0 specification from Sun Microsystems, and the API documentation for assistance.

Module: EJB

Creating EAR files for deployment

An EAR file is an Enterprise Archive. It is used to deploy a whole enterprise application, which may include web components (servlets, JSPs) and EJB components, in a single file.

• WAR files - contain web files (servlets, JSP, HTML, images, etc) • JAR files - contain EJBs

Page 185: J2EE Weblogic Documentation

185

• EAR files - contain embedded WAR and JAR files

Directory structure

Like any Java archive, a particular directory structure is necessary, and a new deployment descriptor file - application.xml.

The correct directory structure for an EAR file would look like:

- MyEJBs.jar - MyWebApp.war / META-INF - application.xml

application.xml deployment descriptor

The application.xml deployment descriptor is not very complex. Basically, it defines:

• the names of the JAR and WAR files inside your application • the root path of the web tree where your web application files should be placed under • declaration of any security roles that are global to the whole application

An example is shown below:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN' 'http://java.sun.com/j2ee/dtds/application_1_2.dtd'> <application> <display-name>Transactional Application Test</display-name> <module> <web> <web-uri>MyWebApp.war</web-uri> <context-root>mywebapp</context-root> </web> </module> <module> <ejb>MyEJBs.jar</ejb> </module> <security-role> <role-name>supplier</role-name> </security-role> </application>

Page 186: J2EE Weblogic Documentation

186

Notes about EAR files (and why they are good)

Imagine a simple application that contains one servlet (or JSP) in a WAR file and one stateless session EJB in a JAR file. When you deploy these separately, recall that you had to deploy the EJB first, and then take the stubs and skeleton files that were generated by compiling the EJB, and include a copy of these stubs and skeletons in your WAR file, so the servlet could access them. Obviously it is generally not desirable to have two copies of the same files in two different places (WAR and JAR) if possible, but with separate deployment, it was the only option.

One of the main advantages of deploying an application as an EAR file is that this redundancy can be removed. When the application server deploys the EAR file, it extracts the contents of the file, and deploys:

1. JAR files (EJBs) first 2. WAR files (web) second

but more importantly, it arranges the Java classloaders so that Java code contained in the WAR file can access any of the Java class files contained in the JAR file.

So, you should create a JAR file for your EJB(s), and in this JAR file put in the EJB stubs and skeletons and any other helper classes you may create. The WAR file now does not need to contain any stubs and skeletons - it can remain "pure" and contain only web components.

Referencing EJBs that your components use

The other thing you should do when creating the deployment descriptors for your web apps and EJBs is declare any EJB references that they make.

e.g. if your servlet/JSP calls an EJB session bean, in the web.xml deployment descriptor, it should include an <ejb-ref> tag to declare this to the container.

e.g. if your EJB session bean calls an EJB entity bean, in the ejb-jar.xml deployment descriptor, for your session bean you should include an <ejb-ref> tag to declare this to the container.

As well as declaring the reference to the container (and to anyone else who may in future reuse your EJBs), it allows you to remove the need for hard-coded JNDI names inside your servlet/JSP/EJB code, when looking up an EJB's home interface.

Have a look at the use of the <ejb-ref> tags in the web.xml deployment descriptor in the example below. Also notice the JNDI lookup code in the servlet, and that it now uses a name which maps into the deployment descriptor, not a hard-coded JNDI name. The mapping from the "java:comp/env/ejb/..." name into the actual JNDI name is specified in the weblogic.xml deployment descriptor.

Page 187: J2EE Weblogic Documentation

187

In addition, if you have two EJBs in the same JAR file, and one is calling the other, you should use the <ejb-link> tag to indicate to the deployer that the EJB being called is actually in the same JAR file, so the deployer make make some optimisations.

Example: servlet/JSP referencing an EJB

In your servlet/JSP file, the section of code which looks up the EJB is like:

// This is the servlet/JSP file // Lookup the home interface MyEJBHome ejbHome; Object obj = ctx.lookup("java:comp/env/ejb/MyEJB"); ejbHome = (MyEJBHome) javax.rmi.PortableRemoteObject.narrow(obj, MyEJBHome.class);

Notice that this lookup uses the name java:comp/env/ejb/MyEJB.

Then in the web.xml deployment descriptor in the WAR file, there should be a declaration of the EJB reference as follows.

<!-- This is the web.xml file --> <ejb-ref> <ejb-ref-name>ejb/MyEJB</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>pkg.MySessionHome</home> <remote>pkg.MySession</remote> </ejb-ref>

Then in the weblogic.xml deployment descriptor in the WAR file, there should be a mapping from the name by which the EJB is referenced in the Java source code (java:comp/env/ejb/MyEJB) into the actual JNDI name that the bean is advertised as in the server. In the example below, it assumes that the actual JNDI name of the EJB is "johns-ejb", and that the name by which it is called in the servlet should be mapped into this JNDI name.

<!-- This is the weblogic.xml file --> <reference-descriptor> <ejb-reference-description> <ejb-ref-name>ejb/MyEJB</ejb-ref-name> <jndi-name>johns-ejb</jndi-name> </ejb-reference-description> </reference-descriptor>

Recall that the <jndi-name> of an EJB is configured in that EJB's weblogic-ejb-jar.xml file. In the example above, the weblogic-ejb-jar.xml file would have the JNDI name configured as "johns-

ejb" even though the class names of the home and remote interface are MySessionHome.class and MySession.class respectively.

Page 188: J2EE Weblogic Documentation

188

Example: session bean referencing entity bean

The following example is similar to the one above, but demonstrates specifying an EJB reference from one EJB (session bean) to another (entity bean).

First, in the session bean Java code, you would look up the entity bean's home interface as follows:

// This is the session bean Java file // Lookup the home interface MyEntityHome ejbHome; Object obj = ctx.lookup("java:comp/env/ejb/MyEntity"); ejbHome = (MyEntityHome) javax.rmi.PortableRemoteObject.narrow(obj, MyEntityHome.class);

Then in the ejb-jar.xml file, you declare the beans. The declaration, including the reference, might look as follows:

<!-- This is ejb-jar.xml --> <enterprise-beans> <session> <ejb-name>MyFirstSessionBean</ejb-name> <home>pkg.MySessionHome</home> <remote>pkg.MySession</home> <ejb-class>pkg.MySessionBean</ejb-class> ... <ejb-ref> <ejb-ref-name>ejb/MyEntity</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>pkg.MyEntityHome</home> <remote>pkg.MyEntity</remote> <ejb-link>MyFirstEntityBean</ejb-link> </ejb-ref> </session> <entity> <ejb-name>MyFirstEntityBean</ejb-name> <home>pkg.MyEntityHome</home> <remote>pkg.MyEntity</remote> <ejb-class>pkg.MyEntityBean</ejb-class> ... </entity> </enterprise-beans>

Note that this time an <ejb-link> is used which specifies the ejb-name of the bean that is being linked to. This allows the container to recognise that the referenced bean is local, and make some optimisations.

Finally, the weblogic-ejb-jar.xml file is used to map from the <ejb-ref-name> into the actual JNDI name by which the beans are advertised.

<!-- This is the weblogic-ejb-jar.xml file --> <weblogic-enterprise-bean> <ejb-name>MyFirstSessionBean</ejb-name> <reference-descriptor> <ejb-reference-description>

Page 189: J2EE Weblogic Documentation

189

<ejb-ref-name>ejb/MyEntity</ejb-ref-name> <jndi-name>janes-entity-bean</jndi-name> </ejb-reference-description> </reference-descriptor> <jndi-name>janes-session-bean</jndi-name> </weblogic-enterprise-bean> <weblogic-enterprise-bean> <ejb-name>MyFirstEntityBean</ejb-name> <jndi-name>janes-entity-bean</jndi-name> </weblogic-enterprise-bean>

Steps in deploying a Java application with many parts

1. Compile your EJB code using javac, as normal

cd jar

javac mypackage/*.java

2. Create an EJB jar file, using the same jar syntax as normal

jar cvf ../ear/MyEJBs.jar *.*

3. Run the appc compiler on your EJB JAR file to generate the generated stubs and skeletons.

java weblogic.appc MyEJBs.jar

4. Compile your servlet. Note that because the servlet will make references to some of the classes in the EJB, you may need to adjust your Java CLASSPATH while compiling so that the compiler can access the EJB home and remote interface class files.

cd war/WEB-INF/classes

javac *.java

5. Create WAR file, as normal.

jar cvf ../ear/webapp.war *.*

6. Make sure the JAR file and WAR file end up in the correct directory structure to make an EAR file, and that you have created your application.xml deployment descriptor. Then use the 'jar' command (same syntax) to create the EAR file.

jar cvf ../myapp.ear *.*

Using Eclipse to generate EAR files

Eclipse WTP/Workshop treats an EAR as a special type of Project - an Enterprise

Application Project.

Page 190: J2EE Weblogic Documentation

190

You create a new Enterprise Application Project (New -> Project -> Enterprise Application Project) and use the wizard to select the various projects (J2EE Modules :-) which will be part of this EAR.

You can later add more by editing the EAR project properties (RMB -> Properties -> J2EE Module Dependencies) and selecting ANY project in the current workspace, but also internal/external JAR files!

You will notice that from now on, the component projects (war, ejb etc) will now have a new subfolder called "Enterprise Application Libraries (ear)". This indicates the current projects that depend on your component project.

You can directly deploy the EAR file (by adding the project to the server definition) or you can Export the EAR file using RMB -> Export -> EAR file

One of the side effects of having an EJB project as part of an EAR is that you can now generate EJB Client jar's - these are files that contain the interfaces & stubs which allow ordinary Java clients (such as applets & AWT/SWING applications) to access the EJB.

An example EAR file

Extract the pieces of the following EAR file to get an idea of the directory structures to use, etc.

Page 191: J2EE Weblogic Documentation

191

Module: XML

Lab exercise - Parsing XML in a JSP

XML is the Extensible Markup Language. In this exercise, we create a JSP that reads in and parses an XML file.

Level of Difficulty: 1 (easy) Estimated time: 20 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Start your WebLogic server running in the background

XML

XML is a language for describing structured information. It uses a tag-based syntax like HTML. However, for XML to be useful, it is typically necessary to parse it, or convert it into a different format. This exercise introduces XML parsing. There are three main kinds of XML parsers: SAX, DOM and StAX.

• SAX stands for "Simple API for XML" and supports sequential parsing of XML documents. The document is read in, and parsed in the order in which the tags appear. Each time a tag starts or ends, an event is triggered. An application programmer writes a set of event handlers to respond to these events from the parser.

• DOM stands for "Document Object Model" and when parsing an XML document, builds an in-memory structured representation of the document. The whole document is read in at once, and the DOM tree is created in memory as a Java data structure and can be navigated by calling methods.

• StAX stands for "Streaming API for XML" and is capable of parsing and writing an XML Document. This API is very resource efficient because it only reads parts of the XML document into memory at once. This way it provides similar capabilities to DOM while maintaining a similar performance to SAX.

In this exercise we use a SAX parser inside a JSP to read in and display an XML file.

Parsing an XML file with SAX

There are three main files required for this exercise: an XML file, a JSP, and a Java class which handles the XML processing.

Before beginning, you should set up the directory structure for a WAR file.

XML file

Page 192: J2EE Weblogic Documentation

192

The first step is to create the XML file that we will parse. Create the following file as addressbook.xml.

<addressbook> <entry id="1"> <name>Wayne</name> <address>Room 4/130</address> <email>[email protected]</email> <phonextn>4469</phonextn> <birthday>2001-01-01</birthday> </entry> <entry id="2"> <name>Maolin</name> <address>Room 4/520</address> <email>[email protected]</email> <phonextn>1858</phonextn> <birthday>2001-01-01</birthday> </entry> </addressbook>

JSP file

The next step is to create a JSP file called printout.jsp as shown below.

<%@ page import="javax.xml.parsers.*"%> <%@ page import="org.xml.sax.*"%> <%@ page import="javax.xml.parsers.*"%> <%@ page import="org.xml.sax.helpers.DefaultHandler" %> <H1> Parsed XML document </H1> <% InputStream is = application.getResourceAsStream("/addressbook.xml"); try { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); SAXParser myParser = spf.newSAXParser(); DefaultHandler h = new handlers.MyHandler(out); myParser.parse(is, h); } catch (Exception e) { } %>

Notice that this JSP has no reference to the structure of the XML file, or what to do with it. All the JSP is responsible for is opening an InputStream to access the XML file, and then

Page 193: J2EE Weblogic Documentation

193

creating a SAX parser to read from the XML file.

The rules for how to process the XML file are contained in the handler class. In the example above, this is the Java object h, and the class is handlers.MyHandler.

Also notice that the example says setValidating(false). This means that the parser will not attempt to validate the XML document against a DTD. If we had requested a validating parser, a DTD file would also be necessary to describe the format/rules of the XML document.

Handler class

The final main section of code required is a Java class that will act as the handler for the SAX parser. It is this file that determines what will happen to the XML.

Create the following file as WEB-INF/classes/handlers/MyHandler.java.

package handlers; import org.xml.sax.*; import javax.xml.parsers.*; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.helpers.DefaultHandler; import javax.servlet.jsp.*; public class MyHandler extends DefaultHandler { JspWriter out; public MyHandler(JspWriter out) { this.out = out; } public void startDocument() throws SAXException { try { out.println("<p>Start of document</p>\n<p>"); } catch (Exception e) { } } public void endDocument() throws SAXException { try { out.println("</p>\n<p>End of document</p>"); } catch (Exception e) { } } public void startElement(String uri, String name,String qName, Attributes attrs) throws SAXException { } public void endElement(String uri, String name, String qName)

Page 194: J2EE Weblogic Documentation

194

throws SAXException { try { if (name.equals("entry")) { out.println("</p><p>"); } } catch (Exception e) { } } public void characters (char ch[], int start, int length) throws SAXException { try { out.println(new String(ch, start, length) + "<BR/>"); } catch (Exception e) { } } public void processingInstruction(String target, String data) { } public void ignorableWhitespace(char ch[], int start, int length) { } }

Note that this handler class extends DefaultHandler. It has a number of methods that can be implemented as event handlers. As the parser is parsing the XML document, it will trigger events that will call your event handler methods.

You will need to compile this file. Change into the WEB-INF/classes directory, and compile the file:

javac handlers/MyHandler.java

Packaging and deployment

The final step is to package and deploy the files as a web application (WAR file).

First, create a WEB-INF/web.xml file with no information, as follows.

<?xml version="1.0" ?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 1.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> </web-app>

Then create the WAR file, and deploy it into WebLogic and test it by opening the JSP in your browser.

Additional Exercise

Page 195: J2EE Weblogic Documentation

195

This doesn't present a nice interface to the user. Modify the jsp and handler class to result the results as a table.

Notes

It is never a good idea to embed HTML into a handler class. The best practice would be for the handler class to populate a collection of javabeans which can then be presented via the JSP.

Apache Commons Digester (http://jakarta.apache.org/commons/digester) is one example of a popular java library to do this automatically. XMLBeans is another example.

Page 196: J2EE Weblogic Documentation

196

Module: XML (DOM)

Lab exercise - Writing XML via DOM

DOM stands for "Document Object Model" and when parsing an XML document, builds an in-memory structured representation of the document. The whole document is read in at once, and the DOM tree is created in memory as a Java data structure and can be navigated by calling methods. In this exercise we use a DOM parser inside a JSP to display an XML file.

Level of Difficulty: 3 (medium) Estimated time: 45 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Start your WebLogic server running in the background • Completed the XML SAX JSP lab

Understanding the code

In the section below, we will walk through the code provided and give an explanation of what is happening. Let's create a file called dom.jsp

<%@ page import="javax.xml.parsers.*" %> <%@ page import="org.w3c.dom.*" %> <%@ page import="java.io.*" %> <html><head> <title>DOM Parser</title> </head> <body> <h1>XML DOM parser test</h1> <hr />

• The java.xml.parsers package contains some basic methods for working with XML parsers (either DOM or SAX).

• The second package, org.w3c.dom, contains DOM-specific objects and methods. There is also a related package, org.w3c.sax that we will use in another exercise.

<% // Create the stream we will read from InputStream is = application.getResourceAsStream("/addressbook.xml"); // Create an instance of the DOM parser and parse the document DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(is); // Begin traversing the document

Page 197: J2EE Weblogic Documentation

197

traverseTree(doc, out); %>

This section of code is where we set up the DOM parser to parse the document. The steps involved are:

1. Create a InputStream object that refers to the particular XML file we want to open. getResourceAsStream() will read a file from our war file.

2. Get a reference to a DocumentBuilderFactory and a DocumentBuilder object. The need for this step is because there are potentially many different implementations of DOM parsers available. For example, the implementation that we will be using is called Xerces, and is part of the Apache project. Another implementation of a DOM parser comes from IBM.

From an application programmer perspective, you aren't usually interested in which implementation of the DOM parser is being used. You just want to get access to whichever DOM parser happens to be installed on the system you are using. The DocumentBuilderFactory class provides a generic way of locating the "default" DOM parser implementation that is installed on any system. When you call DocumentBuilder.newInstance(), it returns a reference to some implementation of a DOM-compliant parser. The DocumentBuilder object refers to the actual DOM parser itself.

3. Parse the XML file, by calling the parse() method on the DocumentBuilder object. With DOM, whenever you call the parse() method, in return you get back a reference to a Document object that is the starting point for the parsed DOM tree.

If there was a syntax error during parsing and the DOM tree could not be built, then a Java exception would be thrown and an error message would appear in the browser. This error message will look like the message generated when testing well-formedness of XML documents in an earlier exercise.

4. Finally, as a result of parsing we have a Document object which represents a DOM tree that we can traverse. In this exercise, there is a specific Java method for performing the traversal, called traverseTree(). We call the traverseTree() method and pass to it a reference to the Document, and also to the pre-defined JSP object called out, which is used for printing data into the HTML code that is sent back to the user's web browser.

Here we declare a Java method that will be used to perform the traversal. We will call this method to handle each node in the DOM tree that has been built in memory by the parser.

<%! /** Handles one node of the tree. It accepts any type of node, and will check the node type before processing it. This function is recursive - if one node contains other "sub-nodes", this function will call itself again to process the sub-nodes. @param currnode the current node @param out where to write the output */ private void traverseTree(Node currnode, JspWriter out) throws Exception {

Page 198: J2EE Weblogic Documentation

198

// If the current node is null, do nothing if(currnode == null) { return; } // Find the type of the current node int type = currnode.getNodeType(); // Check the node type, and process it accordingly switch (type) {

Notice that for the current node we are processing, we first find out the node type, and then use a switch statement to branch to a block of code to handle that particular type of node.

Now we will examine each of the different handlers in turn.

/* * Handle the top-level document node. * Just print out the word "DOCUMENT", and then get the * root element of the document, and process it using * the traverseTree method */ case Node.DOCUMENT_NODE: { out.println("<p>DOCUMENT</p>"); traverseTree (((Document)currnode).getDocumentElement(), out); break; }

There is only one "document" node for each XML document. In this case, first we just print a message to indicate that we have encountered a document node. Seconly, we call the getDocumentElement() method to retrieve the root node of the document. With that root node, we then call the traverseTree() method to handle it. Note that from within the traverseTree() method, we are calling the same method again. This is an example of recursion in programming.

/* * Handle an element node

Page 199: J2EE Weblogic Documentation

199

* This is the most complex type of node dealt with. * First, print out the name of the element, before * processing any other sub-nodes (i.e. a preorder traversal). * Secondly, check if this element has any attributes, and * if it does, process those next, by calling the traverseTree() * method. * Finally, retrieve the children of this node (if any), and * process them one by one using the traverseTree() method. */ case Node.ELEMENT_NODE: { String elementName = currnode.getNodeName(); out.println("<p>ELEMENT: [" + elementName + "]</p>"); if (currnode.hasAttributes()) { NamedNodeMap attributes = currnode.getAttributes(); for (int i=0; i < attributes.getLength(); i++) { Node currattr = attributes.item(i); traverseTree(currattr, out); } } NodeList childNodes = currnode.getChildNodes(); if(childNodes != null) { for (int i=0; i < childNodes.getLength() ; i++) { traverseTree (childNodes.item(i), out); } } break; }

This is the most complex of the handlers. There are three main parts to it:

1. Find out the name of this element (elementName) and print it out. 2. Check to see if this element has any attributes associated with it. If it does, then we

retrieve them (attributes) and then loop through them one by one using a for loop. In DOM, every attribute is treated as a Node as well. So in this example, for each attribute, we simply call the traverseTree() method to handle it.

3. The final step in this example is to process any child nodes of this element. We retrieve a list of all the child nodes, and use a for loop to process each one in turn, using the traverseTree() method to do the processing. Note that children of element nodes are typically either text nodes (if the element contains text) or further element nodes (if the element contains other XML elements nested inside it).

Note that this is where we decide the traversal algorithm to use. In this case, we are using a preorder traversal, which is the most common kind of traversal for processing documents with DOM.

/* * Handle attribute nodes. * Just print out the word "ATTRIBUTE", and then the name

Page 200: J2EE Weblogic Documentation

200

* and value of the attribute itself. */ case Node.ATTRIBUTE_NODE: { String attributeName = currnode.getNodeName(); String attributeValue = currnode.getNodeValue(); out.println("<p>ATTRIBUTE: name=[" + attributeName + "], value=[" + attributeValue + "]</p>"); break; }

In the case of attribute nodes, we just retrieve the attribute name and value, and print them out.

Attribute nodes are leaf nodes in the DOM tree. They have no children to process.

/* * Handle text nodes. * Trim whitespace off the beginning and end of the text. * Then check whether there is any real text, and if so, * print it out. This avoids printing out text nodes that * consist of only whitespace characters. */ case Node.TEXT_NODE: { String text = currnode.getNodeValue().trim(); if (text.length() > 0) { out.println("<p>TEXT: [" + text + "]</p>"); } break; } } } %>

In the case of text nodes, we retrieve the value, and "trim" it. Trimming it means that we remove whitespace from either end of the string.

If the resulting string has any characters left after trimming, then we print it out. This avoids printing text nodes that consist entirely of whitespace.

Text nodes are leaf nodes in the DOM tree. They have no children to process.

Adding indenting to show nesting level

First, copy your dom.jsp file to a new file named dom1.jsp. Make the following changes to

Page 201: J2EE Weblogic Documentation

201

dom1.jsp.

At the moment, the sample JSP prints all nodes at the same level of indenting (against the left-hand margin). The first goal of this exercise is to modify the code so that each time the traversal algorithm enters a new level of "depth" in the DOM tree, we indent the output one level further, and each time the traversal algorithm goes up one level in the DOM tree, we remove the indenting.

The easiest way to achieve indenting is to use the HTML <blockquote> tag. When you want to increase the indenting by one level, print out the following line of HTML:

<blockquote>

When you want to decrease the indenting by one level, print out the corresponding closing tag:

</blockquote>

Think about how the code works. Each time you process a node, the traverseTree() method is called. Another way to think of it is that the start of the traverseTree() method is the time at which you "enter" (i.e. start processing) a node, and the end of the traverseTree() method is when you "exit" (i.e. finish processing) the node.

The solution is quite short - it can be done by adding only two lines of code - but it does require you to think about and understand how the code works (particularly the traverseTree() method).

Formatting the data in a table

The next exercise with the DOM parser is to print out the data from the addressbook.xml file in a HTML table. Your resulting output should look something like the following:

Name Address Email Phonextn Birthday

Wayne Room 4/536 [email protected] 1872 2001-01-01

Maolin Room 4/520 [email protected] 1858 2001-01-01

Copy the original dom.jsp file to become dom2.jsp, and make your changes to dom2.jsp.

Printing a subset of the data

The final exercise is to selectively print data from the DOM tree. Copy the original dom.jsp

Page 202: J2EE Weblogic Documentation

202

file to become dom3.jsp, and make your changes to dom3.jsp.

Suppose that using the addressbook.xml file, we only want to print out a list of names and email, and none of the other information.

Modify the code so that only the <name> and <email> element values are printed. It's not as easy as it sounds - remember that the actual value isn't stored in the DOM "element" node, it is stored in a "text" node that is a child of the element.

Module: XML

Lab exercise - Transforming XML in a JSP

We can use Extensible Stylesheet Language Transformations (XSLT) to transform XML into different formats. We also use XPATH expressions to match elements and attributes.

Level of Difficulty: 2 (medium) Estimated time: 40 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Start your WebLogic server running in the background • Finished SAX and DOM labs.

Creating an XSLT sample file

We will use the existing addressbook.xml file to transform using some XSLT files we will write.

First, let's create addressbook1.xsl

<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>

This is the header of our XSLT file:

• Since this is an XML document, the first line must start with <?xml

Page 203: J2EE Weblogic Documentation

203

• We then indicate that this is a stylesheet which will be performing XSLT transformations. Note that there is a synonym called <xsl:transform> instead of <xsl:stylesheet>

• Finally, the <xsl:output> element tells the XSLT processor what type of output can be expected. In this case, we will be using HTML. This could also equally be 'xml' or 'text'

• See http://www.w3.org/TR/xslt#output for a definitive syntax of this element.

<xsl:template match="/"> <html> <body> <p><i>Start of document</i></p> <!-- Go and apply all the templates for the root --> <xsl:apply-templates/> <p><i>End of document</i></p> </body> </html> </xsl:template>

This element is called once since XML documents represent a logical tree. When the parser reads in the first, or "root" element, this template is matched.

• Note that we display some header/footers around the main body • When <xsl:apply-template> is reached, the XSLT processor will attempt to match the

next template, in priority order.

The rest of the file is fairly straight forward - for each element we encounter, we emit some boilerplate code

<xsl:template match="addressBook"> <h1>Address Book</h1> <!-- Go and apply all the templates for the root --> <xsl:apply-templates/> </xsl:template> <xsl:template match="entry"> <hr/> <h2>Entry <xsl:value-of select="@id"/></h2> <!-- Go and apply all the templates for the root --> <xsl:apply-templates/> </xsl:template> <xsl:template match="name"> <p>Name: <!-- Go and apply all the templates for the root --> <xsl:apply-templates/> </p> </xsl:template> <xsl:template match="address"> <p>Address: <!-- Go and apply all the templates for the root --> <xsl:apply-templates/> </p> </xsl:template> <xsl:template match="email"> <p>E-mail: <!-- Go and apply all the templates for the root -->

Page 204: J2EE Weblogic Documentation

204

<xsl:apply-templates/> </p> </xsl:template> <xsl:template match="phonextn"> <p>Phone: <!-- Go and apply all the templates for the root --> <xsl:apply-templates/> </p> </xsl:template> </xsl:stylesheet>

Notice that for <entry> node we pick up the attribute id, so if we found <entry id="99">, the <xsl:value-of ..> element would return 99

When the XSLT processor has no more matches, it will then return up the parsing tree and will emit the element text contents.

Let's try this out on the command line

java org.apache.xalan.xslt.Process -IN addressbook.xml -XSL addressbook1.xsl

This invokes the Apache Xalan XML processor and returns the result to your terminal. You can use the -OUT addressbook.htm option to save the file, or use standard redirection "> addressbook.htm" to save this to a file.

Try the result in a web browser.

Using a web browser to do transformations

Most modern browsers (Internet Explorer 5+, Mozilla/Firefox, Opera) have a built-in XSLT transform engine. If you modify your addressbook.xml file with the following header on the 2nd line after the <?xml > element...

<?xml-stylesheet type="text/xsl" href="addressbook.xsl"?>

If you open this in your browser (either directly or via a web page), you will find that this is also displayed transformed into HTML.

Using Java to do transformations

Here is a JSP that will read in addressbook.xml and addressbook.xsl to use the JAXPack to do XSLT transforms.

<%@ page import="javax.xml.parsers.*" %> <%@ page import="org.w3c.dom.*" %> <%@ page import="javax.xml.transform.*" %> <%@ page import="javax.xml.transform.dom.*" %>

Page 205: J2EE Weblogic Documentation

205

<%@ page import="javax.xml.transform.stream.*" %> <%@ page import="java.io.*" %> <html><head> <title>DOM Parser</title> </head> <body> <h1>XML DOM parser test</h1> <hr /> <% // Create the stream we will read from InputStream is = application.getResourceAsStream("/addressbook.xml"); InputStream xsls = application.getResourceAsStream("/addressbook.xsl"); StreamSource xmlSource = new StreamSource(is); StreamSource xsltSource = new StreamSource(xsls); // Create a StreamResult pointing to the output file StreamResult fileResult = new StreamResult(out); // Load a Transformer object and perform the transformation TransformerFactory tfFactory = TransformerFactory.newInstance(); Transformer tf = tfFactory.newTransformer(xsltSource); tf.transform(xmlSource, fileResult); %>

The main method we use is javax.xml.transform.Transformer which is part of the standard J2SE implementation from 1.4 onwards.

More exercises: XSLT functions

XSLT provides some functions such as count(), concat(), substring() and so on.

Let's try some. Add this into the main root template (... match="/"... )

<h3>Summary</h3> <p>There are <xsl:value-of select="count(//name)"/> names</p> <p>There are <xsl:value-of select="count(//*)"/> nodes</p>

Here are some quick idioms to remember:

• //name means "any <name> element under the root / element" • //* means any element

Try it out. Note that this counts the number of names in our addressbook.xml and also the total number of nodes.

Advanced exercises:

Page 206: J2EE Weblogic Documentation

206

Printing a subset of the data

How about displaying only <name> elements?

HINT: Just removing the match="address" & so on templates won't work - the text contents of the nodes will still be displayed. Try replacing them all with a match="*" template

Formatting the data in a table

The final exercise with XSLT is to convert your results to a table looking somewhat like this:

Name Address Email Phonextn Birthday

Wayne Room 4/536 [email protected] 1872 2001-01-01

Maolin Room 4/520 [email protected] 1858 2001-01-01

Module: Web Services

Lab exercise 1 - Exploring RPC Web Services

In this exercise, we will view a public Web Services registry (http://www.xmethods.com) and then will use the Weblogic universal test client to explore an existing web service, http://cdyne.com/creditcardverify/luhnchecker.asmx

Level of Difficulty: 1 (easy) Estimated time: 20 minutes Pre-requisites:

Finding Web services

(from wikipedia)

Universal Description, Discovery and Integration (UDDI) is a platform-independent, XML-based registry for businesses worldwide to list themselves on the Internet.

UDDI is an open industry initiative, sponsored by OASIS, enabling businesses to publish service listings and discover each other and define how the services or software applications interact over the Internet. A UDDI business registration consists of three components:

• White Pages — address, contact, and known identifiers; • Yellow Pages — industrial categorizations based on standard taxonomies; • Green Pages — technical information about services exposed by the business.

Page 207: J2EE Weblogic Documentation

207

IBM, Microsoft and SAP supported a publicly accessible Universal Business Registry but closed this down on January 2006.

Fortunately, there are 3rd party registries still available on the internet. http://xmethods.com is one such provider.

Using Xmethods.com

Start a browser and navigate to: http://xmethods.com

You can browse this list for many publicly available web services. Note that the listing includes a Publisher, Style, ServiceName, Description and Implementation column.

Clicking on the service name will reveal a description page of the web service.

On this page is:

• The WSDL address (and alongside this is a "Analyze WSDL" link which you can use to summarise the web service definition file)

• Owner details • Description • Informational website link • End points (optional) • Contributed Clients (where other people have written clients for this webservice in various

languages) • Usage notes

If you wish, you can download the sample clients other people have written, but for the moment, you can scroll down to the bottom to see a detailed description and usage notes of this service. This information is not usually automatically generated or used by programs.

The key information here is the location of the WSDL file.

Using the Weblogic Universal Test Client

Weblogic includes a simplistic test client which you can use to view and try out publically available web services.

Start your weblogic server (either via the command line or via Weblogic Workshop)

Use the URL http://localhost:7001/wls_utc and enter the following WSDL URL: http://cdyne.com/creditcardverify/luhnchecker.asmx?WSDL

Page 208: J2EE Weblogic Documentation

208

You can then press [TEST] and you will see the various operations that this web service supports.

In this case, you should see an operation called CheckCC which has a single parameter called CardNumber

Enter: 4111111111111111 and press the [CheckCC] button.

You should then get the following results screen

Page 209: J2EE Weblogic Documentation

209

Now we can see the XML representation of this transaction. We have our SOAP Envelope and Body for both the request (invocation of the web service) and the response (results returned).

As you can see, you provide the parameter as an XML message called <CheckCC> and the response comes back as an XML message called <CheckCCResponse>

These are just self-defined XML elements under the namespace "http://ws.cdyne.com".

Alternative testing points

Many web service frameworks (include Weblogic) provide an internal test client. The CDYNE credit card checker is written in Microsoft .NET and this provides an internal test client at the address http://cdyne.com/creditcardverify/luhnchecker.asmx

Try this out. Note that this web service supports not only SOAP 1.1 but SOAP 1.2 and a HTTP interface as well.

WSDL file

Now let's look at the WSDL definition of the web service. By convention, most web service frameworks also support returning the WSDL for the web service by using the ?WSDL (or ?wsdl) query string on the endpoint URL

Page 210: J2EE Weblogic Documentation

210

So for the CDYNE credit card checker, we use http://cdyne.com/creditcardverify/luhnchecker.asmx?WSDL

Try this out. Most browsers will show you the XML returned as a formatted document like:

Let's look at the WSDL in more detail:

Firstly, we have some header information: All WSDL documents must have one top level element - the <definitions> tag. This contains the (optional) name of the web service and the target namespace. (note: web browsers sometimes omit the namespace definitions so I added them here)

<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://ws.cdyne.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

targetNamespace="http://ws.cdyne.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

We then have the definition of the XML schemas for the messages

<wsdl:types> <s:schema elementFormDefault="qualified" targetNamespace="http://ws.cdyne.com/"> <s:element name="CheckCC"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="CardNumber" type="s:string" /> </s:sequence> </s:complexType>

Page 211: J2EE Weblogic Documentation

211

</s:element> <s:element name="CheckCCResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="CheckCCResult" type="tns:ReturnIndicator" /> </s:sequence> </s:complexType> </s:element> <s:complexType name="ReturnIndicator"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="CardType" type="s:string" /> <s:element minOccurs="1" maxOccurs="1" name="CardValid" type="s:boolean" /> </s:sequence> </s:complexType> <s:element name="ReturnIndicator" type="tns:ReturnIndicator" /> </s:schema> </wsdl:types>

This basically defines the following types in pseudocode. Note that the s: prefix represents the standard W3C XML Schema

CheckCC { String CardNumber } CheckCCResponse { ReturnIndicator CheckCCResult } ReturnIndicator { String CardType Boolean CardValid }

Next, we have our SOAP message definitions. Basically, these are the parameters we pass and receive from our operations. The ones displayed below are relevant to SOAP 1.1

<wsdl:message name="CheckCCSoapIn"> <wsdl:part name="parameters" element="tns:CheckCC" /> </wsdl:message> <wsdl:message name="CheckCCSoapOut"> <wsdl:part name="parameters" element="tns:CheckCCResponse" /> </wsdl:message>

Next, our <portType> element. Basically this defines what operations exist on for the given port.

<wsdl:portType name="LUHNCheckerSoap"> <wsdl:operation name="CheckCC"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> Enter 4111111111111111 to test a good credit card number.</wsdl:documentation> <wsdl:input message="tns:CheckCCSoapIn" /> <wsdl:output message="tns:CheckCCSoapOut" /> </wsdl:operation> </wsdl:portType>

Page 212: J2EE Weblogic Documentation

212

ie: our operation is CheckCC with the input parameter message called CheckCCSoapIn and the return message called CheckCCSoapOut

Next, <binding> element. This maps the portType to the specific protocol (in this case, SOAP over HTTP, which is represented by the transport attribute "http://schemas.xmlsoap.org/soap/http").

<wsdl:binding name="LUHNCheckerSoap" type="tns:LUHNCheckerSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="CheckCC"> <soap:operation soapAction="http://ws.cdyne.com/CheckCC" style="document" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding>

Note that the style is document and the encoding usage is literal. This is the WS-I standard which supplants the traditional RPC SOAP encoding.

Finally, we define the service itself. The previous elements defined an abstraction of the web service, we now come to the implementation of the web service itself. This maps the service end point (which is the <port> element here) to a physical address (in this case, "http://cdyne.com/creditcardverify/luhnchecker.asmx" ). If we we using alternative transports such as HTTP, this would be reflected here too. Note that for clarity I have omitted the bindings for SOAP12 and HTTP.

<wsdl:service name="LUHNChecker"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> Validates Credit Cards to ensure proper input... </wsdl:documentation> <wsdl:port name="LUHNCheckerSoap" binding="tns:LUHNCheckerSoap"> <soap:address location="http://cdyne.com/creditcardverify/luhnchecker.asmx" /> </wsdl:port> ... omitted other port bindings ... </wsdl:service>

This essentially declares that the service called "LUHNChecker" has a SOAP 1.1 implementation at http://cdyne.com/creditcardverify/luhnchecker.asmx

Lab exercise 2 - Exploring other Web Services

Now that you have tried one web service, why not try other web services from xmethods.com?

Another good source of web services is http://www.webservicex.net.

Page 213: J2EE Weblogic Documentation

213

Reflection

Whilst fundamentally a simple concept, the Web services standards produce quite verbose XML documents for what could be very simple RPC style services. This complexity is needed to allow web services to be self describing, portable and interoperable between systems and languages.

Our next step is to write a client for a web service then we will implement a very simple web service later.

Module: Web Services

Lab exercise 3 - Writing a simple RPC client

In this exercise we will create a simple RPC client

Page 214: J2EE Weblogic Documentation

214

Level of Difficulty: 1 (easy) Estimated time: 20 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Completed Lab exercise 1 - exploring Web services

JAX-RPC Static clients

JAX-RPC is the Java standard for web services. It encapsulates much of the complexity of communicating via SOAP and also maps many Java value classes to the standard XML data types.

In this lab, we will use Weblogic to generate client side stubs which will be invoked by our Java class. Note that each JAX-RPC implementation generates different stub classes, so be aware that you will need to re-generate the Stubs for each platform you are developing with (eg: Apache AXIS)

Create new project

First step is to create a new development project ie: New -> Project -> Dynamic Web Project & set the "Annoted Web Service Facets (minimum)" configuration & name the project labws

Then configure the build path:

1. Project -> Properties -> Java Build Path 2. Select the Libraries tab & Add External Archives

(or go Right Mouse Button -> Build Path -> Add External Archives) 3. Add /opt/bea10/wlserver_10.0/server/lib/wseeclient.jar (or the equivalent path in your

configuration)

Generating a static client stub

If you have weblogic 10.3 you can use the ClientGen web service wizard to create a client, however, for the weblogic 10.0 users you will need to have the following ANT build.xml file to build the stubs.

File -> New -> XML & call the file build.xml

(you can import the build.xml here )

<?xml version="1.0" encoding="UTF-8"?> <project name="webservicesLab" default="build-client" basedir="."> <description>Weblogic JWS builder</description> <target name="init"> <path id="weblogic.class.path"> <pathelement path="${java.class.path}" /> <pathelement path="${env_var:WEBLOGIC_CLASSPATH}" />

Page 215: J2EE Weblogic Documentation

215

<fileset dir="/opt/bea10/wlserver_10.0/server/lib"> <include name="weblogic.jar" /> </fileset> </path> </target> <target name="build-client" depends="init"> <taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask"> <classpath refid="weblogic.class.path" /> </taskdef> <clientgen type="JAXRPC" wsdl="http://cdyne.com/creditcardverify/luhnchecker.asmx?wsdl" destDir="src" generateAsyncMethods="false" classpath="${java.class.path}" autoDetectWrapped="true" packageName="ws" /> </target> <target name="build-server" depends="init"> <taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" > <classpath refid="weblogic.class.path" /> </taskdef> <jwsc srcdir="src" destdir="src"> <jws file="**/*Bean.java" type="JAXRPC" /> <jws file="**/*Service.java" type="JAXRPC" /> </jwsc> </target> </project>

You then run this ANT build file by selecting build.xml Right Mouse Button -> Run As -> Ant Build

You should see the ANT build running in the Workshop Console. Hopefully no errors occur.

The following files should be generated

com.cdyne.ws ReturnIndicator.java ws LUHNChecker.java LUHNCheckerSoap.java LUHNCheckerSoap_Stub.java LUHNChecker_Impl.java LUHNChecker_saved_wsdl.wsdl

The main classes we are interested in are:

• LUHNChecker.java - this is the web service interface (<wsdl:service>) • LUHNCheckerSoap.java - this is the binding (<wsdl:binding> & contains the operations for

that port (eg: checkCC(String) )

Page 216: J2EE Weblogic Documentation

216

• LUHNChecker_Impl.java - this is the implementation of the web service interface *** • LUHNCheckerSoap_Stub.java - this is stub that does the actual communications/marshalling

etc • com.cdyne.ws.ReturnIndicator.java - this represents the complexType ReturnIndicator

You will need to do this analysis every time you generate a stub for a web service...

JSP Client

The next step is to create a JSP with the following code fragment in it

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@page import="ws.*" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> Lunh checker: checking 4111111111111 <% LUHNChecker checker = new LUHNChecker_Impl(); LUHNCheckerSoap port = checker.getLUHNCheckerSoap(); com.cdyne.ws.ReturnIndicator ri = port.checkCC("4111111111111111"); out.println(ri.getCardValid()); out.println(ri.getCardType()); %> </body> </html>

Build, deploy and run as usual

You can modify this JSP to take the credit card argument as an input field in a form.

Module: Web Services

Lab exercise 5 - Writing a simple web service

In this exercise we will create a simple web service.

Page 217: J2EE Weblogic Documentation

217

Level of Difficulty: 3 (medium) Estimated time: 40 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Started the WebLogic server on your workstation • Completed Lab exercise 1 - exploring Web services • Completed Lab exercise 3 - simple client

Writing the server code

It's actually quite simple to write a Web Service if you have a JSR-181 compliant web service framework.

Weblogic 8.1, 9 & 10 all support using Java Annotations to mark web services

• Create a new Web Services Project (New -> Project -> Web Services Project, call it "ws" )

• Create a new Package (New -> Package -> myapp )

• Create a new Weblogic Web service (New -> Other -> Weblogic Web Service). Call this Hello (in the package myapp)

• By default, the wizard generates a method called void Hello().

Change this to the following:

package myapp; import javax.jws.*; @WebService public class Hello { @WebMethod public String hello(String name) { return "Hello, " + name; } }

Notice the annotations:

@WebService tells Java & Weblogic that this is a webservice (the default name is Hello)

@WebMethod declares that the following method is a web service Operation. By default, if you dont have this annotation, ALL PUBLIC METHODS are exposed.

We will let the wonders of code generation do all the work for us to make this a web service!

Generating the code

Page 218: J2EE Weblogic Documentation

218

No need to do any. Workshop will run a builder to do this under the covers for you.

Deploy

As usual, add this to the Server (BEA Weblogic Server v10 [weblogic] -> RMB -> Add and Remove Projects)

or just run via highlighting Hello.java -> RMB -> Run As -> Run on Server

Test

Go to http://localhost:7001/ws/Hello

This gives you an application test page! Look at the WSDL and the Test Page

Problems

Sometimes when you do changes you need to clean the project, rebuild and also re-publish

select the Server (BEA Weblogic server v10 [weblogic] -> RMB -> Publish

Additional Exercise: Java Client (medium)

The next step is to create a JSP client for this service.

Follow the instructions in lab 3 and you should be able to write your own JSP client

Module: Web Services

Lab exercise 6 - Adding Basic security to a simple web service

In this exercise we will modify the previous simple web service to add basic HTTP security

Page 219: J2EE Weblogic Documentation

219

Level of Difficulty: 3 (medium) Estimated time: 40 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Started the WebLogic server on your workstation • Completed JSP Lab exercise 4 - web authentication • Completed Lab exercise 3 - simple client • Completed Lab exercise 5 - simple web services

Weblogic (and J2EE in general) define three basic types of web services security. To quote the weblogic documentation at http://edocs.bea.com/wls/docs100/webserv_sec/overview.html , they are::

• Message-level security, in which data in a SOAP message is digitally signed or encrypted. • Transport-level security, in which SSL is used to secure the connection between a client

application and the Web Service. • Access control security, which specifies which roles are allowed to access Web Services.

Message level security is fairly complex and you can read about this independently at http://edocs.bea.com/wls/docs100/webserv_sec/message.html. Basically you can sign and/or encrypt individual SOAP messages according to the WS-security standard - and this could be the entire SOAP message, or just the header or just the body or even just specific elements!

You could also include a Token (username, SAML or X.509 based) which represents the user.

Transport-level security is basically setting up SSL (or TLS in this case) on the connection between your client and web service. You could use a client based certificates to authenticate the connection. However, this is not the same as USER authentication since this only authorises the network connection.

Access control security is the simplest authentication - this re-uses the HTTP basic authentication (which you did in JSP Lab 4 - web authentication) by setting access control security on our web service project. Effectively all you need to do is to pass the username and password on the SOAP call at the client end and the web application server which the web service is running on will handle the security.

Again, this could be via simple plain text username/password (like "student", "password") or you could use Digest authentication using a client-side certificate (a lot harder).

This lab will use HTTP Basic Authentication and will re-use your existing security setup from the JSP Lab 4 - web authentication.

Setting up usernames & roles

This step has been done in JSP Lab 4 - web authentication.

Basically you set up a group called "hellousers" which maps to a role called "hellousers".

Page 220: J2EE Weblogic Documentation

220

You then created users who were members of this group. In the lab you created a username "student" with password "password" (or whatever)

Writing the server code

Keep the existing HelloWorld.java file

Modify the web.xml and weblogic.xml files.

Basically copy the code fragment from the JSP Lab 4 iafter the </welcome-file-list> tag in web.xml

<security-constraint> <web-resource-collection> <web-resource-name>Hello world</web-resource-name> <description>The Hello world application</description> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <description>These users can use hello JSP</description> <role-name>hellousers</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>Hello World Application</realm-name> </login-config> <security-role> <description>Hello JSP users</description> <role-name>hellousers</role-name> </security-role>

You can optionally modify the URL pattern (we used /*) to the web service name itself. You also have to modify the weblogic.xml file to add the following:

<wls:security-role-assignment> <wls:role-name>hellousers</wls:role-name> <wls:principal-name>hellousers</wls:principal-name> </wls:security-role-assignment>

Redeploy & Test

Just redeploy as usual. You can test that you now have to enter a userid and password by typing in the URL in a browser (or in the Weblogic test client).

Note that if you run your previous client, you should get an 500 error with a message like something like

java.rmi.RemoteException: SOAPFaultException - FaultCode [{http://schemas.xmlsoap.org/soap/envelope/}Client.Authentication] FaultString [Failed to receive message weblogic.wsee.util.AccessException: The server at

Page 221: J2EE Weblogic Documentation

221

http://localhost:7001/ws/Hello returned a 401 error code (Unauthorized). Please check that username and password are set correctly and that you have permission to access the requested method.The server at http://localhost:7001/ws/Hello returned a 401 error code (Unauthorized). Please check that username and password are set correctly and that you have permission to access the requested method.]

Generating the Client skeleton

You can keep the existing client you wrote the the previous lab and therefore do not need to

re-generate the client code.

However, if you need to use the Clientgen Ant task, you now have to change the call to add the username and password parameters.

To do this change your build.xml clientgen elemnt to the following:

<clientgen type="JAXRPC" wsdl="http://localhost:7001/ws/Hello?wsdl" destDir="src" generateAsyncMethods="false" classpath="${java.class.path}" autoDetectWrapped="true" packageName="ws" > <sysproperty key="javax.xml.rpc.security.auth.username" value="student"/> <sysproperty key="javax.xml.rpc.security.auth.password" value="password"/> </clientgen>

Don't forget to tailor this for your configuration - ie: change the wsdl, student and password values to your configuration!!!

Modifying the client

When you wrote your test JSP to invoke this web service, you needed to locate the port.

This was via a method on the service class called getXXXSoapPort() (mine is called getHelloSoapPort() ).

The code generated by Weblogic ClientGen includes a variant of this method called getXXXSoapPort(byte[] username, byte[] password)

So modify the method call to look like getXXXSoapPort(username.getBytes[],

password.getBytes[] ) (assuming that String username contains the username eg: "student", and String password contains the password eg: "password")

Test

Rebuild, and redeploy (if necessary), your client. Check that this now works as expected.

Page 222: J2EE Weblogic Documentation

222

Module: Web Services

Lab exercise 7 - Writing a more complex web service

In this exercise we will experiment with different return types from a web service.

Level of Difficulty: 3 (medium) Estimated time: 40 minutes Pre-requisites:

Page 223: J2EE Weblogic Documentation

223

• Run 'wlenv to set your environment correctly • Started the WebLogic server on your workstation • Completed Lab exercise 5 - simple web service

Other data types

JAX-RPC defines the following simple Java datatypes to an equivalent in XML schema. See Java Enterprise in a Nutshell, 3rd Ed, chapter 12 for a more complete list.

Java Types XML Type: Document-Literal

boolean, java.lang.Boolean xsd:boolean

byte, java.lang.Byte xsd:byte

double, java.lang.Double xsd:double

float, java.lang.Float xsd:float

int, java.lang.Integer xsd:integer

long, java.lang.Long xsd:long

short, java.lang.Short xsd:short

java.lang.String xsd:string

java.math.BigDecimal xsd:decimal

java.math.BigInteger xsd:int

java.net.URI xsd:anyURI

java.util.Calendar xsd:dateTime

java.util.Date xsd:dateTime

java.xml.QName xsd:QName

byte[] xsd:base64Binary

In addition to this, it will map arrays and JavaBeans to an equivalent xsd:ComplexType, xsd:sequence and xsd:element combination.

Lab Exercise: Returning complex types

We will see the impact of returning a simple object array, a and a more complex type as a JavaBean.

Creating a JavaBean

Create a javabean called myapp.HelloBean. This should have the properties String name & int age

(hint: create a class in the package myapp called HelloBean, add private String name;

Page 224: J2EE Weblogic Documentation

224

private int age; & use source -> Generate getters and setters)

Add new complex methods to your class

Append the following methods into your Hello.java class

@WebMethod public String[] sayHellos (String mate) { String[] list = new String[3]; list[0] = "hi " + mate; list[1] = "hola " + mate; list[2] = "nihao " + mate; return list; } @WebMethod public Vector sayHola (String mate){ Vector<String> v = new Vector<String>(); v.add("hola " + mate); v.add("ciao " + mate); return v; } @WebMethod public HelloBean sayBean (String mate) { HelloBean hb = new HelloBean(); hb.setName(mate); hb.setAge(99); return hb; }

Deploy and look at the WSDL generated.

What do you notice?

Note that we now have a complexType called "ArrayOfJavaLangstring_literal" - this is the representation of String[]. Ugly isn't it?

We also have complexType "HelloBean" - this is the Javabean we created. Note that it has 2 elements, Age and Name of xsd:int and xsd:string respectively.

Finally if you look at the "sayHolaResponse" element, we have an anonymous ComplexType with an element called return, with type "java:vector". This is the result of the Vector<String>

Building a client

We can build a client as usual, just do remember to re-run the ant build.xml script in the client project.

Modify your existing client to call the new methods added to your web service.

You should look at the Hello.java file (the interface).

Page 225: J2EE Weblogic Documentation

225

It should contain the method signatures for sayHellos(), sayHola() and sayBean().

Notes:

Rather than generating a String[] array, jax-rpc (and in particular, the weblogic implementation of it), generates a holding class, which you then have to call another method (in this case, getJavaLangString() ) to return the String[] array.

Rather than generating a vector, java jax-rpc returns an array of Object[].

When you have a Javabean, jax-rpc will return a Javabean back to you.

Module: Security

Lab exercise - Confidentiality

In security terms, "confidentiality" is ensuring that information cannot be accessed by those who do not have permission. It is typically satisfied by encrypting data. This lab exercise looks at how you can use encrypted communication between a client and the presentation tier.

Page 226: J2EE Weblogic Documentation

226

Level of Difficulty: 1 (easy) Estimated time: 20 minutes Pre-requisites:

• Run 'wlenv' set your environment correctly • Start your WebLogic server running in the background • Completed an earlier exercise using servlets or JSPs

Using SSL

The laboratory exercises for this module do not involve writing any new code. It assumes that you have some code from a previous lab, preferably a stateless session EJB, and a Java servlet (or JSP) that calls a business method on the EJB.

SSL stands for Secure Sockets Layer, and is also sometimes known as TLS (Transport Layer Security). It is basically a mechanism for encrypting application traffic for transmission over a TCP/IP network. Its most common use is to encrypt HTTP (web) traffic between a web browser and a web server.

• To enable SSL on weblogic 10, go to the Weblogic Console, choose Environment > Servers & select AdminServer

• You need to click the [Lock and Edit] tab on the top left menu to enable updates • Then, on the General tab, select the SSL Listen Port Enabled. Note that the default

listen port is 7002. Finally, [Save] and [ACTIVATE CHANGES] to enable SSL.

Try accessing the Weblogic console using SSL:

https://localhost:7002/console

Try loading one of your earlier web applications (servlet or JSP) using SSL, by using the URL

https://localhost:7002/labs/index.jsp (change /labs & index.jsp to match your context & JSP names )

Note that no change was required to the application.

You can ignore any messages from your browser about invalid certificates, since effectively we have a 'self-signed' SSL certificate issued from "MyOrganization" to "MyOrganization" !!

In a production environment, you would normally purchase an SSL certificate from a commercial vendor such as Verisign or Thawte. You can read your web application server's documentation for the particular process you should follow.

Enforcing SSL

Page 227: J2EE Weblogic Documentation

227

Change the web.xml deployment descriptor for the application you just tested, so that it has a <transport-guarantee> tag, specifying that SSL must be used.

Insert the following XML into your deployment descriptor after the <welcome-file-list> tag you may have used. You can optionally add <auth-constraints> to enforce login authentication too..

<security-constraint> <web-resource-collection> <web-resource-name>My App</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>

Then try invoking your application again, first using the SSL URL (starting with https://) as described above. Then try invoking the JSP using a non-SSL URL (use http:// at the start of the URL and use port 7001). What happens (hint: pay close attention to the URL in the browser if you think nothing happens)?

Module: Security

Lab exercise - Web authentication

In a J2EE application, you can require authentication either at the web tier, or at the EJB tier. This lab exercise looks at different ways you can use authentication information in a web application.

Page 228: J2EE Weblogic Documentation

228

Level of Difficulty: 1 (easy) Estimated time: 30 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Start your WebLogic server running in the background • Completed an earlier exercise using servlets or JSPs

Declarative web authentication

The laboratory exercises for this module do not involve writing any new code. It assumes that you have some code from a previous lab, preferably a stateless session EJB, and a Java servlet (or JSP) that calls a business method on the EJB.

Declarative web authentication involves adding authentication to a web application without changing the Java source code at all. The authentication requirements are specified purely in the XML deployment descriptor(s).

For this exercise, take an existing application, and change the deployment descriptor to require a user to authenticate before being granted access to the application.

In the first instance, use HTTP "Basic" authentication. Follow the instructions in the tutorial on using HTTP Basic authentication in web applications.

Programmatic web authentication

Generally, declarative authentication is preferred wherever possible, because it allows the container to manage the authentication process, and reduces the possibility of programmer errors.

However, sometimes declarative authentication is not enough. With declarative authentication, the smallest section of an application you can protect is one servlet or JSP. Sometimes, within a single servlet or JSP, you need finer-grained control.

With programmatic web authentication, you add some Java code to your servlet/JSP program that checks which user is logged in, and takes appropriate action depending upon the user's identity.

For a servlet that you have already created, and set up declarative web security before (previous section), try the following steps for some simple programmatic web authentication.

1. In the servlet's source code, first of all, import the class java.security.Principal (or import java.security.* if you prefer).

2. Somewhere in the doGet() method, add code similar to the following:

Page 229: J2EE Weblogic Documentation

229

String username = null; Principal p = req.getUserPrincipal(); if (p != null) { username = p.getName(); } out.println("You are logged in as: " + username);

Module: Transactions

Lab exercise - Transactions

Transactions in J2EE applications are largely managed by the container. That means you can modify the transactional properties of an application by altering values in the deployment descriptor (ejb-jar.xml), so there is not a lot of code to write. This exercise is just to explore an application where a transaction is initiated in a servlet.

Page 230: J2EE Weblogic Documentation

230

Level of Difficulty: 1 (easy) Estimated time: 15 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Start your WebLogic server running in the background

Transactions

There is not much to do, programmatically for transactions. With container-managed transactions, it is an issue of choosing the correct values in the deployment descriptor.

Examine an EJB deployment descriptor you created earlier (ejb-jar.xml). You would have created a <container-transaction> declaration like the following.

<assembly-descriptor> <container-transaction> <method> <ejb-name>HelloWorld</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor>

This example says that for all method-names on the remote interface of EJB HelloWorld, we want to use the transaction attribute "Required". You can change how this EJB method behaves in the context of a transaction by changing the value of the transaction attribute.

Transaction

attribute

Meaning

Required This method must participate in a transaction. If an existing transaction is already in

progress, it will join that one, otherwise a new transaction will be started.

RequiresNew This method must participate in a transaction. It will always create a new

transaction. If an existing transaction was already in progress, it will suspend that

one and create a new one. The new transaction created will have no relationship to

the old one.

NotSupported This method will not participate in a transaction. If an existing transaction was

already in progress, it will suspend that one, and execute without a transaction

context.

Supports This method may or may not participate in a transaction. If an existing transaction is

already in progress, it will join that one and run in a transaction. If no transaction is

Page 231: J2EE Weblogic Documentation

231

in progress, it will not create a new one, and therefore it will not run in a transaction.

Never This method will not participate in a transaction. Further, if an existing transaction

was already in progress, it will throw an exception. i.e. it will refuse to run with a

transaction.

Mandatory This method must participate in a transaction. Further, if an existing transaction was

not already in progress, it will throw an exception. i.e. it will refuse to run without a

transaction that is already in progress.

Optional: If you wish to try out some different values, create two different EJBs with one method each. Let's call them EJB1 and EJB2. Set the transaction attribute of EJB1's method to Required, and the transaction attribute of EJB2's method to Never. Make a servlet that invokes EJB1's method. Make EJB1's method invoke EJB2's method. An exception should be thrown.

Starting a transaction in a servlet

So far we have considered transactions only applied to EJB methods. In practice, this is how transactions are used in J2EE applications. However, in rare circumstances, it might be necessary to create a transaction in a servlet or JSP. The following example illustrates how.

This lab exercise is merely exploratory - examine the following example of a web application (servlet) that creates a UserTransaction, and then calls a stateless session EJB. The UserTransaction object is created by the application server and is advertised in the JNDI tree, so the servlet merely does a naming lookup to retrieve the transaction context object.

Note that using transactions in this way is not usually done in J2EE applications, so you should not try to copy this behaviour in your own applications.

Example application: starting a transaction in a servlet

The application is provided in a separate JAR file and WAR file, for the EJB and servlet components respectively.

• TransStatelessSessionEJB.jar • TransClient.war

Module: Legacy

Lab exercise - Using CORBA

Many legacy systems use CORBA as their main distributed systems model of programming. This is because CORBA provides an vendor-independent, language-neutral, platform

Page 232: J2EE Weblogic Documentation

232

agnostic and open standard. There even exists bridges between proprietary systems such as Microsoft DCOM and CORBA.

CORBA can also be more efficient than the J2EE platform - sometimes due to the legacy code such as C being compiled.

In the lab environment, a minimal CORBA ORB is provided - this is the open source ORBit and ORBit2 packages under Redhat Linux. Incidentally, this is also required for the GNOME GUI, which uses CORBA to manage the desktop!

Level of Difficulty: 3 (medium, extra exercise is hard) Estimated time: 45 minutes Pre-requisites:

• Run 'setEnv.sh' to set your environment correctly • Ensure . is in your $CLASSPATH

CORBA - C example

We have provided a sample calculator application, written in C, which provides 2 simple functions - add and sub

This can be found here as a zip file or alternatively, on /pub/aip/corba/src.zip. For the intrepid, this comes from the orbit documentation package http://www.gnome.org/projects/ORBit2/orbit-docs.tar.gz

CORRECTION: There is a bug in Makefile, remove the reference to -llinc in the LDFLAGS= section You can also download the corrected Makefile here.

You can also read the Orbit Documentation for this sample at (http://www.gnome.org/projects/ORBit2/orbit-docs/orbit/x478.html) if you are brave (and understand C).

Unzip this into a subdirectory.

Let's look at the IDL for this application

// // Calculator interface // interface Calculator { double add(in double number1, in double number2); double sub(in double number1, in double number2); };

Basically, this defines 2 functions called add() and sub().

Page 233: J2EE Weblogic Documentation

233

Both a server (calculator-server.c) and a client (calculator-client.c) are provided. There is a Makefile available, so you can compile this example.

make

You can test this now by starting up the server in a seperate window and typing

./calculator-server

Let's try the client - run this in your original window..

./calculator-client

Simple eh? 1+2 = 3

Look at the calculator.ref file. This is where the IOR of the server client is temporarily stored. In real life, it would be better to have a lookup mechanism for this object reference, and CORBA 2 provides a human readable naming mechanism based on the URI standard for this very purpose. The IOR is a string that looks something like

IOR:010000001300000049444c3a43616c63756c61746f723a312e3000000300000 00054424f5c0000000101020005000000554e495800000000170000006361747368 61726b2e69742e7574732e6564752e61750000280000002f746d702f6f726269742 d6368772f6c696e632d3431302d302d323730323739383736386434340000000000 caaedfba5400000001010200280000002f746d702f6f726269742d6368772f6c696 e632d3431302d302d3237303237393837363864343400000000001c000000000000 00c0fa8c60a80c68a86b70282828282828010000006f9971a101000000480000000 100000002000000050000001c00000000000000c0fa8c60a80c68a86b7028282828 2828010000006f9971a101000000140000000100000001000105000000000901010 000000000

If you want this decoded, copy this into your clipboard and enter it into the following URL:

http://www2.parc.com/istl/projects/ILU/parseIOR/

Note that if you choose Parse(Brief) it shows the NIL object. This is because by default, ORBit does not use IIOP and uses unix domain sockets instead. Let's correct this.

You need to create a file called ~/.orbitrc with the following contents

ORBIIOPIPv4=1

Re-run the server, and get the IOR from calculator.ref and try the IOR parser again. You should get a response like

object key is <#00#00#00#00#1C#BCm#FC#A7#D8?#C2#B9#F7#0D#E2#16#FA $#8E#01#00#00#00R#DE#C4#F0>; no trustworthy most-specific-type info; unrecognized ORB; reachable with IIOP 1.2 at host "catshark.it.uts.edu.au", port 34286

Now we can develop CORBA IIOP clients, such as a Java based one.

Page 234: J2EE Weblogic Documentation

234

Java CORBA client

We need to generate skeletons for the Java client. Type

idlj calculator.idl

You should get the following files generated

• CalculatorHelper.java • CalculatorOperations.java • Calculator.java • CalculatorHolder.java • _CalculatorStub.java

We also need to write the client code itself. Create calculator_client.java import org.omg.CORBA.*; import java.io.*; import java.util.*; class Calculator_client { public static void main( String args[] ) { try{ Properties props = System.getProperties(); System.out.println( "Initializing the orb."); // now get a new instance of an application ORB org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,props); // read in the IOR reference file BufferedReader in = new BufferedReader( new FileReader("calculator.ref")); String iorString = in.readLine(); // replace above with the following if you are running JDK 1.4.2 // org.omg.IOP.IORHolder ior_holder = new org.omg.IOP.IORHolder(); // String iorString = ior_holder.readIORFile("calculator.ref"); org.omg.CORBA.Object object = orb.string_to_object( iorString ); Calculator calc = CalculatorHelper.narrow( object ); System.out.println("Now calling add"); double res = calc.add((double)1.0,(double)2.0); System.out.println("Call to Corba Calculator="+res); } catch ( org.omg.CORBA.SystemException e ) { System.err.println( "CORBA System Exception "); System.err.println( e ); e.printStackTrace(); } catch (Exception e) { System.err.println("Other java error "+e); e.printStackTrace(); } } }

And compile the lot javac *.java

(in the supplied Makefile, we have added an extra target called alljava, so you could also type make alljava)

Page 235: J2EE Weblogic Documentation

235

If you had errors, correct them, or check that you have '.' in the classpath.

Start the calculator-server again, then

java Calculator_client

Hopefully, you should see the correct result come out.

Additional exercises

If you sufficiently skilled in C, you could add extra functions to this application, such as mult or div.

Here is the process to follow:

1. Edit calculator.idl file and add the extra definitions. 2. Clear the old code

make distclean 3. Edit the calculator-skelimpl.c - you add your methods at the bottom of this file. Use

add or sub as a template. 4. Re-generate the code

make all 5. You can then also edit the calculator-client.c file to call these extra methods. Don't

forget to make all each time you make changes! 6. Finally, you can follow the above steps and modify/compile/run the Java client.

One more exercise is to run the client and server on different machines. Since you will be logging onto different machines with the same userid, you should make sure you run the server and client from the same directory, so as to have the same calculator.ref file present.

Module: Legacy

Lab exercise - Using JMS

Page 236: J2EE Weblogic Documentation

236

Java Message Service (JMS) provides a Java API for Message Oriented Middleware such as IBM MQseries and integrated JMS providers such as SonicMQ and WebLogic JMS.

In this lab, we will experiment with both point-to-point and publish-subscribe messaging patterns.

Level of Difficulty: 3 (medium, extra exercise is hard) Estimated time: 45 minutes Pre-requisites:

• Run 'wlenv' to set your environment correctly • Ensure . is in your $CLASSPATH • Ensure WebLogic server is running

Point-to-Point messaging

Before we can do any programming, we need to setup queues and topics into WebLogic.

Enter the WebLogic console.

Part 1: Creating a JMS server and Destinations

Weblogic 9 and 10 have a concept called "JMS Modules". These contain the definitions of all the JMS messaging queues/topics etc. They can be application specific (which requires the creation of a Weblogic-specific XML deployment descriptor) or a System module (which is system wide). We will use the System module in our lab.

First we create a JMS Server:

• From the weblogic console, press the [Lock & Edit] button to get into edit mode. • Choose Services > Messaging > JMS Servers & choose [NEW] • Name the server: JMSServer & [Next] • Select AdminServer as the Target & [Finish] • Choose the [Activate Changes] at the top left menu

Now create the Queue

• From the weblogic console, press the [Lock & Edit] button to get into edit mode. • Choose Services > Messaging > JMS module & select [New] • Give the new module a name: SystemModule & [Next] • Select the AdminServer & [Next] • Select the "Would you like to add resources to this JMS System module" checkbox & [Finish] • Now we can create the queue for our lab. Select [New] in the "Summary of Resources" table • Choose the Queue radio button & [Next] • Now enter: name: MyMessageQueue

JNDI Name: jms.MyMessageQueue & [Next]

• Choose [Create a new Subdeployment] - keep the name the system generates & [OK] • Choose targets: JMSServer & [Finish] • Don't forget to [ACTIVATE] changes (top left menu)

Page 237: J2EE Weblogic Documentation

237

Check that the queue exists by going to the Environment > Servers > AdminServer & selecting the "View JNDI tree" link. You should see jms. Expand this and you should see MyMessageQueue appear.

We will use the default WebLogic JMS connection factory weblogic.jms.ConnectionFactory. You can optionally create your own connection factory by following the steps when creating a Queue, but choosing Connection factory instead.. We don't need to do this for our lab

Part 2: Create a receiver and sender Java program

Create a subdirectory eg: ~/jms to develop these programs. Note that they are not JSP or servlets, just ordinary Java applications.

Here is a simple receiver program called receiver.java

import javax.jms.*; import javax.naming.*; import java.util.Hashtable; public class Receiver implements MessageListener { private QueueConnectionFactory qconFactory; private QueueConnection qcon; private QueueSession qsession; private Queue queue; private QueueReceiver qreceiver; public static void main (String[] args) throws Exception { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL,"t3://127.0.0.1:7001"); try { InitialContext ctx = new InitialContext(env); System.out.println("Setting up receiver..."); Receiver r = new Receiver(); r.init(ctx, "jms.MyMessageQueue"); System.out.println("Run init, hit Ctrl-C to stop.."); // loop here if need be. synchronized(r) { r.wait(100000); // wait 100 seconds } System.out.println("Finished waiting, bye..."); } catch (Exception e) { e.printStackTrace(); } } public void init(Context ctx, String queueName) { try { qconFactory = (QueueConnectionFactory) ctx.lookup(

Page 238: J2EE Weblogic Documentation

238

"weblogic.jms.ConnectionFactory"); qcon = qconFactory.createQueueConnection(); qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); queue = (Queue) ctx.lookup(queueName); System.out.println("looked up "+queueName); QueueReceiver qreceiver = qsession.createReceiver(queue); System.out.println("Created queueReceiver..."); qreceiver.setMessageListener(this); System.out.println("Starting QueueConnection..."); // start the thread which listens for incoming messages qcon.start(); } catch (Exception e) { e.printStackTrace(); } } //init public void onMessage(Message msg) { try { String msgText = ((TextMessage)msg).getText(); System.out.println("Message Received: "+ msgText ); } catch (JMSException ex) { ex.printStackTrace(); } } // onMessage }

And here is simple sender program called sender.java

import javax.jms.*; import javax.naming.*; import java.util.Hashtable; public class Sender { public static void main ( String[] args ) throws Exception { try { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL,"t3://127.0.0.1:7001"); InitialContext ctx = new InitialContext(env); QueueConnectionFactory qconFactory = (QueueConnectionFactory)ctx.lookup( "weblogic.jms.ConnectionFactory"); QueueConnection qcon = qconFactory.createQueueConnection(); QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = (Queue) ctx.lookup("jms.MyMessageQueue"); QueueSender qsender = qsession.createSender(queue); TextMessage msg = qsession.createTextMessage();

Page 239: J2EE Weblogic Documentation

239

qcon.start(); msg.setText ("Hello world"); qsender.send (msg); } catch (Exception e) { e.printStackTrace(); } //catch } // main }

Compile this code.

Test by running "java sender" from the shell.

NOTE: if you run this from Eclipse/Weblogic Workshop, you will need to add EITHER wljmsclient.jar OR weblogic.jar from your weblogic installation directory (ie: /opt/bea10/wlserver_10.0/server/lib) otherwise you may get a run-time error.

Note that you can monitor your queues by using Services-> Messaging > JMS Servers Choose the server (JMSServer) & then choose the Monitoring tab & then "Active Destinations" Note that the name of the queue is actually "SystemModule!MyMessageQueue".

Note that the Messages count increases each time you run the "sender".

Now let's receive the messages

If you run the receiver in a seperate window, you should see the messages get consumed.

Extra work

Develop a publish/subscribe version of the above.

Hints:

Refer to the lecture notes for the different names of the classes, for example, replace Queue with Topic.

Also instead of receiving, you subcribe. Instead of sending, you publish.