Custom URL handlers are becoming more popular as desktop applications are interacting with Internet or Cloud sources. For example, to subscribe to a iTunes podcast, a website will have a link which looks something like this:
itpc://www.company.com/public/get/podcast.rss
Where "itpc" is a custom protocol handler created by iTunes to handle URLs of this type. The purpose of this article is to demonstrate how to create your own URL handler in Java.
Problem
Suppose there is need to create the "JTLC" protocol? If I were to create a URL object with this protocol...
public static void main(String[] args) throws Exception
{
String urlStr
{
String urlStr
= "jtlc://www.mycompany.com/some/path/to/resource";
URL url = new URL(urlStr);
}
URL url = new URL(urlStr);
}
I will get a nasty stack trace from Java...
Exception in thread "main" java.net.MalformedURLException:
unknown protocol: jtlc
at java.net.URL.<init>(URL.java:574)
at java.net.URL.<init>(URL.java:464)
at java.net.URL.<init>(URL.java:413)
at jtlc.main.Main.main(Main.java:14)
at java.net.URL.<init>(URL.java:574)
at java.net.URL.<init>(URL.java:464)
at java.net.URL.<init>(URL.java:413)
at jtlc.main.Main.main(Main.java:14)
This is because Java comes with a set of built in handlers to handle well known protocols like HTTP, but your JTLC protocol is unknown to Java so you get a stack trace. However, before Java throws the stack trace, it attempts to locate a handler for the JTLC protocol. If you provide the handler, Java will use it to handle JTLC.
Solution
Package
First (and easiest) thing to do is to create the following package in you application to hold the code for your JTLC protocol handler:
sun.net.www.protocol.jtlc
Java will automatically look in the root sun.net.www.protocol package for protocol handlers. Furthermore, by adding the additional sub-package jtlc (making the full package name you should use sun.net.www.protocol.jtlc), you are telling Java the code in this package handles the JTLC protocol. When you try to create a new URL object with the "jtlc" protocol, Java will look in the root sun.net.www.protocol package for a sub-package named jtlc to find the code to handle this protocol.
If you do not use this package, then you will have to set special system properties to tell Java what package holds the handlers for you JTLC protocol.
URLConnection
Second, you need to create a class which extends java.net.URLConnection.
The name of this class can be whatever you want, but it is good convention to name it after the letters in the protocol. The class for the JTLC protocol may look something like this:
package sun.net.www.protocol.jtlc;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class JtlcConnection extends URLConnection
{
public JtlcConnection(URL u) {
super(u);
}
@Override
public void connect()
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class JtlcConnection extends URLConnection
{
public JtlcConnection(URL u) {
super(u);
}
@Override
public void connect()
throws IOException {
throw new UnsupportedOperationException(
throw new UnsupportedOperationException(
"The connect() method is not supported"
);
}
@Override
public Object getContent()
}
@Override
public Object getContent()
throws IOException {
throw new UnsupportedOperationException(
throw new UnsupportedOperationException(
"The getContent() method is not supported"
);
}
@Override
public InputStream getInputStream()
}
@Override
public InputStream getInputStream()
throws IOException {
throw new UnsupportedOperationException(
throw new UnsupportedOperationException(
"The getInputStream() method is not supported"
);
}
}
}
}
Of course you will want to provide a real implementations for these methods to handle connecting to your resource and getting a stream to the content.
URLStreamHandler
Finally, you will need to create a class with extends java.net.URLStreamHandler.
THE NAME OF THIS CLASS MUST BE "Handler". Java will automatically look for a class named Handler inside the sun.net.www.protocol.jtlc package. If you name this class something other than Handler, Java will not find it.
The purpose of Handler is to create an instance of URLConnection subclass. An example may look like this:
package sun.net.www.protocol.jtlc;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
public class Handler extends URLStreamHandler
{
@Override
protected URLConnection openConnection(URL u)
throws IOException
{
return new JtlcConnection(u);
}
}
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
public class Handler extends URLStreamHandler
{
@Override
protected URLConnection openConnection(URL u)
throws IOException
{
return new JtlcConnection(u);
}
}
Summary
Although there are more than one way to create your own Java protocol handlers, this is the quickest and easiest way I've found.
That's it. Enjoy!
Thank you for putting an effort to published this article. You've done a great job! Good bless!
ReplyDeleteYong
www.gofastek.com
Simple and brilliant.
ReplyDeleteThe sun.net.www.protocol..Handler is the last choice for searching URL procotol handler. Instead you can create handler having any class name in any package and use an URLStreamHandlerFactory. see https://stackoverflow.com/questions/26363573/registering-and-using-a-custom-java-net-url-protocol
ReplyDelete