Creating HttpURLConnection for URLStreamHandlerFac

2019-07-17 06:19发布

问题:

A bit of background, I'm trying to create a URL Stream Handler so I can keep track of how many connections I have active on my webview in my javafx application. Essentially, I'm running an AngularJs app in the WebView, and I'd like to know when it's finished. I can't touch the web site code, so adding a js notifier is not on the table. So, no matter what I put together, the setup always errors with 'protocol doesn't support input.' I've tried to override 'getDoInput' with a method that only returns false, but I still get the error. Any ideas?

Here is something close to what I'm doing:

public class MyUrlStreamHandlerFactory implements URLStreamHandlerFactory {

    public URLStreamHandler createURLStreamHandler(String protocol) {
        if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) {

            return new URLStreamHandler() {
                @Override
                protected URLConnection openConnection(URL url) throws IOException {

                    return new HttpURLConnection(url) {
                        @Override
                        public void connect() throws IOException {

                        }

                        @Override
                        public void disconnect() {

                        }

                        @Override
                        public boolean usingProxy() {
                            return false;
                        }

                        @Override
                        public boolean getDoInput() {
                            return false;
                        }
                    };

                }
            };

        }
        return null;
    }
}

I'm installing it with:

URL.setURLStreamHandlerFactory(new MyUrlStreamHandlerFactory());

回答1:

I understand what you're trying to accomplish however, I think this is the wrong way to go about it.

From: Java Network Programming by Elliotte Rusty Harold

Only abstract URLConnection classes are present in the java.net package. The concrete subclasses are hidden inside the sun.net package hierarchy. It is rare to instantiate URLConnection objects directly in your source code; instead, the runtime environment creates these objects as needed, depending on the protocol in use. The class (which is unknown at compile time) is then instantiated using the forName() and newInstance() methods of the java.lang.Class class.

For example, the connect() method of sun.net.www.protocol.http.HttpURLConnection creates a sun.net.www.http.HttpClient object, which is responsible for connecting to the server.

So unless you want to write your own http protocol handler and an HttpClient, I would suggest exploring other avenues.

Other Things

The only method, that I could find, that throws an UnknownServiceException with the message being "protocol doesn't support input" is:

java.net.URLConnection#getInputStream

/**
* Returns an input stream that reads from this open connection.
*
* @return     an input stream that reads from this open connection.
* @exception  IOException              if an I/O error occurs while
*               creating the input stream.
* @exception  UnknownServiceException  if the protocol does not support
*               input.
*/
public InputStream getInputStream() throws IOException {
    throw new UnknownServiceException("protocol doesn't support input");
}

Overriding getDoInput
You should not override getDoInput to only return false. Instead you should use setDoInput(false). However, you don't want to set doInput to false. You always want to read something, for instance the response code.