Meaning of -1 port value in java.net.URL?

Viewed 552

I need to create an URL based on the port number by using java.net.url class's constructor. To do that I've used the constructor below,

public URL(String protocol, String host, int port, String file){} I need to create two different URL; if the port is 80, need to ignore the port, else URL should contain the port number. I'm not able to send port number as null, there is a value which is -1. When I use -1 for port, it creates the URL without port.

My problem is documentation of constructor; above of the constructor there is a description and that decription is "Specifying a {@code port} number of {@code -1} indicates that the URL should use the default port for the protocol.". As I mentioned, I don't want to use default port number. If that is the case, how can I create a URL only with a such constructor?

BTW, I know, I could use only String version, I don't want to write two new URL to do that. Basically, I want to write something like this, new URL(scheme, serverName, serverPort == 80 ? -1 : serverPort, contextPath); // as I mentioned based on the documentation of URL constructor, -1 gets the default port number, but in the code it is not like that.

Waiting for your suggestions. Thank you.

EDIT new URL(scheme, serverName, serverPort == 80 ? null: serverPort, contextPath);

3 Answers

I see the documentation is what's confusing you. When the documentation says

Specifying a {@code port} number of {@code -1} indicates that the URL should use the default port for the protocol.

What it means is that the URL is created without a port number. But when you connect to a host, you need to use a port, and if the URL does not have a port, the default port for the protocol will be used.

  • The string representation of the URL will not use the default port.
  • The network connection created by URL.openConnectiom will use the default port.

The URL class itself simply stores the port number if you provide it or doesn't store it if you don't.

If it doesn't store one (internally and in parameters that's represented as -1), then the external form of the URL will simply not have a visible port specified. That seems to be exactly what you want to do.

When it says "If the port is not specified, the default port for the protocol is used instead." it simply means that if you actually access the URL in some way (in other words when the code must know a specific port) and you didn't specify one then the handler will just use whatever the default is in the protocol.

In other words: http://example.org/ and http://example.org:80/ are two different URLs (the first would have port set to -1 in an URL object). But if you try to connect to them, then they would do the exact same steps (because in the absence of an explicit port specification any HTTP client will use port 80).

So you want the constructor:

public URL(String protocol, String host, int port, String file){}

not to heed the port, when it's 80?

Shouldn't something like

if(port == 80) return URL(protocol, host, file)
else return URL(protocol, host, port, file)

be sufficient?

Since int is primitive, you cannot null it. Therefore you must define a number here, regardless if you like it or not.

The three argument constructor is just setting the port to -1 as well:

public URL(String protocol, String host, String file)
        throws MalformedURLException {
    this(protocol, host, -1, file);
}

Therefore your best bet is to do the following:

URL url = new URL("http","localhost",port == 80 ? -1 : port,null);

Since all of these constructors are leading to the five argument constructor, the port will be evaluated as follows:

        if (port < -1) {
            throw new MalformedURLException("Invalid port number :" +
                                                port);
        }
        this.port = port;
        authority = (port == -1) ? host : host + ":" + port;

You have no choice here.

Related