You are on page 1of 37

Advanced Java

Applications
Overview
We will see some advanced techniques
and applications of Java

We will take a quick look at some data


structures built into the language

Next will show be how Java and Object


Orientation can be applied to networking

Finally we will be to show Reflection in Java


Hashtable Example

Hashtable numbers = new Hashtable();


key value
numbers.put("one", new Integer(1));
numbers.put("two", new Integer(2));
numbers.put("three", new Integer(3));
Hashtable Example

Specific
Object Object

Integer n = (Integer)numbers.get("two");
if (n != null) {
System.out.println("two = " + n);
}
Many Other Collections
Vector
Stack
LinkedList
Dictionary
ArrayList
http://www.javasoft.com/products/jdk/1.2/docs/api/in
dex.html for a complete list
Networking

Using the networking capabilities provided in the


Java environment is quite easy

We will see how to use Sockets


Sockets

Lower-level network communication


- Client uses some service
- Server - provides some service

TCP provides a reliable, point-to-point


communication channel for client-server apps
What Is a Socket?

A socket is one endpoint of a two-way


communication link between two programs
running on the network.

A socket is bound to a port number so that the TCP


layer can identify the application that data is destined
to be sent.
How do Sockets work?
A server runs on a specific computer and has a socket
that is bound to a specific port number.

Client knows the hostname and port of server


and tries to make a connection request
Connection established
If the server accepts the connection it gets a new
socket bound to a different port.
It needs a new socket (and consequently a
different port number) so that it can continue to
listen to the original socket
How does Java support Sockets

The java.net package provides a class, Socket, that


implements one side of a two-way connection
between your Java program and another program on
the network

It also includes the ServerSocket class, which


implements a socket that servers can use to listen for
and accept connections to client
Echo Echo Echo
import java.io.*;
import java.net.*;

public class EchoClient {


public static void main(String[] args)
throws IOException {

Socket echoSocket = null;


PrintWriter out = null;
BufferedReader in = null;
//
Establish the Socket connection

Host Port Output


try {
echoSocket = new Socket(image ", 7777);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new
InputStreamReader(echoSocket.getInputStream()));
}
catch
Input
Need to Catch Exceptions

}
catch (UnknownHostException e) {
System.err.println("Don't know about host: avatar.");
System.exit(1);
}
catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: avatar.");
System.exit(1);
}
Simple Socket Example
Set up a mechanism to read from standard input

BufferedReader stdIn = new BufferedReader(


new InputStreamReader(System.in));
String userInput;
Read from standard input
while ((userInput = stdIn.readLine()) != null) {

out.println(userInput); Write to
Server
System.out.println("echo: " + in.readLine());
} Output whats read back from Server
Close up Shop on Client side

out.close( );

in.close( );

stdIn.close( );

echoSocket.close( );
Basic Steps
Open a socket.
Open an input stream and output stream to the
socket.
Read from and write to the stream according to the
server's protocol.
Close the streams.
Close the socket.
Same Basic Steps
This client program is straightforward and simple
because the Echo server implements a simple
protocol

Even with more complicated protocols such as HTTP


server, your client program while more complicated
will follow the same basics as this simple example
Server

A server must open a SeverSocket


ServerSocket server = new ServerSocket( 7777 );

Call accept on that socket creating a new socket


Socket socket = server.accept();

Socket acts as socket from client


If a socket is a pipe
We could conceptualize this like so:

Ports Client
Server

The Socket Plumbing The things flowing through


the Plumbing
The Answer Is ..
A Number of things can conceptually flow through the
pipe
We will focus on two:
Objects
Characters from a String

We looked at several examples last time


The first was a simple echo program a very simple
protocol give me back what I gave you (Strings)
We also looked at simpleprotocol example (Protocol
Objects)
Objects flow through the Pipe

Let first address the case where we want to have


objects flowing over the pipe

Must have at least the following mechanisms for


Objects to be written by the server
Objects to be read by the client
The newprotocol Client
public class Client {
Socket socket = new Socket( "127.0.0.1", 9999 );
//
ObjectInputStream input =
new ObjectInputStream(socket.getInputStream() );

// read using serialization


NewProtocol protocol = (NewProtocol)(input.readObject() );
System.out.println(Protocol: + protocol);

socket.close();
The newprotocol Server
class ThreadedSocket extends Thread {
// here is where all the real work is done.
private Socket socket;

ThreadedSocket( Socket socket ) {


this.socket = socket;
//
ObjectOutputStream output =
new ObjectOutputStream(socket.getOutputStream() );

output.writeObject( protocol );
Reading and Writing Objects
An ObjectOutputStream writes primitive data
types and graphs of Java objects to an
OutputStream.

The objects can be read (reconstituted) using an


ObjectInputStream.

General Mechanism
This works for the sockets as was just shown
but is actually more general
Persistent storage of objects can be
accomplished by using a file for the stream.
File example
For example to write an object that can be read by
the example in ObjectInputStream

FileOutputStream ostream = new FileOutputStream(foo.bar");


ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeInt(12345);
p.writeObject("Today");
p.writeObject(new Date());
p.flush();
ostream.close();
The read counterpart

FileInputStream istream = new FileInputStream(" foo.bar ");

ObjectInputStream p = new ObjectInputStream(istream);

int i = p.readInt();

String today = (String)p.readObject();

Date date = (Date)p.readObject();

istream.close();
The Needed Java Framework
Only objects that support the java.io.Serializable
interface can be written to streams.

The class of each serializable object is encoded


including the class name and signature of the class, the
values of the object's fields and arrays, and the closure
of any other objects referenced from the initial objects

This relates to introspection/reflection which we will


discuss shortly
More about the Framework

The default deserialization mechanism for objects


restores the contents of each field to the value and
type it had when it was written.

Marshalling of Objects (Serialize)


Un marshaling of Object (Serialize)
Deserialization& Object Reflection

Fields declared as transient or static are ignored by the


deserialization process.

References to other objects cause those objects to be read


from the stream as necessary.
Graphs of objects are restored correctly using a Reflection
reference sharing mechanism.
New objects are always allocated when deserializing,
which prevents existing objects from being
overwritten
Reflection Allows

Determination of the class of an object.

Creation of an instance of a class whose name is not


known until runtime.

Obtaining information about a class's modifiers, fields,


methods, constructors, and superclasses.

Determination of constants and method declarations


that belong to an interface
Reflection Also Allows

Allows one to get and set the value of an


object's field, even if the field name is
unknown to your program until runtime.
Allows one to invoke a method on an
object, even if the method is not known
until runtime.
Create a new array, whose size and
component type are not known until
runtime, and then modify the array's
components.
Examining Classes

A way to get information about classes at runtime

For each class, the Java Runtime Environment


(JRE) maintains an immutable Class object that
contains information about the class. A Class
object represents, or reflects, the class

To get this information you need to get the Class


object that reflects the class
Retrieving Class Objects
You can retrieve a Class object in several ways:
Class c = foo.getClass() // for some object named foo

Bar b = new Bar();


Class c = b.getClass();
Class s = c.getSuperclass();

Foo
Foo

Bar
Bar
Other Ways of Retrieving Class Objects

If you know the name of the class at compile time,


you can retrieve its Class object by appending
.class to its name:

Class c = java.awt.Button.class;

You can also use the Class.forName static method:

Class c = Class.forName(commandNameToken)
Getting the Class Name
Every class in the Java programming language has a
name. When you declare a class, the name immediately
follows the class keyword

At runtime, you can determine the name of a Class object


by invoking the getName method. The String returned by
getName is the fully-qualified name of the class.

A good home study question: Given an instance prints the


names of the classes its inheritance hierarchy from least
specific to most specific excluding Object
An Example
import java.lang.reflect.*;
import java.awt.*;
class SampleName {
public static void main(String[] args) {
Need Reflection
Button b = new Button(); Package
To Do this
printName(b);
}
static void printName(Object o) {
Class c = o.getClass();
String s = c.getName();
System.out.println(s);
}}

You might also like