The last section showed you how to
install new protocol handlers that you wrote into HotJava, an
application that someone else wrote. However, if you write your own
application, you can implement your own scheme for finding and load
ing protocol handlers. The easiest way to do this is to install a
URLStream HandlerFactory
in your application:
public abstract interface URLStreamHandlerFactory
Only applications are allowed to install a new URL StreamHandlerFactory
. Applets that run in the applet viewer
or a web browser must use the
URLStreamHandlerFactory
that is provided. An
attempt to set a different one will fail, either because another
factory is already installed or because of a Security Exception
.
The URLStreamHandlerFactory
interface declares a
single method, createURLStreamHandler( )
:
public abstract URLStreamHandler createURLStreamHandler(String protocol)
This method loads the appropriate protocol handler for the specified
protocol. To use this method, write a class that implements the
URLStreamHandlerFactory
interface and include a
createURLStreamHandler( )
method in that class.
This method needs to know how to find the protocol handler for a
given protocol. This is no more complicated than knowing the names
and packages of the custom protocols you’ve implemented.
The createURLStreamHandler( )
method does not need
to know the names of all the installed protocol handlers. If it
doesn’t recognize a protocol, then it should simply return
null. This tells Java to follow the default procedure for locating
stream handlers; that is, to look for a class named
protocol
.Handler
in one
of the packages listed in the
java.protocol.handler.pkgs
system property or in
sun.net.www.protocol
.
To install the stream handler factory, pass an instance of the class
that implements the URLStreamHandlerFactory
interface to the static method
URL.setURLStreamHandlerFactory( )
at the start of
your program. Example 16.9 is a
URLStreamHandlerFactory( )
whose
createURLStreamHandler( )
method re cognizes the
finger, daytime, and chargen protocols and returns the appropriate
handler from the last several examples. Since these classes are all
named Handler
, fully package-qualified names are
used.
Example 16-9. A URLStreamHandlerFactory for finger, daytime, and chargen
package com.macfaq.net.www.protocol; import java.net.*; public class NewFactory implements URLStreamHandlerFactory { public URLStreamHandler createURLStreamHandler(String protocol) { if (protocol.equalsIgnoreCase("finger")) { return new com.macfaq.net.www.protocol.finger.Handler( ); } else if (protocol.equalsIgnoreCase("chargen")) { return new com.macfaq.net.www.protocol.chargen.Handler( ); } else if (protocol.equalsIgnoreCase("daytime")) { return new com.macfaq.net.www.protocol.daytime.Handler( ); } else { return null; } } }
We use the equalsIgnoreCase( )
method from
java.lang.String
to test the identity of the
protocol because it shouldn’t make a difference whether you ask
for finger://rama.poly.edu or
FINGER://RAMA.POLY.EDU. If the
protocol is recognized, then createURLStreamHandler( )
creates an instance of the proper
Handler
class and returns it; otherwise, the
method returns null
, which tells the
URL
class to look for a
URLStreamHandler
in the standard locations.
Since browsers, HotJava included, generally don’t allow you to
install your own URLStreamHandlerFactory
, this
will be of use only in applications. Example 16.10 is
a simple character mode program that uses this factory and its
associated protocol handlers to print server data on
System.out
. Notice that it does not import
com.macfaq.net.www.protocol.chargen
,
com.macfaq.net.www.protocol.finger
, or
com.macfaq.net.www.protocol.daytime
. All this
program knows is that it has a URL. It does not need to know how that
protocol is handled or even how the right
URLConnection
object is instantiated.
Example 16-10. A SourceViewer Program That Sets a URLStreamHandlerFactory
import java.net.*; import java.io.*; import com.macfaq.net.www.protocol.*; public class SourceViewer3 { public static void main (String[] args) { URL.setURLStreamHandlerFactory(new NewFactory( )); if (args.length > 0) { try { //Open the URL for reading URL u = new URL(args[0]); InputStream in = new BufferedInputStream(u.openStream( )); // chain the InputStream to a Reader Reader r = new InputStreamReader(in); int c; while ((c = r.read( )) != -1) { System.out.print((char) c); } } catch (MalformedURLException e) { System.err.println(args[0] + " is not a parseable URL"); } catch (IOException e) { System.err.println(e); } } // end if } // end main } // end SourceViewer3
Aside from the one line where the
URLStreamHandlerFactory
is set, this is almost
exactly like the earlier SourceViewer
program of
Example 7.5 in Chapter 7. For
instance, here the program reads from a finger
URL:
D:JAVAJNP2examples15>java SourceViewer3 finger://rama.poly.edu/
Login Name TTY Idle When Where
nadats Nabeel Datsun pts/0 55 Fri 16:54 128.238.213.227
marcus Marcus Tullius *pts/1 20 Thu 12:12 128.238.10.177
marcus Marcus Tullius *pts/5 2:24 Thu 16:42 128.238.10.177
wri Weber Research Insti pts/10 55 Fri 13:26 rama.poly.edu
jbjovi John B. Jovien pts/9 25d Mon 14:54 128.238.213.229
Here it reads from a daytime URL:
% java SourceViewer3 daytime://tock.usno.navy.mil/
<html><head><title>The Time at tock.usno.navy.mil</title></head><body><h1>Fri Oc
t 29 21:22:49 1999
</h1></body></html>
However, it still works with all the usual protocol handlers that come bundled with the JDK. For instance here are the first few lines of output when it reads from an http URL:
% java SourceViewer3 http://www.oreilly.com/oreilly/about.html
<HTML>
<HEAD>
<TITLE>About O'Reilly & Associates</TITLE>
</HEAD>
<BODY LINK="#770000" VLINK="#0000AA" BGCOLOR="#ffffff">
<table border=0 cellspacing=0 cellpadding=0 width=515>
<tr>
<td>
<img src="http://www.oreilly.com/graphics_new/generic_ora_header_wide.gif"
width="515" height="37" ALT="O'Reilly and Associates">
3.17.174.239