Documente Academic
Documente Profesional
Documente Cultură
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
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
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
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
Page 4 of 87
- com.sun.java.swing.plaf.windows.WindowsLookAndFeel: Windows PLAF
- com.sun.java.swing.plaf.mac.MacLookAndFeel: Macintosh PLAF
Advantages of MVC:
- Reduce complexity and Increase reusability
- Multiple views can be registered to a 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)
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
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.
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
- 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.
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
Page 10 of 87
- Support for managing and loading resources:
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”);
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.
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}”); }
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();
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
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.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).
Page 15 of 87
obtain streams, read/write according to the protocol and close the socket lastly.
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();
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
- 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);
Page 19 of 87
developed without dealing with low-level sockets and complex protocols.
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.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.
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
Disadvantages
Passing Remote object Invoking methods on server’s copy is slower
Passing Serializable object Serializing large object can be slow
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
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.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()
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
- <% } %>
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.
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)
Page 28 of 87
- Handling Java plugin: <jsp:plugin>
- Creating tag files: out of scope of the course
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
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” %>
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
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);
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();
Transaction:
- Connection object is created with auto commit by default
- conn.setAutoCommit(false); // turn off auto commit
- conn.commit(); / conn.rollback();
Page 34 of 87
* The relationship between
Persistence API & providers
is like JDBC & database
drivers
Page 35 of 87
@Table(name = “Customer”)
public class Buyer {
@Id
@Column(name = “CustomerID”)
public int getBuyerID() {return buyerID;}
public void setBuyerID(String buyerID) {this.buyerID = buyerID;}
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.
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 { … }
- 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.
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
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.
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.
Page 42 of 87
* Entity bean (in earlier version of EJB) is replaced by JPA entity in EJB 3.0
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());
- 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.
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
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
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();
}
}
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) {
}
}
}
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.
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.
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:
@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() { … }
}
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
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.
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”>
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
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
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.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
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)
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
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
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
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.
Page 66 of 87
Layers in the Java ME architecture:
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.
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.
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.
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.
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
- 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().
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()
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.
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)
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.
Page 76 of 87
Displayable object
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)
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
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
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.
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();
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
Page 81 of 87