Vous êtes sur la page 1sur 81

Unit 02 – Graphical User Interface

Abstract Window Toolkit (AWT):


- the GUI library that contains wrapper classes of native GUI components in the
underlying windowing toolkit.
- Pros: Faster, closely reflect the look and feel of the OS they run on
- Cons: Platform dependent, Prone to error of running platform, Heavy-weight,
look and feel are different when running in different platform.
- Swing was introduced to solve these issues

Swing:
- Most Swing components (except JApplet, JDialog, JFrame and JWindow) are
lightweight, which means that they do not rely on native components.
- Pros: Platform independent, Less affected by bugs in the windowing toolkits,
Support PLAF that allows changing GUI outlook, Consistent interfaces in
different platforms, Has a large set of GUI components.
- Cons: Slower than AWT, PLAF may not look the same as native components

Swing GUI hierarchy:


- java.awt.Component: the superclass of the whole Swing family
- java.awt.Window: the superclass of all containers
- javax.swing.JComponent: the superclass of all components that are not container

javax.swing.JFrame class:
- represents a window that contains other components in its content area
- JFrame(), JFrame(String title)
- void setDefaultCloseOperation(int option) // eg. JFrame.EXIT_ON_CLOSE
- void setSize(int w, int h), setSize(Dimension d)
- void setLayout(LayoutManager m) // set the layout manager, default BorderLayout
- void setVisible(boolean b) // shows or hides the frame
- void pack() // set the size of frame automatically according to the GUI
components
- void setJMenuBar(JMenuBar m)
- void setLocationRelativeTo(Component c) // centered on the screen if c is null
- Component add(Component c), Component add(Component c, Object constraint)

javax.swing components:
- JLabel, JTextField, JPasswordField, JTextArea
(used with JScrollPane)
- JButton, JCheckBox, JRadioButton (added by frame.add(), grouped by
ButtonGroup.add())

Page 1 of 87
- JComboBox, JList, JScrollBar, JSlider
Layout managers (defined in the java.awt package):
- used to arrange GUI components in specific ways
- GridLayout: components are arranged in rectangular grid’s cells of same size
- BorderLayout: default layout manager of a frame. It divides the container into 5
regions – north, east, south, west and center. Each can hold 1 component.
- FlowLayout: default layout manager of a Panel. It arranges components from left
to right in a row. When the row is full, a component is placed in the next row.
Components are displayed in their preferred sizes.
- CardLayout: each component is placed in an individual card. At any time, only
one out of all cards is displayed and the others are hidden.
- GridBagLayout: like grid layout, it arranges components in a grid. It is more
flexible that a component can occupy multiple cells and you can add
components to a grid bag layout in any order. It uses the GridBagConstraints class
to specify how a component is laid out.
- Javax.swing.BoxLayout: arranges components vertically in a column or horizontally
in a row. The components are displayed in their preferred sizes.

Containers:
- javax.swing.JFrame: uses BorderLayout by default
- Javax.swing.Box: uses BoxLayout
- javax.swing.JPanel: uses FlowLayout by default

javax.swing.JPanel class:
- JPanel(), JPanel(LayoutManager layout)
- add(Component c) // adds a component to the panel

The event-delegate model:


- Event: an object that describes a user action happening to a component.
- Event Source: the object that generates an event.
- Event Listener/Handler: the object that is registered to process an event.
- E.g. Clicking a button is an event. The button is the event source. An object that
implements the ActionListener interface can be registered as the event listener.

Java.awt.event.AWTEvent class:
- In Swing/AWT, events are represented subclasses of AWTEvent
- ActionEvent: a button is clicked
- ItemEvent: a checkbox is clicked
- WindowEvent: a window is opened, closed …

Page 2 of 87
The event-delegate model:

Event listeners:
- ActionListener: void actionPerformed(ActionEvent e)
- WindowListener: void windowActivated(WindowEvent e) // the window is made active
- void windowClosed(WindowEvent e) // the window has been closed
- void windowClosing(WindowEvent e) // the user attempts to close it
- void windowDeactivated(WindowEvent e)
- void windowOpened(WindowEvent e) // the window is first made visible

Registering event listener to event source:


- button.addActionListener(ActionListener l)
- frame.addWindowListener(WindowListener l)

Benefits of nested class:


- They create a logical grouping of class such that a helper class that is only
used in another class can be put together with that class
- They increase encapsulation: A nested class can access the enclosing class’
private properties such that the enclosing does not need to public them
- They create more readable, maintainable code

Types of nested classes:


- Static nested class
- Inner class (non-static, declared in class scope)
- Local inner class (declared in method scope)
- Anonymous inner class (declared without a class name)

Static nested class:


- class A { // A is the enclosing class
- static class B { } // B is the nested class
- }
- Within class A, you refer to class B as B. E.g. new B();
- Outside class A, you refer to it as A.B. E.g. new A.B();
- As B is static, it is not associated with any instance of class A. So, B cannot
directly refer to instance members of A.

Page 3 of 87
Non-static inner class & local inner class:
- class A {
- class B { } // B is a non-static inner class, declared outside any method
- void m() {
- class C { } // C is a local inner class, declared inside a method
- }
- }
- C can only be used inside the method m()
- Within class A, you refer to class B, C as B and C. E.g. new B(); new C();
- In a static method of A or a method outside class A, an A instance (e.g. objA) is
required to instantiate B and C. E.g. objA.new B(); objA.new C();
- Inside B and C, you refer to the instance of A as A.this
- Both B and C are associated with an instance of A
- A local inner class cannot access non-final local variables within a method

Anonymous inner class:


- class A {
- void m() {
- B b = new B() { // content of anonymous inner class };
- }
- }
- A new object is created from a class that has no name and subclasses from B if
B is a class, or implements B if B is an interface
- An anonymous inner class can’t access non-final local variables within a
method
- It is often used to write event listeners. E.g.
- buttonA.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) { // event handling logic }
- });

Creating menus in an application:


1. Create a JMenuBar object & add it to the desired frame setJMenuBar(JmenuBar mb)
2. Create JMenu objects and add them to the menu bar mb.add(JMenu m)
3. Create JMenuItem objects and add them to menu m.add(JMenuItem i)
4. Handle the action events from the menu items
* A JMenu can be added to another JMenu

Dialogs (javax.swing package):


- JOptionPane: for Message, Confirm, Input, Option dialogs (e.g. showInputDialog).
The showMessageDialog() method can be used to show object other than String.
For example, a JTextArea can be shown in the message dialog.
- JFileChooser: for file Open, Save dialogs (e.g. showOpenDialog)

Pluggable Look-and-Feel (PLAF):


- A major advantage of Swing: it is possible to control the appearance of your
app
- The javax.swing.UIManager class can be used to set the look and feel of an app
- To retrieve native system LAF, String UIManager.getSystemLookAndFeelClassName()
- To set LAF, void UIManager.setLookAndFeel(LookAndFeel laf) / (String className)
- A PLAF is represented by a subclass of javax.swing.LookAndFeel: Below are some
existing look-and-feel examples:
- Javax.swing.plaf.metal.MetalLookAndFeel: the default PLAF

Page 4 of 87
- com.sun.java.swing.plaf.windows.WindowsLookAndFeel: Windows PLAF
- com.sun.java.swing.plaf.mac.MacLookAndFeel: Macintosh PLAF

The MVC architecture:


- To simplify the design of software that has data and presentation. It separates
data from its presentation in a component to make it easier to develop and use.
- Model: the application data (notify views for updated data)
- View: the presentation of the component (observer of the model)
- Controller: the processing logic of the input to the component (update model)

Advantages of MVC:
- Reduce complexity and Increase reusability
- Multiple views can be registered to a model

Delegate-model architecture in Swing:


- Swing adopts a modified MVC architecture, in which the controller and view are
combined into a UI delegate object. It is called the delegate-model architecture.

- E.g. A JTextField is a UI delegate associated with a javax.swing.text.Document model.


You can use the get/setDocument() method of the JTextField to get/set its model.

javax.swing.JTree class:
- Represents a tree component for displaying hierarchical data
- The DefaultTreeModel class is the default model of JTree. As it is the model, which
notifies the view for changes, we should invoke the methods of DefaultTreeModel
to modify the tree in order for the view to get notified.

javax.swing.tree.DefaultTreeModel class:
- DefaultTreeModel(TreeNode root) // create a tree model with the specified root
- void insertNodeInto(MutableTreeNode child, MutableTreeNode parent, int index)
- void removeNodeFromParent(MutableTreeNode node)
- void valueForPathChanged(TreePath path, Object value) // sets the content of the node

Page 5 of 87
at a path to the specified value

javax.swing.JTable class:
- The DefaultTableModel is the default model of JTable.

javax.swing.table.DefaultTableModel class:
- void addRow(Object[] rowData) // adds a row of data to the table model
- void setValueAt(Object value, int row, int col)

Multithreading:
- Pros: better performance, more responsive GUI program
- Cons: hard to develop and debug, more error-prone (e.g. synchronization pbm)

Creating threads by extending the java.lang.Thread class:


- Create a subclass of the Thread class and override the run() method
- Create an instance of the subclass
- Invoke the start() method on the instance
* Cons: this method cannot be used if your class has to extend another class

Creating threads by implementing the java.lang.Runnable interface:


- Create a class that implements the Runnable interface & supply the run() method
- Create an instance of the class and pass it to the constructor of the Thread class
- Invoke the start() method on the Thread object

java.lang.Thread class:
- Thread(), Thread(Runnable task)
- void start() // starts the thread
- void run() // the method that is called when the thread start
- void interrupt() // interrupts the thread
- static Thread currentThread() // gets the currently executing thread
- static void sleep(long ms) // pauses the current thread for ms
- static void yield() // pauses the current thread and allows another thread to
execute
- static boolean interrupted() // returns if the current thread is interrupted

Thread Pools:
- A Thread object cannot be reused as the start() method can only be called once.
It is inefficient for programs that create large number of threads.
- You can create Runnable objects and pass them to a thread pool for execution
without explicitly creating Thread objects.
- A thread pool implements ExecutorService, which is a subinterface of Executor.
- The Executors class provides methods to create different types of thread pools.

java.util.concurrent.Executor interface:
- void execute(Runnable task) // executes the task in a thread pool

java.util.concurrent.ExecutorService interface:
- void shutdown() // waits for all submitted task to finish and then shut down
- void shutdownNow() // shut down immediately
- boolean isShutdown() // returns whether the thread pool is shut down
- boolean isTerminated() // returns whether all tasks in the pool are terminated

Page 6 of 87
* If a thread pool is not shutdown, the program will not end

java.util.concurrent.Executors:
- static ExecutorService newCachedThreadPool() // pool that caches and reuses threads
- static ExecutorService newFixedThreadPool() // pool with a fixed number of threads
- static ExecutorService newSingleThreadExecutor() // pool of a single thread

Thread Synchronization:
- Sync. problem: multiple threads access the same resource at the same time.
- Critical section: refers to a sensitive program section that only one thread is
allowed at any time. E.g. count = count + 1; // 3 operations involved in 1 statement
- The synchronized keyword is used to prevent critical section from sync problem.
- synchronized void increase() { // way1: synchronized method, which locks this
- count = count + 1; } // object before entering the increase() method
- void increase() {
- synchronized(this) { // way2: synchronized block, where the lock is explicitly
- // specified. This can shorten the locking period.
count = count + 1; } }
- Keep in mind that the synchronized keyword imposes overhead. Use it carefully!
- Synchronization can also be achieved using the ReentrantLock class

Thread Notification (Inter-communication):


- Thread-related methods (inherited to all) in the Object class: wait(), notify(),
notifyAll()
- These methods are used to enable simple communication between threads
- wait(), wait(long ms), wait(long ms, int ns) // pauses the current thread to wait until it is
notified or until the specified time
- void notifyAll() // unblocks all threads that wait for this object
- void notify() // unblocks a randomly selected thread that waits for this object
- These methods must be invoked inside a synchronized method or block (i.e.
they are used with the synchronized keyword)

Interrupting threads:
- Sometimes, you may want to terminate a thread from another thread. This can
be done using the interrupt() method. In this case, the interrupted thread will
throw an InterruptedException. You can get the state of the thread by interrupted()
method.

Event Dispatch Thread (EDT) in Swing:


- Swing framework is not thread safe. If multiple threads operate on a Swing
component at the same time, it may be corrupted. Swing uses a single thread -
call event dispatch thread - for the execution of all its components and event
handlers. So, it is not good to manipulate a Swing component in another thread.
- The javax.swing.SwingUtilities class provides 2 methods for running code in EDT.
- static void invokeLater(Runnable task) // schedules a task to be executed in the EDT
- static void invokeAndWait(Runnable task) // schedules and waits until run() finishes

Drawing in Swing:
- The coordinate system of Swing is (0, 0) => Top left corner
- To do drawing in Swing, subclass from a Swing component and override the
protected void paintComponent(java.awt.Graphics g) method.
- To refresh a Swing component, do not invoke its paintComponent method directly.

Page 7 of 87
Instead call the repaint() method which requests Swing to arrange for repainting.
- The Graphics class represents a drawing area and its related functions.
- Color getColor() / void setColor(Color c) / Font getFont() / void setFont(Font f)
- void drawLine(int x1, int y1, int x2, int y2)
- void drawRect / fillRect / drawOval / fillOval(int x, int y, int w, int h)
- void clearRect(int x, int y, int w, int h) // clears an area with the background color

Unit 03 – Developing applets and desktop applications


Deployment of Java applications:
- Copy all related classes and files to the running machines and run in batch file.
Cons: Files may be missed or corrupted during copying.
Class files must be placed in the correct directory structure.
- Using Java Archive (JAR) files. All related files are compressed into a single
JAR file. A main class may be specified such that the JAR file is executable.
To create JAR : jar cvfe jarfile.jar MainClassName allfiles
To execute JAR : java -jar jarfile.jar
Pros: Secure (JAR file can be digitally signed).
Reduce download time (single file vs multiple files using HTTP).
Files are compressed to reduce storage.
A JAR file may have vendor and version information.
- Using Java Web Start (JWS), which further removes the need to manually
transfer the JAR file. The JAR file is hosted on a web server, and you can start
the application by clicking on a hyperlink in a webpage.

Launching Java application in a web browser using JWS:

- JWS (runs in client side) uses the Java Network Launching Protocol (JNLP) to
install Java apps. To deploy an application using JWS, a JNLP file is needed. It
contains information such as URL for launching the application by JWS.
- Pros: Platform-independence, Offline execution is possible, Secured as JWS

Page 8 of 87
apps are executed in a sandbox which disallow the apps to access local file
systems by default (only signed app can access local file systems and
network), applications are cached locally for faster subsequent runs

Applets:
- Embedded in HTML using the <applet> tag. The browser reserves a space as
the applet’s display area and attempts to download the applet class file from the
web server when it encounters this tag. The browser then instantiates the
applet class. For example: <applet code = “Applet1.class”, width = “200”, height = “200”>
</applet>

Limitations of applets:
- Applets cannot load libraries or define native methods
- An applet cannot read or write files on the local machine
- An applet cannot make network connections except to the host that it came
from
- An applet is not allowed to receive incoming packets from other servers
- An applet cannot start any program on the local machine
- An applet cannot read certain system properties, including the user name
JWS applications vs Applets:
- Similarity: Both are downloaded from remote servers and executed on local
machines. As a result, both are executed in a security sandbox for security.
- Difference: Applet is displayed in a web page, while a JWS application executes
in its own window (frame).

Developing applets:
- An applet either extends the javax.swing.JApplet class or its superclass
java.applet.Applet in AWT
- There is no main() method in an applet. The browser is responsible for the
instantiation of the applet object.

Applet life cycle:

Page 9 of 87
- void init() // invoked only once by the browser to perform initialization such as
GUI
- void start() // invoked every time the containing HTML is displayed
- void paint(Graphics g) // invoked whenever the applet has to be redrawn. E.g. when
the display area is covered and then uncovered
- void stop() // invoked when the applet is not visible. E.g. the browser is minimized
- void destroy() // invoked when the applet is about to be removed from memory
- After an applet object has been instantiated (constructor), the init(), start() and
paint() methods are executed in sequence.
- Before an applet terminates, the stop() and destroy() methods are called in seq

Communication between applet and browser:


- Passing parameters to applet using the HTML <param> tag:
For example, <applet code= “Applet1.class” width = 350 height = 200>
<param name= “x” value= “50” /> </applet>
The parameter can then be retrieved in applet by String getParameter(“x”);
- Using services provided by the java.applet.AppletContext interface:
For example, getAppletContext().showDocument(URL url); gets an AppletContext object
and then opens a URL in the current browser. showStatus(String text); displays the
text in the browser’s status bar. The showStatus() method delegates the call to
the AppletContext object so that there’s no need to getAppletContext().

Swing Application Framework (SAF):


- A small framework that facilitates the implementation of common tasks in
building Swing applications. It does not replace Swing, but helps to make Swing
programming easier and shorter.

Services provided by SAF:


- Application life cycle: GUI startup & shutdown
- Persistent session state: save GUI state from one execution to the next
- Support and simplify action management for event handling

Page 10 of 87
- Support for managing and loading resources:

Application life cycle:


- A SAF program subclasses from the SingleFrameApplication class, overrides the
startup() method and optionally overrides other life cycle methods, invokes the
launch() method in your main() method to start the application and invoke exit()
when your application wishes to exit:
- launch() // invoked by your application to create & launch the SingleFrameApplication
- initialize() // invoked by the framework to configure system properties
- startup() // invoked by the framework to create and show the GUI
- ready() // invoked by the framework when the GUI is ready
- exit() // invoked by your application to request shutdown
- shutdown() // invoked by the framework to hide the GUI and perform clean up
- Pros: standardize coding patterns for GUI applications

Persistent session state:


- When you resize or move the frame (application window) and exit the
application, the framework saves the new window size and location for you
Action management support:
- Another way of handling ActionEvent is to use the javax.swing.Action interface,
which is a sub-interface of ActionListener. The Action interface represents a
command that can be bound to Swing components.

Steps to use the Action interface without using SAF:


- Create a class that implements the Action interface
- Create an action instance by instantiating the new class
- Register the action instance to a Swing component using the setAction method

Action management support in SAF:


- Annotate a method by @Action(name = “?”), the method will then be called when
the action occurs. There is no need to define a class and implement the Action
interface. The action instance is generated automatically and managed in an
action map (retrieved by getContext().getActionMap()) by the SAF.
- Set the action to the Swing component by using the setAction() method. E.g.
ActionMap am = getContext().getActionMap();
button1.setAction(am.get(“?”)); // where ? is the name specified in @Action

Resources management support:


- To let users to customize the appearance of an application, resources such as
strings, fonts, colours and images should be externalized instead of hard-
coding in source code. This way, updating external resources does not require
re-compilation of programs and localization support is easier.
- The resources for a class form a resource bundle, which is implemented in a
.properties file. It specifies each resource by a key-value pair separated by “=”.
For a Customer class, the resource bundle is resources/Customer.properties
- SAF supports the use of resources in 3 ways:
Obtaining resources programmatically using the ResourceMap class
Injecting resources automatically into GUI components using their names
Injecting resources automatically into instance vars by @Resource annotation
- Resource bundle example, file res/resources/ResourceExample.properties:

Page 11 of 87
Application.id = res.ResourceExample // ResourceExample class in res package
Application.title = Demo Program
exit.Action.text = Exit Button Text
label1.text = This is the text of label1
ResourceExample.byetext = Bye bye!
ResourceExample.confirmtext = Confirm
Obtaining resources programmatically using the ResourceMap class:
- ResourceMap resource = getContext().getResourceMap(ResourceExample.class);
- resource.getString(“ResourceExample.byetext”);

Injecting resources automatically into GUI components using their names:


- Assign a name to the GUI component using setName() inherited from Component.
- JLabel label = new JLabel();
- label.setName(“label1”); // the label’s text will be automatically injected with label1.text

Injecting resources automatically into instance vars by @Resource annotation:


- @Resource private String confirmtext; // associated with key ResourceExample.confirmtext
- @Resource(key=“ResourceExample.confirmtext”) private String otherName; // diff. key
name
- And when the applications starts, execute the following code to inject inst. vars.
- ResourceMap resource = getContext().getResourceMap(ResourceExample.class);
- Resource.injectFields(this);

Localization using multiple resource bundles:


- To support zh, another resource bundle named ResourceExample_zh.properties can
be defined to store the resources in zh. If the running machine’s locale is zh,
this resource bundle will be used. The original resource bundle is the default.
Note that it is not required for a localized resource bundle to contain all
resources in the default bundle.

JavaFX:
- It is a declarative language that is compiled into Java classes and executed in a
JVM. It is stored in a file with .fx extension.
- It aims to facilitate the development of Rich Interactive Applications (RIAs) in
desktop and mobile. It is designed specifically for creating content-rich UI.

JavaFX Syntax:
- JavaFX uses the same import and package statements as Java
- The JavaFX Stage class represents a window (like JFrame in Swing)
- The Scene class is the content pane in a Stage (like the content pane of a JFrame)
- The javafx.scene.control.Label class represents a label GUI component.
- The HBox, Vbox and Title classes are like Horizontal, Vertical Box and GridLayout.
- The [ ] symbol is used to define a sequence in JavaFX (like an array in Java)
- You can invoke Java APIs in JavaFX programs just like in you do in Java
- Instance variables are defined like this: var str = “A String”;
JavaFX example:
- Stage {
- title: “Hello”
- scene: Scene {
- width: 300
- height: 200
- content: HBox {
- content [

Page 12 of 87
- Label { text: “Press the Button” },
- Button { text: “Button Text” }
- ]
- }
- }
- }
- The above code creates an anonymous object of type Stage. The instance vars
title and scene of the Stage object are initialized. The content of the scene object
contains a HBox object, which in turn contains a Label and a Button object.

Basic data types in JavaFX:


- String (corresponds to java.lang.String)
- Boolean (corresponds to java.lang.Boolean)
- Number (represents floating point numbers that corresponds to java.lang.Number)
- Integer (corresponds to Java byte, short, int, long, java.math.BigInteger)
- javafx.lang.Duration (no corresponding type in Java): e.g. 10ms, 2.5s, 1h+1.5m

Interpolation in JavaFX:
- Interpolation is a powerful feature for String manipulation. For example,
- var course = “MT811”; // declare a string variable
- println(“Hello {course}”); // the expression within {} are evaluated at runtime

Sequences:
- Declaration: [0, 1, 2, 3], [0..3] // include 3, [0..<3] // exclude 3
- JavaFX sequence is not nested. [0, 1, [2, 3]] is automatically flattened to [0, 1, 2, 3]

Flow controls:
- if-then-else: if (n mod 2 == 0) then { … } else { … }
- for-in: for (i in seq1) { println(i); }

Binding in JavaFX:
- Tracking of data changes for automatically updating the bound variables
- The binding is set up by the bind keyword. E.g. var n = 0; var n1 = bind n;
- A bound function can be set up by the bound keyword:
- bound function ntimes(x) { x * n; } // case 1: n2 is updated if n changed
- function ntimes(x) { x * n; } // case 2: n2 is not updated if n is changed
- var n2 = bind ntimes(10);

Triggers in JavaFX:
- Enable operations to be specified in the source of changes. E.g.
- var n1 = 1 on replace { println(“n1 is changed.”); };
- var n2 =1 on replace oldvalue = newvalue { println(“n2 is changed: {oldvalue} -> {newvalue}”); }

Event handling in JavaFX:


- Achieved by the action instance variable:
- Button {
- text: s
- action: if ("0123456789.".contains(s))
- function() { processDigit(s); }
- else if ("+-* /".contains(s))
- function() { processOperator(s); }
- }

Page 13 of 87
Graphics programming in JavaFX:
- Shapes are represented by classes in JavaFX. E.g. Circle, Ellipse, Line, Rectangle
- Circle {
- centerX: bind scene1.width / 4 // scene1 is the ref var to the Scene object
- centerY: 100
- radius: 50
- fill: Color.RED
- }

Animation in JavaFX:
- uses the Timeline class: can be thought of as an animation thread that consists
of one or more key frames. Each frame is represented by the KeyFrame class.
E.g.
- var anim = Timeline {
- repeatCount: Timeline.INDEFINITE
- autoReverse: true
- keyFrames: [
- keyFrame {
- time: 0s
- values: x => 0
- action: function() { xVisible = true }
- },
- KeyFrame {
- time: 2s
- values x=> 100
- action: function() { xVisible = false }
- }
- ]
- }
- anim.play();

Unit 04 – Socket and client/server programming


What can you do with a Java network program:
- Retrieving and displaying data (maybe repeatedly)
- Uploading data to server (maybe large volume of data such as images)
- Implementing peer-to-peer interaction program such as group communication
- Implementing multithreaded servers of any kind
- Use RMI to build tiered applications

Layers in TCP/IP suite and their example protocols:


- Physical (Ethernet)  Network (IP)  Transport (TCP)  Application (HTTP)

IP:
- A network layer protocol for host addressing
- Classes: A (1-126), B (128-191), C (192-223), D (224-239), E (240 – 255)
- Class D is for multicasting. Class E is reserved for future use.

Domain name system (DNS) (an application layer protocol that uses UDP):
- A system that translate between domain names and IP addresses efficiently
- DNS (System) is implemented as a hierarchy of domain name servers

UDP is suitable when:


- the communicate involves small and independent packets (e.g. ping, DNS)
- the timely transmission of data is more important than the reliability (e.g. video)

Page 14 of 87
- multicasting is required (UDP supports multicasting while TCP does not)

Ports:
- The range of port numbers is 0 to 65535. The well-known ports from 0 to 1023

Java network API for TCP connections:


- InetAddress, Socket, ServerSocket

java.net.InetAddress class:
- static InetAddress getByName(String hostname)
- byte[ ] getAddress(), String getHostAddress()

java.net.Socket class:
- Socket(String host, int port) // constructor
- InputStream getInputStream(), OutputStream getOutputStream()
- close() // closes the socket
* PrintWriter and BufferedReader are usually used to wrap the streams for efficiency in
case text-based protocols is involved (e.g. HTTP).

Client application structure:


- Create a socket by specifying the host and the port number of the server
- Use getInputStream() & getOutputStream() to open streams for communication
- Read and write to the server according to the application-level protocol
- Close the streams and the socket

End-of-line compatibility issue:


- Different OS uses different end-of-line characters. The standard network
protocol uses CRLF. Therefore, instead of using println(), which prints using the
end-of-line character of the underlying OS, use print() with “\r\n” at the end.

The observer pattern:


- java.util.Observer interface: a single void update(Observable o, Object arg) method
- java.util.Observable class: void addObserver(Observer o), void setChanged(), void
notifyObservers(), void notifyObservers(Object arg)
- Note that setChanged() must be invoked before notifyObservers().
- In MVC, the model can be a subclass of Observable and views are Observers

Difficulties in developing server programs:


- Designing application-layer protocol
- Multithreading issues
java.net.ServerSocket class:
- ServerSocket(int port) // constructor
- Socket accept() // listen for and blocks until an incoming connection arrives
- close() // closes this server socket and stop listening

Typical architecture of multithreaded server:


- It contains a ClientHandler inner class that implements the Runnable interface
- A forever loop in main() that listens for incoming requests and delegates each
request to a new ClientHandler in a new thread
- In the ClientHandler class, uses socket.getInputStream() and getOutputStream() to

Page 15 of 87
obtain streams, read/write according to the protocol and close the socket lastly.

Advantages of multithreaded servers:


- Efficient: Handling multiple clients concurrently. Better response time for clients.
- Robust: fail in one thread does not affect the other threads and the server

Uniform Resource Locator (URL):


- Consists of: protocol, hostname, filename and port (optional)
- URL addressable objects are resources like HTML, image, programs …
- The Java URL framework is a collection of API (6 classes & interfaces) that
facilitate the downloading and decoding of URL-addressable objects

URL framework: (we focus on the underlined classes)


- API divided into 2 parts: (1) handling protocols and (2) handling contents
- Handling protocols: the URL class, the URLStreamHandlerFactory interface, the
URLStreamHandler abstract class and the URLConnection abstract class
- Handling contents: the URLConnection abstract class, the ContentHandlerFactory
interface and the ContentHandler abstract class
-
java.net.URL class:
- It supports different protocols: HTTP, FTP
- URL(String string) // creates a URL from the input string
- URLConnection openConnection() // opens a connection to the URL
- InputStream openStream() // opens a connection to the URL and get input stream

Using the URL class to retrieve HTTP resource with different methods:
- By default, the URL class uses the GET method to retrieve HTTP resources and
returns the HTTP response through the input stream opened by openStream(). To
use the POST method, the URLConnection class is needed.
java.net.URLConnection abstract class:
- It is capable of interacting directly with the server to download the resource. It
knows how to generate requests, and interpret the response headers.
- It can be used to read from and write to a URL resource (required for POST)
- It is obtained by the urlObj.openConnection() method
- InputStream getInputStream(), OutputStream getOutputStream()
- setDoInput(boolean b) // default true, setDoOutput(boolean b) // default false
- String getContentType(), int getContentLength() // returns header information

GET Example:
- URL url = new URL(getURL);
- BufferedInputStream bis = new BufferedInputStream(url.openStream());
- … // continue to read from the stream

POST Example:
- URL url = new URL(postURL);
- URLConnection conn = url.openConnection();
- conn.setDoOutput(true); // enables outputting and set the method to POST
- OutputStream out = conn.getOutputStream();
- out.write(postData.getBytes()); // write the POST data to server
- out.close();
- BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line;

Page 16 of 87
- While ((line = in.readLine()) != null) {
- System.out.println(line);
- }

HttpURLConnection class:
- The openConnection() method of a URL object returns an object that is a subclass
of the URLConnection abstract class. When the protocol in the URL is HTTP, a
HttpURLConnection object (concrete subclass of URLConnection) is returned.
- void setRequestMethod(String method), String getRequestMethod() // e.g. returns “GET”
- int getResponseCode(), String getResponseMessage()
- To cast the URLConnection reference to HttpURLConnection:
- if (conn instanceof HttpURLConnection) {
- HttpURLConnection http = (HttpURLConnection) conn;
- System.out.println(http.getResponseCode());
- }
Unit 05 – Datagram, Multicast networking and RMI
TCP vs UDP:
TCP UDP
Connection-oriented Connectionless
Correctness is guaranteed (reliable) Data may be lost (unreliable)
Data arrives in order as they are sent Data may arrive out of order
Overhead involved More efficient
Streams are used for data transmission Datagrams are used instead of streams
Uses Socket and ServerSocket classes Only DatagramSocket class is used
TCP socket is dedicated to a single host UDP socket can send to different hosts
Data received is from a single host Data may come from any host

UDP in Java:
- Java implements UDP with the DatagramPacket and DatagramSocket classes.
- The sender and recipient first create a DatagramPacket and a DatagramSocket
object
- The recipient listens at a specified port number
- The sender packs the data, recipient’s IP and port in the DatagramPacket object.
The DatagramSocket object’s send() method is called to send the datagram.
- The recipient calls the receive() method of the DatagramSocket object to receive.

java.net.DatagramPacket class:
- It carries the data and the address information (both sender and receiver)
- DatagramPacket(byte[] buffer, int length) // constructor for receiving
- DatagramPacket(byte[] buffer, int length, InetAddress address, int port) // for sending
- void setAddress(InetAddress addr), InetAddress getAddress()
- void setPort(int port), int getPort()
- void setData(byte[] buffer), byte[] getData()
- void setLength(int length), int getLength()

java.net.DatagramSocket class:
- It represents a socket for sending and receiving DatagramPackets
- It is bounded to a local address and a local port number
- DatagramSocket() // constructor for sending. Binds to an available port
- DatagramSocket(int port) // for receiving and possibly sending
- void send(DatagramPacket packet)

Page 17 of 87
- void receive(DatagramPacket packet)
- InetAddress getLocalAddress(), int getLocalPort()
- void close(), boolean isClosed() // closes this datagram socket
UDP example:
- Sender:
- DatagramSocket socket = new DatagramSocket();
- Byte[] data = “some data”.getBytes(); // the data length should be conservative
- InetAddress addr = InetAddress.getByName(“host.address.com”);
- DatagramPacket packet = new DatagramPacket(data, data.length, addr, 2222);
- socket.send(packet);
- socket.close();

- Receiver:
- DatagramSocket socket = new DatagramSocket(2222);
- byte buffer[] = new byte[65507]; // the theorectical max. payload of UDP
- DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
- socket.receive(packet);
- // invokes packet.getAddess(), packet.getPort(), packet.getLength(), packet.getData() …
- socket.close();

Multicast networking (a bandwidth-conserving technology):


- TCP and UDP are protocols designed for unicast transmission services. It is
inefficient to send data to multiple recipients using these protocols. If a network
supports a multicast service, multicasting can be used to send the data to
multiple recipients efficiently. A multicast network is a network that a host can
put a single packet on it and have the packet transported to all of the recipients.
- It significantly reduces network load and increase transmission rate.
- It is based on datagram network protocols. Instead of sending to a single
destination, you send a packet to a multicast group.
- Requirement 1: Routers must be able to handle multicast packet
- Requirement 2: All hosts and routers within the network must support IGMP
- IGMP (Internet Group Management Protocol) is the standard for IP
multicasting, which is used to establish host memberships (multicast groups)

Multicast group: (class D: 224-239)


- A multicast group is simply a class D IP. Any host that is interested in the group
needs to join as a group member. With it, the sender does not need to know
how many and who the recipients are. The sender simply sends the data to the
multicast group’s IP and the multicast network protocol takes care of the job.

Time to live (TTL):


- It is important to define TTL for multicast packets to prevent forever
transmission
Multicast vs Broadcast:
- Broadcast means a single transmission operation that causes a packet to be
received and processed by all hosts that are members of a particular subnet.
Each subnet has an IP reserved for broadcasting, which is usually the last IP.
Broadcasting across multiple networks is usually not permitted by routers.
- Multicasting can be transmitted across multiple networks as long as the hosts
and routers support IGMP. Only hosts that are interested receive the packet.

Advantages and limitations of multicasting:

Page 18 of 87
Advantages Limitations
Reduces transmission traffic to save Every router within must be multicast
transmission cost enabled
Reduce the load placed on the network Security issue: Everyone can send to a
servers given multicast group

Situations that multicasting applies:


- Listening to radio stations that broadcast on the Internet
- Watching live lectures via the Internet
- Network games that involve hundreds of players

java.net.MulticastSocket class: (extends DatagramSocket)


- Adds methods to join or leave a multicast group plus methods to set TTL
- MulticastSocket() // constructor for sending
- MulticastSocket(int port) // constructor for receiving and possibly sending
- void joinGroup(InetAddress mAddr), void leaveGroup(InetAddress mAddr)
- int getTimeToLive(), void setTimeToLive(int ttl) // set TTL of outgoing packets

Port usage in multicasting:


- Multicast and unicast use the same set of UDP ports. When a port is in used by
UDP (DatagramSocket), another MulticastSocket cannot use that port. However,
multiple MulticastSockets can bind to the same port if it is not used by UDP.

Sending and receiving multicast packets:


- It follows the same model as using DatagramSocket except:
- For sending, you can specify a TTL value for the packet using setTimeToLive() of
the MulticastSocket object.
- Before receiving, you need to join the multicast group using joinGroup() of the
MulticastSocket object.
Multicast examples:
- Sender:
- MulticastSocket socket = new MulticastSocket();
- socket.setTimeToLive(1);
- DatagramPacket packet = new DatagramPacket(data, data.length, mgAddr, port);
- socket.send(packet);

- Receiver:
- MulticastSocket socket = new MulticastSocket(port);
- socket.joinGroup(mgAddr);
- byte[] buffer = new byte[65507];
- DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
- socket.receive(packet);
- socket.leaveGroup(mgAddr);

Peer-to-peer model: (contrasts with client/server model)


- A communications model in which each party has the same capabilities and
either party can start a communication session. No server is involved.
- Multicast networking is good for building peer-to-peer application

Remote Method Invocation (RMI):


- A set of high-level APIs that enable Java objects to communicate via their
methods regardless of their location. Thus, networked applications can be

Page 19 of 87
developed without dealing with low-level sockets and complex protocols.

- A remote object must implement one or more remote interfaces.


- RMI provides the necessary mechanism for passing information back and forth
between the client and remote objects.
RMI registry:
- It provides a mapping between names and object references for uses by the
server and client. With it, only a single socket is needed to listen to client
requests for all the bound remote objects so that scalability is promoted.
- The RMI registry can be provided by a command-line tool in the JDK, rmiregistry,
or embedded in a RMI server by using the RMI API.

Programs in an RMI application:


- Remote interface: specifies the method(s) that can be invoked remotely
- Remote object: the object that implements the remote interface
- RMI server: creates remote objects and registers them to the RMI registry
- RMI client: lookups and invokes the remote objects

Remote interface:
- All remote interfaces extend the java.rmi.Remote interface and all remote methods
must be declared to throw java.rmi.RemoteException. E.g.
- public interface Daytime extends Remote {
- public Date getDate() throws RemoteException }

Remote object:
- A remote object may subclass from UnicastRemoteObject or RemoteObject class
(both in java.rmi.server) and provide a constructor that throws RemoteException.
E.g.
- public class DaytimeImpl extends UnicastRemoteObject implements Daytime {
- public DaytimeImpl() throws RemoteException { }
- public Date getDaye() { return new Date(); }
- }

RMI server:
- It creates a remote object (new DaytimeImpl()) and binds it in the RMI registry
using the bind(String name, Remote ref) method of java.rmi.Naming class. The Naming
class provides registry and lookup services to server and client respectively.
- The creation of remote object may throw RemoteException and the bind() method

Page 20 of 87
may throw AlreadyBoundException and MalformedURLException. So, the server must
handle these exceptions. E.g.
- Psvm() throws RemoteException, AlreadyBoundException, MalformedURLException {
- DaytimeImpl daytime = new DaytimeImpl();
- Naming.bind(“daytime”, daytime);
- }
RMI client:
- It looks up the remote object by specifying the host name and the registered
name of the remote object. For example, “rmi://localhost/daytime” looks up the
remote object with name “daytime” in the RMI registry running on localhost.
- Psvm() throws RemoteException, NotBoundException, MalformedURLException {
- Daytime daytime = (Daytime) Naming.lookup(“rmi://localhost/daytime”);
- Date now = daytime.getDate();
- }

java.rmi.Remote class:
- It is just a marker interface that declares no methods. An RMI client will always
access the remote object through its remote interface.

class:
java.rmi.RemoteException
- It is the common superclass of a number of communication-related exceptions
that may occur during the execution of RMI. All methods specified in a remote
interface must be declared to throw it.

java.rmi.Naming final class:


- For storing & obtaining references to remote objects in the RMI registry.
- void bind(String name, Remote remoteObj) // may throw AlreadyBoundException
- void rebind(String name, Remote remoteObj) // rebinds the name to a new remote obj
- void unbind(String name) // removes the binding. May throw NotBoundException
- Remote lookup(String name) // used by client. May throw NotBoundException
- String[] list(String registryURL) // list the names of bound objects
- A program can bind, unbind or rebind if it runs on the same host as the RMI
registry. The remote objects, however, can be running on any host.
- Internally, the Naming class makes use of the java.rmi.registry.Registry interface and
the java.rmi.registry.LocateRegistry class.

java.rmi.registry.LocateRegistry class:
- Its task is to make an initial connection to an RMI registry, or to create an RMI
registry that listens on a certain port.
- Registry createRegistry(int port) // create in localhost
- Registry getRegistry() // get registry with default port 1099 in locahost
- Registry getRegistry(int port) // get registry with specified port in locahost
- Registry getRegistry(String host) // get registry with default port 1099 in specified
host
- Registry getRegistry(String host, int port) // get registry with specified port & host
java.rmi.registry.Registry interface:
- It provides helper methods for the binding and lookup of RMI remote objects
- void bind(String name, Remote remoteObj) // may throw AlreadyBoundException
- void rebind(String name, Remote remoteObj) // rebinds the name to a new remote obj
- void unbind(String name) // removes the binding. May throw NotBoundException
- Remote lookup(String name) // used by client. May throw NotBoundException
- String[] list() // list the names of bound objects

Page 21 of 87
java.rmi.server.RemoteObject & RemoteServer abstract class:
- RemoteObject is the ultimate superclass of all remote objects. It implements the
Remote & Serializable marker interfaces. RemoteServer is a subclass of RemoteObject.

java.rmi.server.UnicastRemoteObject class:
- It is a concrete subclass of the RemoteServer class. It is used as the immediate
superclass for most normal remote objects. It provides static methods for
exporting a UnicastRemoteObject. The exportation is automatically done in the
constructor of the UnicastRemoteObject in case your remote object subclasses
from it. If you do not subclass from it, you can also export the object by invoking
the static RemoteStub exportObject(Remote remoteObj) method.

Starting the RMI registry server:


- In DOS window, type the rmiregistry command to start the RMI registry server
- Create the RMI registry server automatically using LocateRegistry.createRegistry()

Using LocateRegistry and Registry:


- Server: you don’t need to run the rmiregistry command manually
- Registry registry = LocateRegistry.createRegistry(1099);
- registry.bind(“counter”, remoteObj);
- Client:
- Registry registry = LocateRegistry.getRegistry(“localhost”); // find registry listening to
1099
- Counter counter = (Counter) registry.lookup(“counter);

Stubs and skeletons:


- A stub, on the client side, is a reference to the remote object. It marshals
method parameters and converts remote method calls to network requests.
- A skeleton, on the remote side, accepts requests from stub. It unmarshals
method parameters and invokes the actual method on the remote object. It also
marshals the return value or exception and sends it back to stub.

RMI can pass the following 2 types of objects:


- Remote objects: objects that implement the Remote interface

Page 22 of 87
- Serializable non-remote objects: objects that implement the Serializable interface
* Objects that do not implement the Remote or Serializable interface cannot be
passed

Passing Remote objects:


- RMI passes the reference of a remote object from a host to another host as a
stub. Both hosts hold references to the same instance (single instance).

Passing Serializable non-remote objects:


- RMI passes serializable non-remote objects by making copies and sending
them across the network using Java serialization (convert the objects into bytes
for transmission). Since the second host holds a copy, changing its states has
no effect on the server’s copy.

Disadvantages
Passing Remote object Invoking methods on server’s copy is slower
Passing Serializable object Serializing large object can be slow

Dynamic class loading:


- It supports the dynamic loading of class files along with passed parameter and
return type from one host to another host.

Why need it?


- Suppose a remote method expects void aMethod(A a). It can be invoked by a
client with argument of class B, which is a Serializable non-remote subclass of
A. (If class B is a Remote subclass of A, the definition of B is not required
because the remote object deals with stub, which must exists in the server’s
JVM). The problem is that the JVM in the remote machine may not have the
definition of class B. RMI handles this issue by supporting dynamic class
loading.

Security issue of dynamic class loading:


- Dynamic class loading is potentially risky. RMI requires programs that receive
dynamically loaded classes to install a security manager.

Network programming using RMI vs Streams & sockets:


Advantages Disadvantage
RMI - Network transparency: you do - There is communication
not need to deal with sockets overhead in every method call
- Cleaner and Higher-level API - RMI provides less control on the
data being transmitted across
the network
Streams

Unit 06 – Servlets and JSPs


Containers in Java EE platform:
- Web container: for hosting Java Web components such as servlets, JSPs,
JSFs.
- EJB container: for hosting EJB components, which implements business logic
in enterprise applications.

Page 23 of 87
- Application client container: for hosting client Java applications including
console and GUI applications.
- Applet container: for hosting Java applets.
- You may regard container as the runtime environment of application component

Java Web components vs CGI programs:


- CGI is a standard (not language) for Web server to execute external programs.
It defines how data are passed between Web server & external program.
- Web container plus Web component play the role of a CGI program. The Web
container handles the interactions to the Web server according to Java EE
spec.
- Java Web components are more efficient: It is run in a lightweight thread
instead of heavyweight process. It also stays in memory to serve multiple
requests.
- Java Web components better support shared data: A Web component instance
is used to serve multiple requests so that variables can be used to store data
across multiple requests. It does not have to rely on files or OS shared memory.
- Java Web components are platform independent.

Java Web components vs Server plug-ins:


- Platform independent: Server plug-ins is server dependent. Java is not.
- Robustness: Java is executed in a controlled environment (JVM). Failure of
server plug-ins may crash the whole server.

Java Web components vs PHP & Ruby on Rails:


- Java Web components are more efficient due to the maturity of Java and
competition amongst Java EE application servers from different vendors.
- Java Web components have a larger set of built-in and third-party APIs.
- Java Web components have better professional support services.
- There are more PHP hosting services for PHP applications. Some are even
free.
- Ruby on Rails usually results in less development effort than Java.

Servlets:
- They are Java objects that execute on a Web server. Just like applets, they are
not standalone applications. All ?-lets have to follow a specified and well-
defined framework to enable seamless integration with the servers.

Page 24 of 87
- The Web container loads the servlet class the first time it is requested. The
servlet then stays loaded to handle multiple requests until it is explicitly
unloaded or the Web container is shut down.
- All servlets must implement either directly or indirectly the javax.servlet.Servlet
interface, which defines the life cycle methods (init(), service(), destroy()) of a
servlet. The Web container is responsible for the creation and destroying of
servlets and so, it is also responsible for invoking these life cycle methods.
- It is suitable for processing tasks such as login and logout. However, it is
uneasy to use it for presenting HTML content.
javax.servlet.Servlet interface:
- void init(ServletConfig config) // invoked when the servlet is first loaded in container
- void service(ServletRequest request, ServletResponse response) // invoked whenever
request arrives. It may be executed concurrently so that it must be thread-safe.
- void destroy() // invoked just before the servlet is destroyed. It can be used to free
resources and persist serlvet states if required

javax.servlet.ServletRequest interface:
- It encapsulates the communication from client to servlet (request).
- ServletInputStream getInputStream() // binary, BufferedReader getReader() // character
- String getParameter(String name), String[] getParameterValues(String name) // returns the
first value or all values of the request parameter with the specified name.
- Enumeration getParameterNames()

javax.servlet.ServletResponse interface:
- ServletOutputStream getOutputStream() // binary, PrintWriter getWriter() // character
- void setContentType(String type), void setContentLength(int length)

javax.servlet.GenericServlet abstract class:


- It is a simple implementation of the Servlet interface that facilitates the building of
simple servlet applications. It is generally used for writing generic, protocol
independent servlet class. To write servlets that are specific to the HTTP
protocol (i.e. to be executed in a Web server), use the HttpServlet class.

javax.servlet.http.HttpServlet abstract class:


- It defines a servlet that uses the HTTP protocol. It is a subclass of GenericServlet.
- It provides many useful methods for handling HTTP requests and sending
properly formatted HTTP responses.
- doGet(HttpServletRequest request, HttpServletResponse response)
- doPost(HttpServletRequest request, HttpServletResponse response)

javax.servlet.http.HttpServletRequest interface:
- It is a sub-interface of ServletRequest. It provides higher-level HTTP specific
request information for HTTP servlets (e.g. parsing). The Web container creates
an HttpServletRequest object and passes it to the servlet using the service()
method.
- String getMethod() // e.g. returns GET or POST
- String getHeader(String name), int getIntHeader(String name), long getDateHeader(String
nam)
- Cookie[ ] getCookies(), HttpSession getSession(), HttpSession getSession(boolean create)
javax.servlet.http.HttpServletResponse interface:
- A sub-interface of ServletResponse. It provides methods for sending HTTP

Page 25 of 87
specific response to the client. The Web container creates an HttpServletResponse
object and passes it to the HTTP servlet through the service() method.
- void setStatus(int code), setStatus(int code, String message) // set status code in case of
no error. E.g. SC_OK
- void sendError(int code), sendError(int code, String message) // send error response
- void sendRedirect(String location) // send redirection e.g. request.sendRedirect(“./Home”);
- void setHeader(String name, String value), setIntHeader(String name, int value),
setDateHeader(String name, long value)
- void addCookie(Cookie cookie) // adds a cookie to the response to be stored in client

javax.servlet.http.Cookie class:
- A piece of information that is stored on the client side at the request of server
- Cookie(String name, String value) // constructor
- String getValue(), void setValue(String value)

javax.servlet.http.HttpSession interface:
- It defines methods for manipulating HTTP sessions, which allows servlet to
identify a user and maintain the user’s information across multiple requests.
- Object getAttribute(String name), void setAttribute (String name, Object value)
- void removeAttribute(String name)
- Enumeration getAttributeNames()

Retrieving parameters in HTTP requests:


- Parameters can be sent in query string (GET) or using form (GET or POST)
- In both cases, We can use the String getParameter(String name) method of the
HttpServletRequest object to retrieve the parameters. It returns null if name not
exists

Determine MIME and set content type:


- For a HttpServlet, the getServletContext() can be used to get the context:
- String mime = getServletContext().getMimeType(filename);
- response.setContentType(mime);

Forwarding and Including other resource:


- It is done by the RequestDispatcher object. Within doGet() or doPost(),
- RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(“/Navigation”);
- dispatcher.include(request, response); / dispatcher.forward(request, response);
Benefits common to Servlets & JSP:
- Efficiency, Portability, Robustness, Ease of data sharing
Strengths
servlets They are more suitable for processing tasks
They are better for generating binary output
JSPs They are more suitable for content presentation
They work with webpage design tools
No manual compilation is needed, which leads to shorter develop cycle.

JavaServer Pages (JSPs):


- It is another type of Web componenets. A JSP file has file extension “.jsp”.
- All JSPs are converted to servlets by the Web container for execution.

Page 26 of 87
Types of JSP constructs:
- Directives: page, include, taglib, tag, attribute, variable (totally 6)
- Scripting elements: scriptlets, expressions and declarations
- JSP implicit objects: pageContext, request, session, application, response, out …
- Standard actions (built-in tags): <jsp:useBean>, <jsp:setProperty>, <jsp:getProperty>,
<jsp:include>, <jsp:forward>
- Expression language (EL): ${ … EL expression … }
- JSP Standard Tag Library (JSTL): a useful custom tag library
- Custom tags:

page directive:
- <%@ page contentType=”text/plain” import=”java.text.DateFormat %> // sets content type
of the response to ”text/plain”, and imports the class in the translated servlet

include directive:
- Includes static file in the JSP during the translation process
- <%@ include file="copyright.jsp" %>
taglib directive
- Defines a tag library and the prefix to be used in the JSP.
- <%@ taglib prefix=“c” uri=”http://java.sun.com/jsp/jstl/core” %> // the ‘c’ prefix can be used
in the JSP to invoke the tags in the tag library. E.g. <c:set var=”count” value=”10” />

tag, attribute
and variable directives:
- Used in defining tag files, which are used to define custom tags in JSP syntax.

Scripting elements:
- Scriptlets: <% … %> You may think of scriptlets as being executed in the service()
method of the generated servlet. Therefore, flow control, function calls, variable
declaration and inner class definition are allowed but import/package
statements and method definitions are not allowed.
- <% if (Math.random() > 0.5) { %>
- servlets
- <% } else { %>
- JSPs
- <% } %>

- Expressions: <%= … %> You may think of expressions as the parameters of


println() methods that are invoked inside the service() method.
- <p>The current time is: <%= new java.util.Date() %> </p>

Page 27 of 87
- Declarations: <%! … %> For defining variables and methods in JSPs. They are
placed outside the service() method within the generated servlet class.
- <%! int random100() { return (int) (Math.random() * 100); } %>
- <p>A random number between 0 and 100: <%= random100() %> </p>

JSP comments:
- <%-- JSP comments --%> // they are removed during translation to servlets, so they
will not be sent to the client.

JSP Implicit objects and API:


- Used in JSP scripting elements to obtain the request and response objects.
They are automatically available in JSPs:
- request: (HttpServletRequest), response: (HttpServletResponse)
- application: (ServletContext), session: (HttpSession)
- out: (javax.servlet.jsp.JspWriter), pageContext: (javax.servlet.jsp.PageContext)
- E.g. <% out.println(new java.util.Date()); %> equals to <%= new java.util.Date() %>
Scopes of attributes in a JSP:
- In servlets, you attach attributes to different scopes by setAttribute() of HttpSession,
ServletRequest or ServletContext object. In JSP, you use the PageContext object.
- PAGE_SCOPE: attached to the pageContext object. Objects in it exist wintin a
single JSP file.
- REQUEST_SCOPE: attached to the request object. Objects in it exist in the request
of the client, across page forwarding and inclusion on the same request.
- SESSION_SCOPE: attached to the session object. Objects in it exist in the HTTP
session across multiple requests from the same client.
- APPLICATION_SCOPE: attached to the application object. Objects in it exist across
the whole Web application.
- For example, user’s login status should be attached to the session object.

javax.servlet.jsp.PageContext Class:
- It provides accessing to the attributes of various scopes, performs forwarding
and including.
- Object getAttribute(String name), void setAttribute(String name, Object o) // page scope
- void removeAttribute(String name) // page scope
- Object getAttribute(String name, int scope), void setAttribute(String name, Object o, int scope)
- void removeAttribute(String name, int scope)
- Enumeration getAttributeNamesInScope(int scope)
- void forward(String relativeURL), void include(String relativeURL)

Problems of using scripting elements in JSP:


- The mixing of presentation logic (content) with processing logic (code) makes
development and maintenance difficult in large Web applications. It’s better to
separate them. Scripting elements should be avoided whenever possible.
- Other JSP elements (Standard actions, EL, JSTL and simple tags) can be used
to achieve the functionalities of scripting elements without using Java code.

Standard actions (JSP built-in tags):


- They are predefined (built-in) tags in JSP. They can be categorized according to
their functionalities:
- Manipulating JavaBeans: <jsp:useBean>, <jsp:getProperty>, <jsp:setProperty>
- Including and forwarding to another page: <jsp:include>, <jsp:forward>, <jsp:param>

Page 28 of 87
- Handling Java plugin: <jsp:plugin>
- Creating tag files: out of scope of the course

Manipulating JavaBeans using standard actions:


- <jsp:useBean id=”user1” class=”utility.User” scope=“request” /> //get or create a JavaBean
object named user1 of utility.User type in the request scope (default page scope)
- <jsp:setProperty name=”user1” property=”username” value=”Mary” /> // set the username
property of the user1 object to the value “Mary”
- <jsp:getProperty name=”user1” property=”username” /> // get the property
- To get or create JavaBean object and initialize it if creation is involved:
- <jsp:useBean id=”user2” class=”utility.User”>
- <jsp:setProperty name=”user2” property=”username” value=”John” />
- </jsp:useBean>
- To set property to the parameter value of JSP:
// the username property is set to
<jsp:setProperty name=”user2” property=”username” />
the value of the parameter that has the same name “username”

Including and forwarding using standard actions:


- <jsp:include page=”./AnotherPage.jsp” flush=”true” /> // include the output of AnotherPage
to the current page. The inclusion is performed at run-time (not translation-time
in <%@ include %> directive). Change in AnotherPage is automatically refreshed.
- <jsp:forward page=”./AnotherPage.jsp”>
- <jsp:param name=”username” value=”David” />
- </jsp:forward>
- The <jsp:param> tag can also be used in <jsp:include>

Benefit of Standard actions over Scripting elements:


- No Java code is involved in standard actions

Expression Language (EL):


- It provides a mechanism to access EL implicit objects, scoped variables in JSP
without using scripting elements. Its syntax is ${ … EL expression … }
- Displaying the username property of a bean named u in 3 different ways:
- EL: ${u.username} / ${u[“username”]}
- Standard action: <jsp:getProperty name=”u” property=”username” />
- Scripting element: <%= u.getUsername() %>

EL Operators:
- . and [ ] // for accessing property of object
- empty // tests for emptiness of a value. It returns true for a null value, a
container that has no element, and a string of zero length (${empty “”} => true).
EL implicit objects:
- Similar to JSP implicit objects, it provides access to scoped variables. However,
EL implicit objects are not the same as the JSP implicit objects. For example,
the request and response JSP implicit objects cannot be used directly in EL.
- pageContext: (PageContext)
- pageScope: (java.util.Map), requestScope: (Map), sessionScope: (Map)
- applicationScope: (Map) // A map of all objects in the corresponding scope
- param: (Map) // A map of all request parameters, each in a (String, String) pair
- paramValues: (Map) // parameters that have multiple values, in a (String, String[])
pair

Page 29 of 87
Notes on EL:
- ${noSuchBean} and ${pageContext.noSuchMember} evaluates to empty string
- ${Math.random()} is invalid because Java APIs cannot be used in EL expressions

JSP Standard Tag Library (JSTL): (not standard actions)


- JSP actions (tags) are either built-in (standard actions) or custom. JSTL is a
useful custom tag library. It provides advance features in developing JSPs
without directly using Java code. It consists of 4 tag libraries and a function lib.

Libraries in JSTL:
- Core tags: <%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
- XML tags: <%@ taglib prefix=”x” uri=”http://java.sun.com/jsp/jstl/xml” %>
- SQL tags: <%@ taglib prefix=”sql” uri=”http://java.sun.com/jsp/jstl/sql” %>
- Formatting tags: <%@ taglib prefix=”fmt” uri=”http://java.sun.com/jsp/jstl/fmt” %>
- Functions: <%@ taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions” %>

Steps to use JSTL in writing JSPs:


- Include the JSTL library (jar files) in your Web application
- Write a taglib directive for each of the library that you want to use
- Apply the JSTL tags or functions in your page

JSTL Core tags:


- It provides programmatic support for JSP without using scripting elements.
- Manipulating variables and objects:
- <c:set>: sets the value of a variable, a JavaBean property or an entry in a map.
- <c:remove>: removes a variable or an attribute in a scope in JSP.
- Flow controls:
- <c:if>, <c:forEach>
Simple Tags:
- Apart from standard actions and JSTL, we can create our own custom tags.
There are two ways of creating custom tags in JSP:
- Classic tags: out of scope of the course
- Simple tags: they are implemented by tag files, which are JSP files with file
extension “.tag”. The tag file contains JSP fragment that is invoked when the
custom tag is used. You can think of a tag file as the definition of a Java
method, and using the tag is like calling the method.

Steps to create simple tag:


- Create a tag file with extension “.tag”. If you want to pass an attribute (like a
method parameter) to the tag file, write an attribute directive in the tag file.
- Add a taglib directive to specify the prefix and tagdir attribute
- Use the tags with the specified prefix

Web application architectures with JSPs:


- Model 1 architecture:

Page 30 of 87
- It is simple to use and appropriate for small applications

- Model 2 architecture:

- A servlet accepts and processes the client request, and forwards processed
results to a JSP for building the response content.
- Advantages: reducing complexity and increasing reuse by mixing the strengths
of both servlets and JSPs.
Unit 07 – Java database and persistence programming
Client/Server architecture:
- 2-tier: a client (consists of UI and application logic) and a server (DBMS). The
client and server communicate with SQL.
- 3-tier: an additional middle tier between client and server. Client (UI), middle tier
(called application server, business logic and translations of client requests and
server responses) and server (DBMS). The client and application server
communicate with RMI, HTTP, etc. The application server communicates with
DBMS through JDBC, JPA, etc. The middle tier can be implemented using Web
components (e.g. servlets) and/or EJB.

Advantages Disadvantages
2-tier - Lower cost - The risk of exposing the
- The architecture is simple business logic as they are
embedded in client
- Business logics can be messed
up for different clients
- Modification may have to be
done on multiple locations
- Less scalable
3-tier - Business logic is separated from - Higher cost

Page 31 of 87
UI, which reduces the chance of - The architecture is more complex
messing up business logic for
due to the added tier
new clients
- Single place for business logic
modification & deployment
- Easily scalable
- Centralize access control and
connection pooling are possible
- Suitable for complex systems

Java Database Connectivity (JDBC) allows you to:


- Establish connection to the DBMS
- Send SQL statements to the DBMS for execution
- Process the result set of a query

JDBC supports connection pooling and distributed transactions. It is commonly


used in the middle tier of a 3-tier architecture.
There are 4 types of JDBC drivers:
- Type 1 driver (JDBC-ODBC bridge): translates JDBC calls to ODBC calls
- Type 2 driver: talks to platform dependent native RDBMS library
- Type 3 driver: talks to RDBMS directly using platform independent standard
protocols, such as HTTP
- Type 4 driver: talks to RDBMS directly using vendor-dependent protocols

Advantages Disadvantages
Type 1 - Fast and easy to develop - ODBC driver must be installed on
- Platform independent the client machines.
- Poor performance due to overhead
of translation
Type 2 - Better performance than type - DBMS native library must be
1 installed on client machines
- Platform dependent
Type 3 - Better performance than 1 & 2 - Overhead in translation to standard
- Suitable for applications protocols
deployed over the Internet
Type 4 - Maximum performance - Not suitable for deployment over
the Internet as proprietary protocols
are used
In a production environment, it is recommended to use only type 3 or 4 drivers for
better performance and easy maintenance.

Page 32 of 87
The java.sql.DriverManager class:
- manages the JDBC drivers
- provides methods for obtaining database connections
- Class.forName("org.apache.derby.jdbc.ClientDriver");
- Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);

The java.sql.Connection interface:


- Represents a database connection to a DBMS
- Provides methods for obtaining statement objects
- Statement stmt = conn.createStatement();
- PreparedStatement ps = conn.prepareStatement(sqlStmtWithQuestionMark);
- CallableStatement cs = conn.prepareCall(sqlStmtWithQuestionMark);
- conn.close(); // close the connection & its associated Statement

Three types of statements in JDBC:


- Statements (java.sql.Statement interface): used for infrequent SQL
- Prepared statements (java.sql.PreparedStatement interface): pre-compiled
statements that are used frequently, with better performance
- Callable statements (java.sql.CallableStatement): used for executing stored
procedures and system procedures in DBMS

The java.sql.Statement interface:


- Represents a static SQL statement to be sent to DBMS for execution
- ResultSet rs = stmt.executeQuery(selectSql);
- int rowsAffected = stmt.executeUpdate(updateSql);
- stmt.close(); // close the Statement and its associated ResultSet

The java.sql.ResultSet interface:


- Represents a result set of a SELECT statement
- while (rs.next()) { // move cursor forward by 1 record, false if no
more
- int intValue = rs.getInt(1);
- String strValue = rs.getString(“columnName”);
- }
- rs.close(); // close the result set

The java.sql.PreparedStatement interface:


- A sub-interface of Statement which contains pre-compiled SQL command
- ps.setInt(1, id); // setting the 1st parameter of prepared statement

Page 33 of 87
- ps.clearParameters(); // clear all parameter values
- ResultSet rs = ps.executeQuery();
- int rowsAffected = ps.executeUpdate();
* Adv: The setXXX() method automatically escapes SQL special characters
The java.sql.CallableStatement interface:
- A sub-interface of PreparedStatement which contains SQL stored procedure
- cs.setInt(1, id); // setting the 1st parameter of callable statement
- cs.getString(2); // returns the 2nd parameter value
- cs.execute();

Stored Procedure advantages:


- Reduced network traffic and client-side processing as calculation is performed
on the DBMS on server side
- Easier to maintain as there is only a single copy of stored procedure
For updateable ResultSet (those created with ResultSet.CONCUR_UPDATABLE),
the following methods can be used to update table:
- rs.moveToInsertRow(); // creates an empty row
- rs.updateInt(“CustomerID”, 5); // set CustomerID to 5 (not update DB)
- rs.insertRow(); // persists the change by insert
- rs.updateRow(); // persists the change by update
- rs.deleteRow(); // advance cursor to next row automatically

However, it’s preferable to use Statement/PreparedStatement for update because:


- Not all JDBC drivers support updatable result sets
- Using ResultSet to update often involves looping and selection logic in the
JDBC program. As DBMS is optimized for these operations, it is better to
perform these tasks on the DBMS

Transaction:
- Connection object is created with auto commit by default
- conn.setAutoCommit(false); // turn off auto commit
- conn.commit(); / conn.rollback();

Java Persistence API (JPA):


- Similar to JDBC, but a higher-level API for database access.
- Enables you to access database via plain Java objects without using SQL.

Page 34 of 87
* The relationship between
Persistence API & providers
is like JDBC & database
drivers

- Entity: POJO with JPA annotations


- Persistence API: standard API defined in JPA spec for manipulating entities
- Persistence Provider: implementation library according to the JPA spec. The
provider is selected by means of a config file. It may use JDBC inside.
Example JPA compliant persistence providers:
- TopLink, EclipseLink, Hibernate

Annotations for Entity (javax.persistence.*):


- @Entity: defines that the class is an entity that represents a table
- @Id: defines the primary key of a table
- @Table: for table mapping in case the class & table names are different
- @Column: for column mapping in case the property & column names are diff.
- @Transient: for defining non-persistence property (i.e. not method) that does
not correspond to a persistent field in the database table

Rules for entity classes:


- It must be annotated with @Entity
- At least one instance field, getter or setter method must be annotated with @Id
- There must be a public or protected default constructor (no parameter)
- An entity class must not be “final”. All methods and persistent instance variables
must not be final.
- For an entity object to be passed by value, it must implement “Serializable”
- All persistent instance variables must not be public

An example Entity class:


@Entity

Page 35 of 87
@Table(name = “Customer”)
public class Buyer {

private int buyerID;


private String firstName;
private String lastName;

@Id
@Column(name = “CustomerID”)
public int getBuyerID() {return buyerID;}
public void setBuyerID(String buyerID) {this.buyerID = buyerID;}

@Transient // there is no “Name” field in database }


public String getName() {return firstName + “ ” + lastName;}
}

Persistence Context and EntityManager interface:


- Entity objects are connected to the database at runtime via a persistence
context. We manipulate the persistence context via the EntityManager API,
which represents an entity manager object.

Functionalities of the EntityManager interface:


- Database synchronization and Transaction control
- Entity lookup and queries
- Entity life cycle management

Steps to obtain EntityManager in J2SE:


- use the Javax.persistence.Persistence class to obtain the
EntityManagerFactory
- use the Javax.persistence.EntityManagerFactory object to obtain the manager
- The set of entities that can be managed by the manager is defined in a
persistence unit, which is a packaging of related entity classes, selected
persistence provider, database mapping and other configuration data. It is
specified in a persistence.xml file.
EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenceUnitName);
EntityManager manager = factory.createEntityManager();
… processing …
manager.close();
factory.close(); // release resources

Page 36 of 87
The javax.persistence.EntityManager interface:
- provides a set of methods for manipulating entities in a persistence context
- manager.getTransaction().begin(); // begin a transaction
- Customer c = manager.find(Customer.class, 1); // lookup entity, null if not found
- if (c != null) { c.setFirstName(“new name”); }
-
- Customer c1 = new Customer();
- c1.setCustomerID(10);
- System.out.println(manager.contains(c1)); // prints “false”
- manager.persist(c1); // let the manager manages this new entity
- System.out.println(manager.contains(c1)); // prints “true”
-
- Customer c2 = manager.find(Customer.class, 3);
- if (c2 != null) { manager.remove(c2); }
- manager.getTransaction().commit(); // commit a transaction
Entity life cycle states:
- An entity instance can be in one of 4 states: new, managed, detached, removed

- New: the instance is newly created by a constructor and not persisted yet. In
this state, any change to the instance does not update the database.
- Managed: The instance is managed in a persistence context and associated
with a database record according to the primary key value. In this state, any
change to the entity is updated to the database. (With active transaction, the
entity returned by find() goes to this state)

Page 37 of 87
- Detached: The entity is associated with a database record, but not with a
persistence context. When a persistence context ends, all its managed entities
go to this state. (Without active Tx, entity returned by find() is in this state)
- Removed: The entity is associated with a persistence context and its
associated database record is scheduled to be deleted.

Life Cycle events for Entities:


- Methods can be annotated to handle specific life cycle events.
- @PrePersist/PostPersist: invoke the method before/after the entity is persisted.
- @PreRemove/PostRemove
- @PreUpdate/PostUpdate
- @PostLoad: invoke the method after the entity is loaded
- @PreRemove
- public void handlePreRemove() { // maybe some clean up work }

The javax.persistence.Query interface:


- represents an entity query, which can get a set of entities based on some
criteria
- List getResultList() // returns the results of a SELECT query
- Object getSingleResult() // returns the first result of a SELECT query
- Query setParameter(String name / int pos, Object value) // sets the value of a query parameter
- Query setFirstResult(int startPos) // sets the position of the first result to retrieve in SELECT
- Query setMaxResults(int n) // sets the maximum number of results to retrieve in SELECT
- int executeUpdate() // execute an UPDATE or DELETE query

Steps to run named entity query:


1. define the command in the form of SQL or Java Persistence Query Language
2. obtain the query object
3. set the query parameter, if any, by using setParameter() method
4. run getResultList(), getSingleResult() or executeUpdate() to run the query

Types of entity queries:


- Named queries / Static queries: for Java Persistence Query Language, the
query command is specified in an entity class by using the @NamedQuery
annotation. An entity class can have multiple named queries, specified by
@NamedQueries, which contains an array of @NamedQuery. For SQL, the
@NamedNativeQuery and @NamedNativeQueries annotations are used.
Please note that the names of named queries must be unique within the

Page 38 of 87
persistence unit. Below is an example entity class that contains named queries:
@Entity
@NamedQueries( {
@NamedQuery(name=“Q1”, query=“SELECT c FROM Customer c”),
@NamedQuery(name=“Q2”, query=“SELECT c FROM Customer c
WHERE c.firstName = :firstName”)
})
public class Customer { … }

And the program that invokes the queries:


Query q1 = manager.createNamedQuery(“Q1”);
List customers = q1.getResultList();
Query q2 = manager.createNamedQuery(“Q2”);
q2.setParameter(“firstName”, “David”);
Customer david = (Customer) q2.getSingleResult();

- Dynamic queries: defined at runtime before they are executed in the program.
For Java Persistence Query Language, use the EntityManager.createQuery()
method to create the dynamic query. For SQL, use createNativeQuery().
Query q3 = manager.createQuery(“SELECT MAX(c.customerID) FROM Customer c”);
int maxID = (int) q3.getSingleResult();

Entity Relationships:
- JPA provides support for entity relationships by annotating entity classes and
runtime facilities for accessing related entities.

Multiplicity of relationships (owner to target):


one to one one to many many to one many to many
@OneToOne @OneToMany @ManyToOne @ManyToMany

Directions of relationship (owner vs target):


- unidirectional: owning direction only. An owner entity can access its related
target entities, but the inverse direction is not supported.
- bi-directional: traversal can be done on both directions.

Seven combinations of relationship multiplicity & direction:


- One-to-one unidirectional / bi-directional relationship
- Many-to-many unidirectional / bi-directional relationship

Page 39 of 87
- One-to-many unidirectional relationship
- Many-to-one unidirectional relationship
- Many-to-one bi-directional relationship = One-to-many bi-directional relationship

Many-to-one bi-directional example (Item to Customer):


In Item entity class:
private Customer customer;
@ManyToOne
@JoinColumn(name="CustomerID") // the Customer ID foreign key in the Item table
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; }
In Customer entity:
private List<Item> items;
@OneToMany(mappedBy="customer") // the customer property in the Item entity
public List<Item> getItems() { return items; }
public void setItems(List<Item> items) { this.items = items; }
Unit 08 – Developing business components with Java
Java EE is a collection of Java technologies for developing enterprise applications.
Web components such as servlet and JSP are part of Java EE. Enterprise
JavaBean (EJB) is also one of the Java EE technologies for building business
components in enterprise applications. Java EE server that conforms to the Java
EE specification should support functions common to enterprise applications, such
as transaction and security control. Some open-source Java EE servers are
GlassFish and JBoss.

Common requirements of enterprise applications:


- Security, Reliability, Availability, Scalability

What is a container:
- It can be regarded as the runtime environment of application components.

Java EE architecture:

Page 40 of 87
Enterprise applications are developed as components and deployed to the different
containers of a Java EE server. There are four types of containers in Java EE:
- Web container: for hosting Web components such as servlets, JSPs & JSFs
- EJB container: for hosting EJB components, which implements business logic
in enterprise applications
- Application client container: for hosting client Java applications including
console and GUI applications
- Applet container: for hosting Java applets
JavaBeans vs EJB:
- EJB is not a blown-up version of JavaBean.
- JavaBean is used for building visible (e.g. JButton) or non-visible components
for software applications, with no support for distributed computing. For
example, Swing components are JavaBeans. EJB is used for developing 3-tier
applications and is never visible. In other words, an EJB is a server-side
component that implements the business logic of an enterprise application.

Why need EJB as we can implement middle tier in servlets?


- If we were using servlets to implement the middle tier, we must be responsible
for implementing the complex features such as transaction handling, scalability,
security, database connectivity and messaging by ourselves. With EJB, the
container provides these services to the EJB so that we can concentrate on
implementing the business logic in the EJB.

Rules for EJB development:

Page 41 of 87
- An EJB is not allowed to use a non-final static field, though using a final static
field is allowed.
- To cope with reality, an EJB is not allowed to produce graphical output because
there may be nowhere to display it.
- For security, an EJB is not allowed to access local file systems.
- An EJB is not allowed to listen or write to a socket.
- An EJB is not allowed to manipulate a thread.
- An EJB is not allowed to load native code.
- An EJB is not allowed to pass “this” as a method’s argument or return “this”.

EJB Container:
- Responsible for creating EJB objects when necessary.
- Determines how an EJB is used to serve the requests from clients.
- Intercepts the invocation of EJBs’ business methods from a client, allowing it to
provide additional services such as transaction and security.
- Manages resources used by EJBs.

Mechanisms for EJBs and the EJB container to interact:


- Callback methods: EJBs implement callback methods (e.g. @PreDestroy) that
would be invoked during its life cycles (activated, passivated or removed)
- A reference to the container: Through objects that implement the EJBContext
interface, which represent a reference to the EJB container.
- Java Naming and Directory Interface (JNDI): similar in nature to a RMI registry,
provides naming services to EJB for locating other resources including other
EJBs and data sources. JNDI services are provided by a Java EE server.

Benefits of using EJB:


- With EJB providing system-level services, programmers can focus on
developing business logic of enterprise applications.
- Programmers can focus on developing the UI of the client as business logic is
implemented in the EJB. (Thin client instead of Smart client)
- EJBs can be reused in building new applications.

Types of EJBs in EJB 3.0 (Java EE 5.0):


- Session beans: used to perform a task in the server for its client. You may think
of session bean as an enhanced RMI remote object located in a Java EE
server.
- Message-driven beans: provides asynchronous processing of client request.

Page 42 of 87
* Entity bean (in earlier version of EJB) is replaced by JPA entity in EJB 3.0

Structure of a Java EE application:


- A Java EE application is packaged in an “EAR” file for deployment to the server.
An “EAR” file is just a “JAR” file that has .ear extension. It contains a number of
deployment descriptors and Java EE modules as shown below.

Deployment descriptor: a XML file that specifies the deployment configuration of


the application.
Java EE modules:
- EJB module: contains EJBs (session beans and message driven beans), which
is packaged as .JAR
- Web module: contains Web components such as servlets, JSPs and other
resources such as HTML and image files. A Web module is packaged as .WAR
- Application client module: consists of client programs that access Java EE
server components. It is packaged as .JAR
- Resource adapter module: integrate legacy system, out of our scope.

Session beans:
- A session bean consists of a bean interface and an implementation class. A
simple session bean can be constructed in a way similar to the construction of a
RMI remote object. Annotations or XML are used in the bean interface and
implementation class to specify the EJB nature and settings.

javax.ejb.* Annotations:

Page 43 of 87
- Bean interface: [@Remote vs @Local]
- Implementation class: [@Stateless vs @Stateful] a stateful session bean
guarantees that the state information (instance variables) of the bean through
one referenced is not affected by the invocations of the bean in other
references. It is not guaranteed in a stateless session bean. (See pg. 26 table)
- Application client: [@EJB] the variables annotated with @EJB are
automatically initialized by the application client container

Dependency injection:
- The mechanism of examining annotations and injecting references by Java EE
containers in runtime is called dependency injection.
- The EJB specification mandates dependency injection in static variables in
application clients, and instance variables in other Java EE components
because application client programs are executed in their static main methods,
while instances of Java EE components are constructed for execution.
- GlassFish V2 server supports dependency injection in EJBs, servlets, and
application clients running inside the container, but does not support JSPs.
- Besides dependency injection, a Java EE program can retrieve the reference of
an EJB by using JNDI. Actually, with dependency injection, Java EE containers
transparently perform the JNDI naming registrations for EJBs and lookups for
EJB clients. In case you want to customize the names that are registered to
JNDI or dependency injection is not available (like JSPs), your EJBs and client
programs can work with the JNDI service directly.
Java Naming and Directory Interface (JNDI):
- a naming service provided by Java EE servers
- application clients and EJBs can use JNDI to look up Java EE components like
EJBs and other resources
- To bind a customized name to a session bean in the JNDI, use the mappedName
element of the @Stateless annotation. To look up with customized name, the
application client uses the mappedName element of the @EJB annotation. E.g.
- Implementation class:
- @Stateless(mappedName = “hiBean”)
- public class HelloBean implements HelloRemote { … }
- Application client:
- Public class HelloClient {
- @EJB(mappedName = “hiBean”)
- private static HelloRemote hello;
- …

Page 44 of 87
- }
javax.naming.InitialContext class:
- Similar to an RMI client looking up a RMI remote object.
- Used to look up EJB by the JNDI service when dependency injection is not
applicable (such as in JSPs).
- InitialContext ic = new InitialContext();
- HelloRemote hello = (HelloRemote) ic.lookup(“hiBean”);
- System.out.println(hello.greet());

Life cycle of a stateless session bean:

- A stateless bean either does not exist or is in the ready state. When a stateless
bean is instantiated by the container, the container performs dependency
injection and invokes any method annotated by @javax.annotation.PostConstruct
before going to the ready state.
- Depending on implementation, the instantiation strategy (when to instantiate)
may differ. The container may instantiate the instances of the bean during
deployment. Sometimes, a pool of beans may be instantiated to improve
performance. However, these are not specified in the EJB specification.
- The container may decide to unload a stateless session bean when the
container is low in resources or the bean has not been requested for some
time. Any method marked by @javax.annotation.PreDestroy is invoked before that.

Stateful session bean:


- the retention of state information (instance variables in the bean) is guaranteed
in each reference of the session bean.
- occupies more resources than stateless session bean in order to maintain state

Page 45 of 87
- There is no pooling for stateful session bean in the EJB container (Not created
in deployment). Upon a client request, the container instantiates a bean
instance, invokes any method marked with @PostConstruct, and puts it in the
ready state.
- When a bean is not invoked for a specific length of time or the client calls a
bean method marked with @javax.ejb.Remove, the container will invoke any
method marked with @PreDestroy and unload the bean.
- When the EJB container is running low in resources, it may passivate a ready
stateful bean instance, calls methods that are marked with @javax.ejb.PrePassivate
and put it in the passive state. It is done by writing the bean state to secondary
storage and removing the instance from the main memory.
- If a client invokes a bean that is in the passive state, the container activates the
bean by loading the state from secondary storage to main memory. After
activation, any method marked with @java.ejb.PostActivate is invoked.
- If a passive bean timeouts (server setting), it is removed by the container.
Remote vs Local interface:
- @Remote: allows remote clients, such as application clients that are outside
the EJB container, to access the bean (using RMI).
- @Local: allows local clients, such as Web components and other EJBs that are
in the same enterprise application (EAR) as that bean, to access the bean
without the overhead of RMI.
- A session bean, whether stateful or stateless, may have either a remote, a local
or both interfaces.

Page 46 of 87
Comparison between basic Session bean and basic RMI: (ref: Self Test 8.2 Q4)
RMI Session bean
Interface - extends java.rmi.Remote - annotated by
- each method is declared to @javax.ejb.Remote /
@javax.ejb.Local
throw RemoteException
Implementation - extends java.rmi.server. - annotated by
class UnicastRemoteObject @javax.ejb.Stateless /
- has a default constructor @javax.ejb.Stateful
that is declared to throw
RemoteException
Server program - the server creates a remote - no server program is
object and binds it to a RMI required
registry
Client program - looks up the remote object - Either uses dependency
in a RMI registry to obtain a injection by declaring a static
reference variable annotated by
@javax.ejb.EJB
- Or lookup by using JNDI

Problem of session beans:


- tight coupling between client and the EJB.
- client must wait for the return of EJB method before it can proceed, which is
unacceptable for some tasks.

Java Messaging Service (JMS):


- a loosely-coupled messaging mechanism provided by the Java EE platform.
- Programs transmit data to each other by sending and receiving messages to
and from a messaging server. Unlike RMI, this type of communication is
asynchronous. The messaging server provides the storage to hold the
messages and guarantees the reliability of message delivery.
The 2 messaging styles (also called messaging domains) in JMS:
- Point-to-point messaging style: like sending email to a recipient. The sender
sends a msg to a msg queue, and the msg is later retrieved by one receiver,
which acknowledges the messaging server upon processing of the message.
- Subscribe-publish messaging style: messages are associated to a topic in the
server. The receiver subscribes to a topic and listens for messages. When a
message is sent to the topic, the server delivers it to all subscribers of the topic.
* In JMS terminology, queues and topics are known as destinations of
messages.

The JMS API:

Page 47 of 87
- javax.jms.ConnectionFactory interface: used for creating JMS connections
- javax.jms.Connection interface: represents a client’s connection to the JMS server.
A JMS program must call the start() method before receiving JMS messages.
- javax.jms.Session interface: represents a JMS session in which JMS applications
sends and receives messages.
- javax.jms.MessageProducer interface: the sender, which sends messages to a JMS
destination using the send(Message message) method.
- javax.jms.MessageConsumer interface: the receiver, which receives messages from
a JMS destination using the Message receive() method.
- javax.jms.Destination interface: represents a JMS destination.
- javax.jms.Queue & javax.jms.Topic interfaces: sub-interfaces of javax.jms.Destination.
- javax.jms.Message interface: represents a JMS message.
- javax.jms.TextMessage & javax.jms.ObjectMessage interfaces: sub-interfaces of
Message
* You must obtain the ConnectionFactory, Queue and Topic from the message server
before you can use them in your application. To do so, use dependency injection
with the @javax.annotation.Resource annotation or use JNDI to look them up.
JMS sample code:
public class Sender {
@Resource(mappedName=”jms/mt811factory”) The connection factory with JNDI
name “jms/mt811factory” and the
private static ConnectionFactory factory; queue “jms/mt811queue” are set up
@Resource(mappedName=”jms/mt811queue”) in the Java EE server

private static Queue queue;

public static void main(…) throws JMSException {


Do not require transaction support

Page 48 of 87
Connection conn = factory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
TextMessage msg = session.createTextMessage(“testing”);
producer.send(msg);
producer.close();
session.close();
conn.close();
}
}

public class Receiver {


@Resource(mappedName=”jms/mt811factory”)
private static ConnectionFactory factory;
@Resource(mappedName=”jms/mt811queue”)
private static Queue queue;
public static void main(…) throws JMSException {
Connection conn = factory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(queue);
conn.start();
TextMessage msg = (TextMessage) consumer.receive(1000);
if (msg != null) // null in case no message is received within 1000ms
System.out.println(“Message: “ + msg.getText());
consumer.close();
session.close();
conn.close();
}
}

Message-driven beans (MDB):


- Adopts the message-oriented approach. The client application sends request
as messages to a message queue (using JMS) that will be consumed by an
MDB.
- Provides asynchronous processing for its clients. Designed to solve the
synchronous problem of session beans.
- An MDB, when deployed to an EJB container, is targeted for a particular JMS
destination. When a JMS message arrives at the destination, the EJB container
invokes the MDB to receive and handle the message.
- Since an MDB is not directly invoked by the client application, an MDB has no
remote or local interface. It has only a bean class that implements the
javax.jms.MessageListener interface and supplies an onMessage() method for

Page 49 of 87
handling messages.
- The @javax.ejb.MessageDriven annotation is used to mark a class as MDB and the
mappedName element is used to specify the JNDI name of the destination (queue
or topic) associated with the MDB. The following is an example:
-
@MessageDriven(mappedName=“jms/mt811queue”)
public class MDBean implements MessageListener {
public void onMessage(Message message) {
try {
TextMessage msg = (TextMessage) message;
System.out.println(msg.getText());
} catch (JMSException ex) {
}
}
}

Life cycle of MDB:

- Very similar to the life cycle of stateless session bean


- The EJB container may hold a pool of ready MDBs for better performance

Use of Java Persistence API (JPA) in EJB:


- Be recall that entity objects are connected to database records at runtime via a
persistent context. Persistent contexts are manipulated by entity managers.

The 2 types of entity managers, classified by how the managers are obtained:
- Application-managed entity managers: created in application code by using the
EntityManagerFactory interface. All entity managers used in Java SE applications
are of this type.
- Container-managed entity managers: provided by Java EE containers by
dependency injection with the @javax.persistence.PersistenceContext annotation, or
by using JNDI lookup. Although Java EE components, such as EJBs, may use

Page 50 of 87
either type of managers, it is recommended to use this type because of the
container services such as transaction management.

The 2 types of container-managed persistence contexts depending on the scopes


of the contexts: (*by default, EJB clients’ invocations of beans’ methods are
executed in transactions provided by the EJB container)
- Container-managed transaction-scoped persistence contexts: exists within the
lifetime of a single transaction. When the transaction ends, it is closed and all
entities in the persistence context are detached.
- Container-managed extended persistence contexts: exists across multiple
transactions. Entities are detached from the persistence context when a
transaction ends and are re-attached when the next transaction begins.
Extended contexts are only used in stateful session beans to support entity
persistence across method invocations of the beans. All application-managed
persistence context are extended in nature.

JPA in enterprise application example:


- Typically, we have a (stateless or stateful) session bean (EJB) that makes use
of an entity class (JPA) for database persistence.
- Stateless session bean example:
@Stateless
The “unitName” element specifies
public class TellerBean implements TellerRemote { the persistence unit that contains the
data source connection info. No
@PersistenceContext (unitName=“bankpu”) “type” element is specified implies
private EntityManager manager; transaction-scope context by default.

public void createAccount(int id, String holder, double balance) {

Page 51 of 87
Account ac = new Account(); // the entity class
ac.setAccountID(id);
ac.setHolder(holder);
ac.setBalance(balance);
manager.persist(ac);
}
}
- Stateful session bean example:
@Stateful
public class ATMBean implements ATMRemote {
@PersistenceContext (unitName=”bankpu”, type=PersistenceContextType.EXTENDED)
private EntityManager manager;
private Account account = null;
public void transfer(int toId, double amount) {
… calculate the new balance for source and target account
account.setBalance(sourceBalance);
Account toAccount = manager.find(Account.class, toId);
toAccount.setBalance(targetBalance);
}
}

Transactions in EJBs:
- By default, EJB clients’ invocations of business methods are executed in
transactions provided by the EJB container.
- A transaction is a sequence of changes to a database that must be successfully
accomplished as a whole.

The 2 types of transaction management in EJBs:


- Container-managed transaction (CMT): the container is responsible for
managing transactions. There is no code in the bean to perform any
transactional function. CMT is available to both session beans and MDBs. It is
the default for all EJBs, and the use of CMT is recommended over BMT
whenever possible because the main reason for using EJBs is to make use of
the services provided by the container.
- Bean-managed transaction (BMT): the developer is responsible for
implementing transactional code in a bean. To use BMT, you need to
understand Java Transaction API (JTA), which is out of scope of this course.

Page 52 of 87
Transaction attributes in CMT:
- Used to specify the scope of transaction in bean’s methods by marking them
with @javax.ejb.TransactionAttribute with a values of javax.ejb.TransactionAttributeType:

Attribute Values *Client Transaction EJB Transaction Remarks


REQUIRED (the None New_Tx The method must be involved in a Tx. The
default value)Client_Tx Client_Tx EJB container starts a new Tx if necessary.
REQUIRED_NEW None New_Tx The method always starts a new Tx to
Client_Tx New_Tx execute the bean method.
MANDATORY None Error A transaction must be started before the
Client_Tx Client_Tx method is invoked.
SUPPORTS None None The method will be included in a transaction
Client_Tx Client_Tx if it is invoked within a transaction.
NOT_SUPPORTED None None Any transaction will be suspended & resume
Client_Tx None before & after the method is invoked.
NEVER None None The method should never be involved in a
Client_Tx Error transaction.
* The client can be another EJB

@Stateful
@TransactionAttribute(TransactionAttributeType.SUPPORTS) // applies to all methods in class
public class ATMBean implements ATMRemote {

@TransactionAttribute(TransactionAttributeType.REQUIRED) // applies to this method only
public void transfer() { … }
}

2 types of Exceptions in EJB:


- System exceptions: RuntimeException & its subclasses such as EJBException
- Application exceptions: exceptions that are not RuntimeException

A system exception thrown in an EJB business method generates a rollback in the


transaction. An application exception does not rollback the transaction.

Unit 09 – Processing XML with Java


XML is not an extension of HTML. It is a subset of SGML.

Usages of XML: data exchange in e-commerce & data storage

Benefits of XML:
- XML is structured, suitable for hierarchical data
- XML is text-based and so, platform independent & language independent
- XML is an open standard

Page 53 of 87
- XML is totally extensible with user defined tags
- XML enables interoperability
- XML is supported by open parsing technologies such as DOM and SAX

Rules for well-formed (not necessarily equals to valid) XML:


- The optional header <?xml version=”1.0”?>, if exists, must be in the first line
- XML comments: <!-- xml comment -->
- Single rooted
- Each opening tag must have a matching closing tag
- Attributes values must be quoted with ‘ or “
- Tags must be nested properly
- Element names and attribute names are case-sensitive
- < > & are escaped by &lt; &gt; &amp; respectively

XML namespaces:
- Used to avoid naming conflicts
- <c:customer customerid=”1” xmlns:c=”http://example.com/xml/customer”>\
- http://example.com/xml/customer is the namespace URI and c is the prefix
- Although namespace URIs almost always begins with http://, they are not actual
Web addresses. It is just a plain unique string for identifying groups of related
XML tags.

Why do we need DTD or XSD?


- For data exchange, well-formedness alone is not sufficient. Some structure
must be defined so that both parties know what to read.

Document Type Definition (DTD):


- Part of the XML 1.0 specification
- It defines or constrains the structure of an XML document
- Can be written internally in the XML
- <!DOCTYPE customer [
- <!ELEMENT customer (name, telephone)>
- <!ELEMENT name (#PCDATA)>
- <!ELEMENT telephone (#PCDATA)>
- <!ATTLIST customer customerid CDATA #REQUIRED>
- ]>
- <customer customerid = “1”>
- <name>Peter Chan</name>

Page 54 of 87
- <telephone>12345678</telephone>
- </customer>
- Or typically written as external .dtd file and have the XML links to it. The DTD
part is the same in this case. The following line is used to link a XML to DTD
- <!DOCTYPE customer SYSTEM “customer.dtd”>

XML Schema (XSD):


- Replace DTD, designed to overcome the shortcomings of DTD (non-XML, no
data type support)
- More flexible and powerful. E.g. Data type like integer is supported
- XML based, so that it can be processed by XML tools
- Defined according to the namespace URI http://www.w3.org/2001/XMLSchema
- <xsd:schema xmlns:xsd=” http://www.w3.org/2001/XMLSchema”>
- <xsd:element name=”customer”>
- <xsd:complexType> An XML element’s type is complex if it has attributes
and/or contains other elements in its content.
- <xsd:sequence>
- <xsd:element name=”name” type=”xsd:string” />
- <xsd:element name=”telephone” type=”xsd:string” />
- </xsd:sequence>
- <xsd:attribute name=”customerid” type=”xsd:int” use=”required” />
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
Data types in XSD:
- xsd:string, xsd:integer, xsd:int, xsd:long, xsd:decimal, xsd:float, xsd:double,
xsd:date, xsd:time, xsd:boolean

Linking XSD to XML:


- By specifying the noNamespaceSchemaLocation attribute (which is defined in the
http://www.w3.org/2001/XMLSchema-instance namespace URI) in the root element
- <customer customerid=”1” xsi:noNamespaceSchemaLocation=”customer.xsd”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” >

Mechanisms for event-based parsing:


- Push parsing: the parser pushes events to your application code (e.g. SAX)
- Pull parsing: your application pulls XML events from the parser (e.g. StAX)

Simple API for XML (SAX):


- Uses event-based push parsing mechanism: SAX parser reads an XML

Page 55 of 87
document sequentially from beginning to end and generates an event every
time it encounters a particular XML construct
- To create & set up SAX parsers, we use “Java API for XML Processing” (JAXP)
- SAX API: org.xml.sax package & its sub-packages
- JAXP API: javax.xml.parsers package

javax.xml.parsers.SAXParserFactory class:
- An abstract class for creating and setting up SAXParsers
- To obtain the factory object, use SAXParserFactory.newInstance()
- To obtain a SAXParser object, use factory.newSAXParser()
- setValidating(Boolean b) / isValidating(): whether the parser performs DTD validation
- setSchema(Schema s) / getSchema(): the schema to be used for validation

javax.xml.parsers.SAXParser class:
- overloaded parse() methods for XML parsing

org.xml.sax.helpers.DefaultHandler class:
- void startDocument() / void endDocument()
- void startElement(String uri, String localName, String qName, Attributes attributes) where uri
is the namespace URI, localName is the tag name without namespace prefix,
qName is the qualified tag name with namespace prefix. Attributes is described
next.

Page 56 of 87
- void endElement(String uri, String localName, String qName)
- where ch[start, length] contains data
void characters(char[] ch, int start, int length)
- void warning(SAXParseException e) // for a parser warning
- void error(SAXParseException e) // for recoverable parser error
- void fatalError(SAXParseException e) // for fatal XML parsing error
* invisible characters such as white spaces (‘ ’) and end of line (‘\n’) are also
captured in the characters() method by the SAX parser.

org.xml.sax.Attributes interface:
- int getLength() // returns the number of attributes in the list
- String getLocalName(int index) // tag name without namespace prefix
- String getQName(int index) // qualified tag name with namespace prefix
- String getURI(int index) // namespace URI of attribute at index
- String getValue(int index) // get attribute value at index
- String getValue(String qName) // get attribute value by qualified tag name
- String getValue(String uri, String localName) // get value by URI and local name

Characteristics of SAX:
Advantages Disadvantages
- Fast and consumes small amount of - Cannot modify or generate XML
memory as it reads XML sequentially - Not suitable for processing XML
- Good for state-independent XML content with inter-related XML
processing elements (i.e. state dependent)
- Only support sequential access
Streaming API for XML (StAX):
- A more recent event-based parsing API than SAX
- Uses event-based pull parsing mechanism: Advances the parser to pull events
that correspond to XML constructs being parsed.
- Supports both reading and writing XML.
- The pulling nature of StAX alleviates the need to write handler classes and
maintain parsing states across callback methods. Therefore, it is generally
easier to write a program using StAX than SAX.
- Can be accessed by 2 sets of APIs: Cursor API and Iterator API

Cursor API vs Iterator API of StAX for reading XML:


- The difference lies only in the style for accessing the event details

Page 57 of 87
Cursor API Iterator API
- More simple, easier to use, faster - More flexible, extensible and OO but
and requires less memory more complex than cursor API

javax.xml.stream.XMLInputFactory class:
- Used to create XML readers (stream reader or event reader)
- To obtain the factory object, use XMLInputFactory.newInstance()
- To obtain a stream reader (cursor API: XMLStreamReader), use
factory.createXMLStreamReader(InputStream is) or createXMLStreamReader(Reader r)
- To obtain an event reader (iterator API: XMLEventReader), use
factory.createXMLEventReader(InputStream is), createXMLEventReader(Reader r) or
createXMLEventReader(XMLStreamReader r)
javax.xml.stream.XMLStreamConstants interface:
- Defines constants (i.e. static int) that represent different types of events in StAX
- Examples: START_DOCUMENT, START_ELEMENT, END_ELEMENT, CHARACTERS

javax.xml.stream.XMLStreamReader interface (cursor API):


- Supports sequential reading of XML
- boolean hasNext() // checks if there are more parsing events
- int next() // advances to the next event and returns its event type
- int getEventType() // returns the type of current event (as XMLStreamConstants)
- boolean isStartElement(), isEndElement(), isCharacters()
- QName getName() // returns the qualified name of the current START_ELEMENT or
END_ELEMENT (note that only these elements have name)
- QName getAttributeName(int index), String getAttributeValue(int index)

Page 58 of 87
- String getText()// returns the string of a CHARACTER event
- close() // releases resources and closes reader
- Cursor is positioned at the START_DOCUMENT event initially

javax.xml.stream.XMLEventReader interface (iterator API):


- Supports sequential reading of XML
- Events are represented by the XMLEvent interface and its sub-interfaces
- boolean hasNext() // checks if there are more parsing events
- XMLEvent nextEvent() // advances to and returns the next event
- XMLEvent peek() // returns the next parsing event without advancing the parser
- close() // releases resources and closes reader
- Unlike cursor API, initial reading position is before the START_DOCUMENT event

javax.xml.stream.events.XMLEvent interface:
- int getEventType() // returns the type of current event (as XMLStreamConstants)
- StartElement asStartElement(), EndElement asEndElement(), Characters asCharacters() -
returns this event as StartElement, EndElement or Characters; an exception is
resulted if the casting fails
- boolean isStartElement(), isEndElement(), isAttribute(), isCharacters(), isStartDocument(),
isEndDocument() testifies the actual type of this event

Sub-interfaces of XMLEvent: (all in javax.xml.stream.events package)


StartDocument and EndDocument
StartElement: QName getName(), Iterator getAttributes()
EndElement: QName getName()
Characters: String getData()
Attribute: QName getName(), String getValue()
Cursor API vs Iterator API of StAX for writing XML:
- Support writing XML constructs to an XML document sequentially

Page 59 of 87
- To obtain the factory object, use XMLOutputFactory.newInstance()
- To obtain a stream writer (cursor API: XMLStreamWriter), use
factory.createXMLStreamWriter(OutputStream os) or createXMLStreamWriter(Writer w). The
factory object can also be used to create XMLEventWriter object.
- writer.writeStartDocument(), writeEndDocument(), writeStartElement(String qName),
writeEndElement(), writeAttribute(String qName, String value), writeCharacters(String data)
where the writeStartDocument() writes the <?xml … ?> processing instruction and
writeEndDocument() inserts any necessary closing tags to be well-formed
- flush() // flushes the buffered data to the output
- StAX iterator API for writing is not covered in course material

Characteristics of StAX:
Advantages Disadvantages
- Can modify or generate XML - Slightly slower and use more
- Easier to program than SAX as there memory than SAX parsers
is no need to write the handler class - Only support sequential access
- The pulling nature of StAX makes it
better for inter-related XML elements
(i.e. state dependent) processing
because we can read XML actively
(instead of passively in case of SAX)

Document Object Model (DOM):

Page 60 of 87
- A standard for representing XML doc. across different programming languages.
- Uses tree-based XML parsing. An XML document is treated as a tree.
- Attribute, whitespaces are also stored as tree node.
- The “cusomterid” attribute node is not a child of its associated “customer” node
- Other tree-based XML parsing API: JDOM, dom4j
- To create DOM builders, we use “Java API for XML Processing” (JAXP)
- DOM API: org.w3c.dom package & its sub-packages
- JAXP API: javax.xml.parsers package

javax.xml.parsers.DocumentBuilderFactory class: (similar to SAXParserFactory)

Page 61 of 87
- An abstract class for creating document builders
- To obtain the factory object, use DocumentBuilderFactory.newInstance()
- To obtain a document builder, use factory.newDocumentBuilder()
- setValidating(Boolean b) / isValidating(): whether the parser performs DTD validation
- setSchema(Schema s) / getSchema(): the schema to be used for validation

javax.xml.parsers.DocumentBuilder class:
- overloaded parse() methods for parsing XML as a Document tree object
- Document newDocument() // returns a new empty DOM tree

The org.w3c.dom package:


- The DOM API for accessing and manipulating the document tree

org.w3c.dom.Node interface:
- Represents a node (of any node type) in the document tree.
- short getNodeType() // returns Node constants like DOCUMENT_NODE, TEXT_NODE …
- NamedNodeMap getAttributes() // NamedNodeMap is a map of name-Node pairs
- boolean hasAttributes()
- NodeList getChildNodes() // NodeList is an ordered list of Node object
- Node getParentNode(), getFirstChild(), getLastChild(), getPreviousSibling(), getNextSibling()
- String getNodeName() // returns tag name for element, “#text” for text node
- getNodeValue() // returns null on an element node, text data on a text node
- getTextContent() // returns the text data associated with an element or text node
- void setNodeValue(String value), setTextContent(String text)
- Node appendChild(Node newChild), insertBefore(Node newChild, Node refChild),
remove(Node oldChild), replaceChild(Node newChild, Node oldChild), cloneNode(boolean
deep)

Page 62 of 87
org.w3c.dom.Document interface:
- represents the document tree of an XML document
- the parse() method of DocumentBuilder object returns an object of this type
- Element getDocumentElement() // returns the root element
- NodeList getElementsByTagName(String tag) // search in the whole document
- Element createElement(String tag) // creates an element node
- Attr createAttribute(String name) // creates an attribute node
- Text createTextNode(String text) // creates a text node

org.w3c.dom.Element interface:
- represents an XML element (tag)
- NodeList getElementsByTagName(String tag) // search the tag name under this
element
- String getTagName() // returns the tag name of the element
- boolean has Attribute(String name) // tests if this element has the specified attribute
- String getAttribute(String name), Attr getAttributeNode(String name)
- void setAttribute(String name, String value), Attr setAttributeNode(Attr attr)
- void removeAttribute(String name), Attr removeAttributeNode(Attr attr)

org.w3c.dom.Attr interface:
- represents an attribute (name-value pair) of an XML element
- String getValue(), void setValue(String value)
- String getName() // returns the name of the attribute
- Element getOwnerElement() // returns the Element that owns this attribute

org.w3c.dom.CharacterData interface:
- represents a node that contains text data
- Text and Comment are sub-interfaces of CharacterData. Text represents the text
content of an element or attribute node. Comment represents XML comment.
- String getData(), void setData(String data)
- int getLength() // returns the length of the text data

Characteristics of DOM:
Advantages Disadvantages
- Can modify or generate XML - Slower and use more memory (reads
- Higher level API that SAX and StAX entire tree) than SAX & StAX parsers
such that it is easier to program - Not suitable for reading just a small
- Random access is supported portion of XML from a large XML file

Page 63 of 87
Java Architecture for XML Binding (JAXB)
- JAXB tools create document-specific Java classes that map between XML data
and Java objects.
- In JAXB, the process of converting XML data into Java objects is called
“unmarshalling” (called “parsing” in DOM), and the reverse is called
“marshalling” (called “serializing” in DOM).

- Generating XML schema from existing Java classes requires the use of JAXB
annotations, which are out of the scope of our course. To generate Java
classes from existing XML schemas, we use the JAXB complier (“xjc” command
in JDK).
- One of the JAXB compiler’s jobs is the conversion of schema data types into
Java data types. The table below shows the conversions:

Page 64 of 87
javax.xml.bind.JAXBContext class:
- Provides factory methods for creating marshallers and unmarshallers.
- To obtain the factory object, use JAXBContext.newInstance(String package) where
package specifies the package of the generated JAXB-compliant classes.
- To obtain a unmarshaller, use factory.createUnmarshaller()
- To obtain a marshaller, use factory.createMarshaller()

javax.xml.bind.Unmarshaller interface:
- represents a unmarshaller for converting an XML document to Java object
- overloaded Object unmarshal() methods for deserialization of XML

javax.xml.bind.Marshaller interface:
- represents a marshaller for converting a Java object into an XML document
- overloaded void marshal() methods for serialization of Java object into XML

Characteristics of JAXB:
Advantages Disadvantages
- It provides a Java programmers with - XML schemas are required in JAXB
a high-level, familiar, convenient and - JAXB is slower and requires more
transparent mean of manipulating
memory than SAX, StAX and DOM
XML data

Unit 10 – Java for Wireless Devices


What is Java ME?

Page 65 of 87
- With limited amount of memory, low-end user interfaces and relatively slow
CPUs in some target platforms, every aspect of Java, including the virtual
machine and the language itself, had to be reconsidered. Java ME is a
complete redesign of the Java technology so that it can fit into the restricted
environment.
- Java ME introduced a layered concept. Different layers called “configuration”
and “profile” provide the functionalities of Java, with profile being implemented
on top of configuration. Different configurations and profiles can be defined for
devices with different hardware capabilities.
- For mobile devices, the key configuration is the Connected Limited Device
Configuration (CLDC) and the key profile is the Mobile Information Device
Profile (MIDP). More capable devices use the Connected Device Configuration
(CDC) and its associated profiles.
- Apart from Java, you may also use JavaFX to program the Java ME platform. It
is particular suitable for developing user interfaces and media-rich applications.
Why use Java for wireless development?
- Java is object-oriented.
- Java is secure. Java ME provides a sandbox environment for applications.
- Java is portable. Java ME applications are portable within the constraints of the
supported configuration and profiles.
- Java enjoys wide manufacturer support.
- Either Java or JavaFX can be used to program the Java ME platform.

Target Devices:
- High-end devices: have 2 to 4 MB of memory, persistent data storage and
network connection. Possibly with reasonable user interface. E.g. set-top boxes
- Low-end devices: as little as 128kB of memory, intermittent network connection
and a very limited user interface. Often powered by battery so power
consumption is a key concern. E.g. mobile phones and PDAs.

Why does Java ME need the layered architecture?


- The Java ME platform has to cover a wide range of devices, with different
amounts of memory (10kB to 10MB) and CPUs (16 to 64 bits) and new devices.
The variability of Java ME devices is much larger than the Java SE or Java EE
platform. To cope with such a large variability, Java ME adopted a layered
structure on top of the device operation system. It enables the creation of
customized versions of Java for different device categories.

Page 66 of 87
Layers in the Java ME architecture:

- Configuration: it defines a wide range of devices with similar memory and


processing power. From a programmer’s point of view, it is a JVM and a set of
class libraries providing the most basic functionalities.
- Profile: based on the configuration, it defines more specific functionalities, with
additional class libraries, for a set of devices within the same configuration.
- Optional packages: it optionally provides additional functionalities that are
technology-specific to some mobile applications.
JVM in Java ME:
- K virtual machine (KVM): used for low-end devices (CLDC)
- Classic virtual machine (CVM): used for high-end devices. It is the same as the
Java SE virtual machine that is used on a desktop PC. (CDC)

The configuration layer:


- It defines the Java language and virtual machine features (KVM or CVM) and
minimum libraries that a Java ME supported device manufacturer is expected to
provide for all devices of the same class.
- Currently, there are two configurations defined in Java ME. They are CDC and
CLDC. CDC targets high-end devices while CLDC targets the low-end devices.
CDC is designed to be a superset of CLDC to enhance portability. This way, an
application that runs in CLDC can also be run in CDC.

The profile layer:


- A large range of devices is covered by a single configuration. Therefore, profile
is defined to provide specific class libraries for specific application domains.
- Applications are written for a specific profile, as profiles are designed for a
particular configuration. Both profiles and configurations together define a set of
Java classes that can be used by the applications.

Profiles currently available in Java ME:

Page 67 of 87
- Mobile Information Device Profile (MIDP): based on CLDC, it provides a
standard environment for small, resource-limited, wireless-connected devices
like mobile phones and two-way pagers. These devices have small display,
limited input devices, local storage, battery life and CPU power.
- Foundation Profile (FP): based on CDC, support network-enabled high-end
devices with Java SE-based class library, but support for GUI is excluded.
- Personal Basis Profile (PBP): based on FP, this profile adds support for
lightweight GUI components.
- Personal Profile (PP): based on PBP, this profile provides full support of AWT
and applet functionalities.

Optional packages:
- It provides technology-specific APIs to Java ME applications
- Two optional packages available to CDC:
- RMI Optional Package: supports RMI for networked devices
- JDBC Optional Package: provides JDBC API for database connectivity
Can a Java ME application run in Java SE platform?
- No. While the Java SE API and the Java ME API have some overlap, each of
them is not a subset of the other. For example, the Java ME libraries include a
subset of the Java SE classes and some classes (mostly in the profile level)
that are unique to Java ME.

Connected Limited Device Configuration (CLDC):


- It is designed for devices with severe resource limitations such as PDAs.
- Minimum hardware requirement for CLDC: at least 192kB of total memory, a
16-bit or 32-bit processor, low power consumption, intermittent connectivity with
limited bandwidth.

Issues addressed by CLDC:


- Java language and virtual machine features
- Core Java libraries (subset of java.lang and java.util packages)
- Input/output (subset of the java.io package)
- Networking
- Security
- Internationalization
* GUI, event-handling, persistent data writing, life cycle management and
accessing information securely are not addressed in CLDC. These are too device-
specific to be covered in CLDC and should be addressed in profiles or optional

Page 68 of 87
packages.

Libraries in CLDC:
- Subset of Java SE libraries: to reduce learning curve of Java SE programmer.
This includes the majority of classes in the java.lang, java.util and java.io packages.
For the java.io package, significant part of the classes is missing. The
functionalities of the missing part are provided by GCF.
- Generic Connection Framework (GCF): the i/o or networking functionalities in
mobile phone or PDA are very different from those of a typical PC. So, the i/o
and networking libraries in Java SE are not applicable to CLDC devices. GCF
provides the i/o or networking functionalities in CLDC.

Notes on CLDC:
- All primitive types, including floating point numbers, are supported in CLDC 1.1
- The finalize() method is not supported in the CLDC version of java.lang.Object
- The keyword native is not supported. Java Native Interface (JNI) is not
supported in CLDC.
Generic Connection Framework (GCF):
- A set of classes and interfaces in the javax.microedition.io package that replace
most of the java.io and java.net classes defined by Java SE.
- CLDC contributes part of the GCF with generic connection interfaces.

Mobile Information Device Profile (MIDP):


- Based on CLDC, MIDP defines additional classes for devices with a small
display and some form of user input.
- Minimum hardware requirement for MIDP: screen-size of 96 x 54, one or more
user-input (one-handed, two-handed keyboard or touch screen), two-way
wireless network, ability to play tones.

Libraries in MIDP:
- classes from Java SE: java.lang.IllegalStateException, java.util.Timer, java.util.TimerTask
- javax.microedition.io package: extends CLDC to provide specific networking
support such as the HttpConnection class
- javax.microedition.lcdui package: implements user interface for small screens
- javax.microedition.rms package: support for persistent storage
- javax.microedition.media package: support playback and control of sound
- javax.microedition.pki package: support secured connection

Page 69 of 87
MIDlet:
- MIDP defines an application model for the execution of applications. An
application that conforms to the model is called MIDlet. A MIDlet is implemented
as a subclass of the javax.microedition.midlet.MIDlet class.
* A Servlet conforms to the application model of Servlet and an Applet conforms to
the application model of Applet.

MIDlet suite:
- A MIDlet application is packaged as a MIDlet suite for deployment. Each MIDlet
suite consists of two files: Java Application Descriptor (JAD) and Java Archive
(JAR). The JAR file contains class file(s), image and sound file(s).
- For a mobile phone to execute a MIDP application, it needs to download and
install the JAD and JAR files. Java ME provides a mechanism, Over-the-air
provisioning (OTA), for mobile devices to install MIDlet suites over the Internet.
For development, it is usually installed through a cable connection to a desktop
PC to save airtime cost.

Connected Device Configuration:


- Minimum hardware requirement for CDC: at least 4MB of memory for the Java
platform and a 32-bit processor
- Available profiles: FP, PBP and PP
- Foundation Profile: is the most basic profile in CDC. It supplements the CDC
library by providing additional security functionalities. No GUI is supported in
FP.
- Personal Basis Profile: a superset of FP that adds support for lightweight GUI.
- Personal Profile: a superset of PBP that adds full AWT support including applet.

CDC optional packages:


- RMI: provides a subset of RMI functionalities in Java SE
- JDBC: provides a subset of the JDBC 3.0 API
- Advanced Graphics and User Interface (AGUI): provides a modified
implementation of Swing for building application with rich and advanced GUIs
- Web services: provides data access from Java ME clients to Web services

JavaFX Mobile:
- Remember that JavaFX is a Java-based platform for rich Interactive
applications (RIAs) development in desktop, mobile and other consumer
devices.
- JavaFX Mobile is part of the JavaFX platform to support mobile applications.

Page 70 of 87
- JavaFX elements (APIs) are divided into common elements and application-
specific elements. This design maximizes the reuse of common elements and
provides specialized functionalities for different types of applications.

Advantages of using JavaFX Mobile in developing Java ME applications:


- The JavaFX language adopts a declarative syntax, which is good for RIAs
development. Java syntax is not as good for RIAs development.
- The JavaFX platform is a software layer above the JVM, which means that what
you can do with Java ME on the device can also be done in JavaFX application.
- You can take advantage of JavaFX data binding using the “Bind” keyword.

Unit 11 – Developing Java ME applications


Application model of MIDlets:
- Like a Java applet that runs within the browser environment, a MIDlet has to be
executed within the environment provided by the MIDP. 2-way communication
must exist between a MIDlet and the device. E.g. the MIDlet informs the device
to quit as required by user / the device holds the MIDlet during an incoming call.
MIDP defines the application model that governs the interaction between them.

Life cycle management of MIDlets:

Page 71 of 87
- A MIDlet is a class that extends the javax.microedition.midlet.MIDlet class
- A MIDlet can have a constructor, which is the best place for GUI initialization
- The MIDlet class defines 3 abstract life cycle methods: startApp(), pauseApp() and
destroyApp(boolean uncondition), which must be implemented in a MIDlet.
- During the lifetime of a MIDlet, it can be in 1 of 3 states: active, paused, destroyed

At any time, the device may decide to move the


MIDlet into the paused state

- pauseApp() is invoked just before the MIDlet goes to the paused state. Typical
implementation involves releasing unnecessary memory, network connections
and stopping animation to save CPU time. Noted that even in paused state, the
MIDlet can still handle asynchronous events such as a timer event.
- startApp() is invoked just before the MIDlet goes to the active state. Typical
implementation involves acquiring resources such as memory and connections
needed by the MIDlet.
- destroyApp() is invoked just before the destroy of MIDlet. It is used to release
resources used by the MIDlet. However, if the unconditional parameter is false, the
MIDlet can refuse to be destroyed by throwing MIDletStateChangeException. In
case of sudden power loss, the destroyApp() may be skipped. So, do not rely
on it for saving critical data. Once destroyed, a MIDlet cannot re-enter any other
state.
- The MIDP API provides no mechanism to obtain the current state of a MIDlet.
You need to keep track of it by yourself.
- The 3 life cycle methods are invoked by the system. It is also possible for the
MIDlet to change its state by invoking built-in methods of MIDlet class. To inform
the system it wants to enter the active state, call the void resumeRequest() method.
However, whether the MIDlet goes to active state depends on whether the

Page 72 of 87
system honours the request. If so, the host will invoke startApp() before. To
inform the system that it has voluntarily entered the paused state (after
performing tasks similar to pauseApp), call the void notifyPaused() method. In this
case, the system will not invoke pauseApp(). To inform the system that it can be
destroyed (after performing tasks similar to destroyApp), the void notifyDestroyed()
method can be called. In this case, the system will not invoke destroyApp().

GUI programming in MIDlets:


- AWT/Swing are too heavy-weighted for handheld devices. A new family of GUI
classes, defined in the javax.microedition.lcdui package is needed.

abstract class:
javax.microedition.lcdui.Displayable
- A Displayable object is one that can be made visible on the display.
- The Screen & Canvas subclasses provide high and low-level access to the
display
- Low-level programming is more efficient but difficult to write and less portable.

class:
javax.microedition.lcdui.Display
- The manager of the display hardware and input device on the host.
- It is used to control which Displayable object is currently visible (one at any time).
- No matter how many MIDlets exists, there is only one instance of Display object.
- To obtain the Display object, Display.getDisplay(this) where this refers to the MIDlet.
- To display next Displayable object, void display.setCurrent(Displayable next)
- To display an Alert object and then next Displayable object after the alert closes,
void display.setCurrent(Alert alert, Displayable next)
- To get the current Displayable object, Displayable getCurrent()
- Note that setCurrent() might not take effect immediately. It is up to the host to
determine the appropriate moment. In any case, the method returns
immediately while the device deals with the effect of setting a Displayable

Page 73 of 87
High-level GUI classes:
- The Screen abstract class is the superclass of all other high-level GUI classes
- There are 4 direct subclasses: TextBox, List, Alert and Form

javax.microedition.lcdui.TextBox class:
- Typically used for entering username, password or email address
- To create a new TextBox, TextBox(String title, String text, int maxSize, int constraints),
where constraints limits what the user can enter (enum: TextField.ANY, EMAILADDR,
NUMERIC, PHONENUMBER, URL, PASSWORD). PASSWORD can be combined with
another constant using “bitwise or” (e.g. TextField.ANY | TextField.PASSWORD)
- String getString(), void setString(String text)
- int size() // get the number of characters of the string in the TextBox

javax.microedition.lcdui.Alert class:
- Can be modal (alert.setTimeout(Alert.FOREVER)) or timed (alert.setTimeout(1000))
- To create an Alert, Alert(String title) or Alert(String title, String alertText, Image alertImage,
AlertType alertType) where the AlertType parameter can be AlertType.ALARM,
CONFIRMATION, ERROR, INFO or WARNING.
- int getTimeout(), void setTimeout(int ms), int getDefaultTimeout()

javax.microedition.lcdui.List class:
- Presents a number of choices to the user
- 3 types of list: Choice.EXCLUSIVE (single selection that looks like radio buttons),
IMPLICIT (single selection without the radio buttons) and MULTIPLE (checkboxes).
- List(String title, int listType), List(String title, int listType, String[] choices, Image[] images)
- int getSelectedIndex() // returns the index of the selected element in EXCLUSIVE
or IMPLICIT list (zero-based) and -1 for MULTIPLE list
- boolean isSelected(int index), int size()

Displaying screen with several controls:


- The List, TextBox and Alert classes are designed to occupy the whole screen. So,
you cannot mix them together in a screen. In this case, Form class is used.
- A form is a container for other GUI classes (it cannot contain Displayable objects).
Three groups of classes can be used: String, Image and Item:

Page 74 of 87
- The String is java.lang.String. All other classes are in javax.microedition.lcdui
- An Image can be contained in a Form (high-level) or drawn on a Canvas (low-
level)
- The Item class is abstract
- A StringItem has both a label & textual content. Its appearance can be
customized
- An ImageItem supports alternative text in case the Image cannot be displayed
(e.g. when the image exceeds the capacity of the device’s display)
- A TextField has both a label and editable textual content. API is similar to TextBox.
- A DateField supports the input of date/time: DateField.DATE, DATE_TIME, TIME.
- A ChoiceGroup represents a group of elements for selection. API is similar to List.
- A Guage represents a slide bar that is typically used to control sound volume.

javax.microedition.lcdui.Form class:
- To create a Form, Form(String title), Form(String title, Item[] items)
- int append(Item item), append(String str), append(Image img)
- void insert(int index, Item item) // inserts an item into the form at specified index
- void delete(int index), void deleteAll()
- Item get(int index), void set(int index, Item item), int size()
Low-level GUI classes:
- The Canvas class provides low-level access to the display of the device.
- You can draw graphics primitives, such as lines and shapes, using Canvas.
- To use Canvas, you create a subclass of Canvas and override paint(Graphics g). You
draw in the paint method using the javax.microedition.lcdui.Graphics object.
- Since Canvas is a subclass of Displayable, it can be displayed on screen.

javax.microedition.lcdui.Canvas abstract class:


- abstract void paint(Graphics g) // renders the Canvas
- void repaint() // requests a repaint for the Canvas
- int getWidth(), int getHeight()

Page 75 of 87
class:
javax.microedition.lcdui.Graphics
- It is similar to its counterpart in Swing. It provides methods for drawing shapes.
- void drawLine(int x1, int y1, int x2, int y2)
- void drawArc / fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) // also used
for drawing circles or ellipses
- void drawRect / fillRect(int x, int y, int width, int height)
- void drawRoundRect / fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
- void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
- void drawImage(Image img, int x, int y, int anchor)
- void drawString(String str, int x, int y, int anchor)
- int getColor(), int getRedComponent(), int getGreenComponent(), int getBlueComponent()
- void setColor(int RGB), void setColor(int red, int green, int blue)
- Font getFont(), void setFont(Font font)

High-level event handling:


- Applicable to all Displayable object (including Canvas)
- Similar to event handling of AWT and Swing in that there are event sources and
event listeners.
- In MIDP, there are 2 types of event listeners: CommandListener, ItemStateListener.
- CommandListener listens to command event, generated by any Displayable obj
- ItemStateListener listens to Item state change events, generated by a Form object
- Steps to handle Command event: Create a Command object  Add the Command
to a Displayable object using addCommand()  Create a listener class that
implements the CommandListener interface by supplying commandAction() method
 Create a listener object and register it to the Displayable object using
setCommandListener(). For Item, uses setItemCommandListener()
javax.microedition.lcdui.Command class:
- Represents an action that can be invoked by user similar to a button / menu
item
- To create a Command, Command(String label, in type, int priority)

javax.microedition.lcdui.CommandListener interface:
- Supply the method: void commandAction(Command c, Displayable d)
- A listener can be registered to listen on more than one Command but each
Command can only be handled by a single listener.

javax.microedition.lcdui.Displayable abstract class:


- void addCommand(Command cmd) / removeCommand(Command cmd)
- void setCommandListener(CommandListener l) // set a listener for all Commands to this

Page 76 of 87
Displayable object

Item state change event:


- triggered when the user has changed the status of an Item in a form
interactively; for example, when the user has entered some text in a TextField.

interface:
javax.microedition.lcdui.ItemStateListener
- represents a handler of item state change events
- Supply the method: void itemStateChanged(Item item)
- A listener can be registered to listen on more than one item state but each item
state can only be handled by a single listener.

java.microedition.lcdui.Form class:
- void setItemStateListener(ItemStateListener listener)

Low-level event handling:


- Only Canvas supports low-level event handling
- A number of low-level event handling methods, called “event delivery methods”
are defined in Canvas that will be invoked when specified events occur. The
default implementations of these methods are empty. Below are some of them:
- void keyPressed(int keyCode) // invoked when user presses a key
- void keyRepeated (int keyCode) // invoked when user holds down a key
- void keyReleased(int keyCode) // invoked when user releases a key
- void showNotify() // invoked before a canvas is made visible
- void hideNotify() // invoked after a canvas is made invisible
- String getKeyName(int keyCode) // returns the name of the key
The javax.microedition.rms package:
- The record management system (RMS) API for storing and retrieving
information in non-volatile memory.
- A RMS database is a flat-file database that stores data in record based.

javax.microedition.rms.RecordStore class:
- static RecordStore openRecordStore(String recordStoreName, boolean createIfNeeded)
- static void deleteRecordStore(String recordStoreName)
- void closeRecordStore() // close an opened record store
- byte[] getRecord(int recordID)
- int getRecord(int recordID, byte[] buffer, int offset) // gets data into buffer & returns bytes
- void setRecord(int recordID, byte[] newData, int offset, int numBytes)
- int addRecord(byte[] data, int offset, int numBytes) // add record to the store & returns ID

Page 77 of 87
- void deleteRecord(int recordID)
- RecordEnumeration enumerateRecords(RecordFilter filter, RecordComparator comparator,
boolean keepUpdated) // return an enumeration of records for iteration with “filter” as
selection and “comparator” as order (both can be null for not used). If
“keepUpdated” is true, the enumeration will be kept synchronized with the record
store.
- As byte array is required, we use java.io.DataOutputStream & ByteArrayOutputStream
classes to write records and use java.io.DataInputStream & ByteArrayInputStream to
get records. For example, for writing records:
- ByteArrayOutputStream bs = new ByteArrayOutputStream();
- DataOutputStream ds = new DataOutputStream(bs);
- ds.writeInt(3); / ds.writeUTF(“Hello”);
- byte[] data = bs.toByteArray();
- For reading records:
- DataInputStream ds = new DataInputStream(new ByteArrayInputStream(data));
- int x = ds.readInt(); / String s = ds.readUTF();
- Using RecordEnumeration to retrieve all records:
- RecordEnumeration enum = recordStore.enumerateRecords(null, null, false);
- while (enum.hasNextElement()) {
- byte[] data = enum.nextRecord();
- }

javax.microedition.rms.RecordEnumeration interface:
- boolean hasNextElement() / hasPreviousElement()
- byte[] nextRecord() / previousRecord() / int numRecords() // get no. records in the enum
- void rebuild() // rebuilds the enumeration to obtain the current record set
javax.microedition.rms.RecordFilter interface:
- boolean matches(byte[] candidate) // returns true if candidate matches the criteria

javax.microedition.rms.RecordComparator interface:
- int compare(byte[] rec1, byte[] rec2) // returns one
of following constants
- RecordComparator.EQUIVALENT // rec1 = rec2 in ordering
- RecordComparator.FOLLOWS // rec1 > rec2
- RecordComparator.PRECEDES // rec1 < rec2

GCF API in MIDP (the javax.microedition.io package):

Page 78 of 87
- The basic APIs are provided by the CLDC
- MIDP adds the HttpConnection, SocketConnection, UDPDatagramConnection and
ServerSocketConnection interfaces (not covered in this course) to GCF

HTTP connection in MIDlets:


- Supported by the javax.microedition.io.HttpConnection interface.
- HttpConnection is specifically designed to facilitate HTTP connection & parsing of
HTTP headers.
- To open an Http connection: HttpConnection http = (HttpConnection) Connecter.open(url);
- Due to its importance, it must be supported by all MIDP devices.

javax.microedition.io.HttpConnection interface:
- InputStream openInputStream() / DataInputStream openDataInputStream()
- OutputStream openOutputStream() / DataOutputStream openDataOutputStream()
- Int getResponseCode() / String getResponseMessage() // reads HTTP response info
- void close()// close the connection
- String getRequestMethod() / void setRequestMethod(String method)
- String getRequestProperty(String key) / void setRequestProperty(String key, String value)
- String getEncoding() / String getType() // get encoding or content type
- long getLength() // get content length
- long getLastModified() // get the value of the last-modified header

Page 79 of 87
- String getHeaderField(int n) / getHeaderField(String name)
- When an HTTP connection is obtained by the Connector.open(), it is said to be in
the setup state. In this state, you can modify the HTTP request. The connection
will change to connected state when any method (e.g. openInputStream, getLength,
getEncoding) that requires data to be sent or received from server is invoked.

HTTP programming example:


- HttpConnection http = (HttpConnection) Connector.open(url);
- StringBuffer resp = new StringBuffer();
- InputStream is = http.openInputStream();
- String server = http.getHeaderField(“server”);
- int b;
- while ((b = is.read()) != -1)
- resp.append((char) b);
- http.close();

Socket connection in MIDlets:


- Supported by the javax.microedition.io.SocketConnection interface.
- The support is not mandatory for MIDP devices => avoid for portability
- To obtain a socket connection: SocketConnection socket = (SocketConnection)
Connecter.open(“socket://localhost:8080”);
- Sending & reading data are done via the output & input streams of the socket.

javax.microedition.io.SocketConnection interface:
- InputStream openInputStream() / DataInputStream openDataInputStream()
- OutputStream openOutputStream() / DataOutputStream openDataOutputStream()
- void close() // close the socket connection
- String getAddress() / int getPort() // returns the remote address and port
- String getLocalAddress() / int getLocalPort() // returns the local address and port
Socket programming example: (typically put in run() of a thread)
- SocketConnection socket = (SocketConnection) Connector.open(serverURL);
- DataOutputStream dos = socket.openDataOutputStream();
- DataInputStream dis = socket.openDataInputStream();
- dos.writeUTF(msg); / dos.flush();
- String data = dis.readUTF();
- dos.close(); dis.close(); socket.close();

Datagram connection in MIDlets:


- Supported by the javax.microedition.io.DatagramConnection interface (in CLDC) and

Page 80 of 87
its sub-interface javax.microedition.io.UDPDatagramConnection (in MIDP), which has
extra methods for accessing the local address and port number.
- The support is not mandatory for MIDP devices => avoid for portabillity
- To obtain a socket connection: DatagramConnection socket = (DatagramConnection)
Connecter.open(“datagram://localhost:8080”);

javax.microedition.io.UDPDatagramConnection interface:
- Datagram newDatagram(byte[] buf, int size), newDatagram(byte[] buf, int size, String addr)
- Datagram newDatagram(int size), newDatagram(int size, String addr)
- void receive(Datagram datagram) / void send(Datagram datagram)
- int getMaximumLength()
- Above are inherited from DatagramConnection. Below in UDPDatagramConnection:
- String getLocalAddress() / int getLocalPort()

javax.microedition.io.Datagram interface:
- String getAddress(), void setAddress(String addr)
- byte[] getData(), void setData(byte[] buffer, int offset, int len)
- int getLength(), void setLength(int len)
- int readInt(), String readUTF(), double readDouble(), byte readByte(), boolean readBoolean(),
void reallyFully(byte[] b) // read from datagram. Corresponding write methods exists

Datagram programming example: (typically put in run() of a thread)


- DatagramConnection conn = (DatagramConnection) Connector.open(serverURL);
- Datagram datagram = conn.newDatagram(msg.getBytes(), msg.length);
- conn.send(datagram);
- Datagram received = conn.newDatagram(conn.getMaximumLength());
- conn.receive(received);
- String data = new String(received.getData(), 0, received.getLength());
- conn.close();

Page 81 of 87

Vous aimerez peut-être aussi