Joshua Zollinger
Joshua Zollinger

Reputation: 757

How do I specify a port number dynamically for an HTTPUrl?

I have a project that I am working on. It comes in two parts. For this part, we are supposed to be building the server, client communicator, and other functionality. We are not building the client yet; in order to pass off this part of the project, there is an automated tester that will act as the client. It will specify a random port number and create the server, then call a bunch of methods through the communicator.

The only place that I have access to the port number is when I initialize the server. The server itself has a main method that sets up the server; I have tried storing it as a static variable to access later, but when I try to access it I always get 0 as the port number in the request, which is wrong.

This line is from the ClientCommunicator. Specifically, this is what happens when the "client" calls the validateUser function, which only accepts two arguments: username and password. I cannot pass the port number as an additional argument.

String response = HttpClientHelper.doGetRequest(Helper.BASE_URL +"validateUser?username="+username+"&password="+password,null);

Helper has a static final variable BASE_URL which is currently set to

public static final BASE_URL = "http://localhost:8080/";

Obviously, this is no longer going to work. The change I would like to make would be to turn the line in my client communicator to

String response = ...(Helper.BASE_URL + (PORT_NUMBER) + "/" +...

where PORT_NUMBER would actually be something like Server.PORT_NUMBER,

and turn BASE_URL to

public static final BASE_URL = "http://localhost:"

However, I'm not sure how I would dynamically add the port number into the doGetRequest. I have tried storing it as a static variable in the server class which gets initialized when the server is started, but if I try to access it that way it ends up defaulting to 0.

My server class (I am not type-checking in this class for the port number, it's done elsewhere):

public class IndexerServer{
    public static int port;

    public enum RequestMethod {
        GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
    }

    public static void main(String[] args) throws IOException {
        int port = 8080;
        if(args.length > 0){
            port = Integer.parseInt(args[0]);
        }
        IndexerServer.port = port;
        InetSocketAddress addr = new InetSocketAddress(port);
        HttpServer server = HttpServer.create(addr,0);
        Helper.BASE_URL+= port + "/";

        server.createContext("/validateUser",new ValidateUser());
        server.createContext("/getProjects",new GetProjects());
        server.createContext("/getSampleImage",new GetSampleImage());
        server.createContext("/downloadBatch",new DownloadBatch());
        server.createContext("/getFields",new GetFields());
        server.createContext("/search",new Search());
        server.createContext("/submitbatch",new SubmitBatch());

        server.createContext("/images",new ImageDownloader());
        server.createContext("/fieldhelp",new HtmlDownloader());
        server.createContext("/knowndata",new HtmlDownloader());

        server.setExecutor(Executors.newCachedThreadPool());
        server.start();
        System.out.println("Server is listening on port "+port);
    }
}

and the pertinent part of the HTTPHelper

public class HttpClientHelper
{
public static String doGetRequest(String urlString,Map<String,String> headers){
    URL url;
    HttpURLConnection connection = null;
    try {
        //Create connection
        url = new URL(urlString);
        connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Content-Language", "en-US");

        connection.setUseCaches (false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        if(connection.getResponseCode() == 500){
            return "failed";
        }
        //Get Response
        InputStream is = connection.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();
        while((line = rd.readLine()) != null) {
            response.append(line);
        }
        rd.close();
        return response.toString();

    } catch (Exception e) {

        e.printStackTrace();
        return null;

    } finally {

        if(connection != null) {
            connection.disconnect();
        }
    }
}

Upvotes: 1

Views: 7813

Answers (2)

Jason C
Jason C

Reputation: 40315

If you don't care about losing the authority or anchor part of the input URL, you can just parse it, break it up and recreate it, replacing the port:

final int PORT = 42;

URL url = new URL(str);
URL newurl = new URL(url.getProtocol(), url.getHost(), PORT, url.getFile());

For example, for the input:

http://user:[email protected]:1234/path/file.ext?param=value#anchor

The output is:

http://hello.com:42/path/file.ext?param=value

If you want to preserve the authority / anchor, you'll have to modify the host and output appropriately (url.getAuthority() and url.getRef() will return the parsed components).

Upvotes: 2

jhn
jhn

Reputation: 361

Are the server and client communicator two different programs? If so, you can simply pass the port as an extra argument to the client when starting up and compose the string from there.

If both classes are part of the same program you can simply pass the port to HttpClientHelper using Integer.toString(port) when you call this helper. Something along the lines of url = new URL(urlString + port).

Upvotes: 0

Related Questions