53

Trying to build http://IP:4567/foldername/1234?abc=xyz. I don't know much about it but I wrote below code from searching from google:

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

public class MyUrlConstruct {

    public static void main(String a[]){

        try {
            String protocol = "http";
            String host = "IP";
            int port = 4567;
            String path = "foldername/1234";
            URL url = new URL (protocol, host, port, path);
            System.out.println(url.toString()+"?");
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }
    }
}

I am able to build URL http://IP:port/foldername/1234?. I am stuck at query part. Please help me to move forward.

px06
  • 2,256
  • 1
  • 27
  • 47
rrr ppp
  • 571
  • 1
  • 4
  • 7
  • 2
    Possible duplicate of [How do I concatenate two strings in Java?](http://stackoverflow.com/questions/3753869/how-do-i-concatenate-two-strings-in-java) – px06 Sep 14 '16 at 20:05
  • @px06 urls need escaping and validation, concat is not going to cut it because if `abc=xyz` contains some other `=, ? or &` it will be broken. Use a dedicated lib for this, for extremely simple cases concat may work though. – Christophe Roussy Mar 06 '18 at 13:52
  • 1
    Possible duplicate of [How to build url in java?](https://stackoverflow.com/questions/26641809/how-to-build-url-in-java) – Ivar Mar 19 '18 at 11:07
  • As of Java 7 there is the (EE) builtin `javax.ws.rs.core.UriBuilder` which does this for you. – Keeley Hoek Jan 10 '22 at 05:00

6 Answers6

74

You can just pass raw spec

new URL("http://IP:4567/foldername/1234?abc=xyz");

Or you can take something like org.apache.http.client.utils.URIBuilder and build it in safe manner with proper url encoding

URIBuilder builder = new URIBuilder();
builder.setScheme("http");
builder.setHost("IP");
builder.setPath("/foldername/1234");
builder.addParameter("abc", "xyz");
URL url = builder.build().toURL();
Community
  • 1
  • 1
vsminkov
  • 10,912
  • 2
  • 38
  • 50
  • 1
    Already had this lib as a dependency thanks to Apache http client lib, really helpful and simple. – Christophe Roussy Mar 06 '18 at 13:40
  • 1
    Note that this builder can also be used for partial url building, for example just for the parameters: `... builder.addParameter(...); ... builder.toString()` will return just this part even if other parts are missing. – Christophe Roussy Mar 06 '18 at 13:48
35

Use OkHttp

There is a very popular library named OkHttp which has been starred 20K times on GitHub. With this library, you can build the url like below:

import okhttp3.HttpUrl;

URL url = new HttpUrl.Builder()
    .scheme("http")
    .host("example.com")
    .port(4567)
    .addPathSegments("foldername/1234")
    .addQueryParameter("abc", "xyz")
    .build().url();

Or you can simply parse an URL:

URL url = HttpUrl.parse("http://example.com:4567/foldername/1234?abc=xyz").url();
Tyler Liu
  • 19,552
  • 11
  • 100
  • 84
  • 16
    I would avoid using a full HTTP client if all you need is to build a URL string. That's a heavy dependency for a light task. – NeuroXc Apr 09 '18 at 12:06
  • 1
    @NeuroXc yes what you said makes sense. I come from Node.js world where it's the dependency hell, so I get used to managing dependencies. On the other hand, it's not that bad since a heavy dependency won't make your app slow. It will make your app bigger though.So it depends. It could be an issue but in some case people don't care it. – Tyler Liu Apr 09 '18 at 13:39
  • I used your solution while migrating from an older Http client to okhttp, had to manually build the Url at onc place in the code base. thanks for this! Also we can use `HttpUrl url ` instead of `URL url` – Skynet Mar 30 '19 at 15:50
30

In general non-Java terms, a URL is a specialized type of URI. You can use the URI class (which is more modern than the venerable URL class, which has been around since Java 1.0) to create a URI more reliably, and you can convert it to a URL with the toURL method of URI:

String protocol = "http";
String host = "example.com";
int port = 4567;
String path = "/foldername/1234";
String auth = null;
String fragment = null;
URI uri = new URI(protocol, auth, host, port, path, query, fragment);
URL url = uri.toURL();

Note that the path needs to start with a slash.

VGR
  • 40,506
  • 4
  • 48
  • 63
  • 1
    If i have to user fragment in this code with "&" how can i use it ? e.g "http://IP:4567/foldername/1234?abc=xyz&def=stu" – rrr ppp Sep 15 '16 at 12:22
  • 3
    That is not a fragment. That's just multiple query parameters. Unfortunately, URI currently has no easy to assemble those; you’ll have to build the query string yourself. Note that query parameter values usually need to be [encoded](http://docs.oracle.com/javase/8/docs/api/java/net/URLEncoder.html#encode-java.lang.String-java.lang.String-). – VGR Sep 15 '16 at 13:26
  • 1
    As others stated this is OK for simple cases, but if you also need to escape params this will be problematic (&, ?, =, ...) – Christophe Roussy Mar 06 '18 at 13:50
  • @ChristopheRoussy This is [an open bug](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6306820) which for some reason Oracle doesn’t seem to feel is worth bothering to address. – VGR Mar 06 '18 at 14:31
  • @VGR probably for backward compatibility ? – Christophe Roussy Mar 06 '18 at 15:14
  • @ChristopheRoussy Backward compatibility is of paramount importance, but adding new constructors and methods would not break anything for existing code. Adding a template-less version of the [UriBuilder](https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/UriBuilder.html) class from Java EE would be even better. – VGR Mar 06 '18 at 15:19
11

If you happen to be using Spring already, I have found the org.springframework.web.util.UriComponentsBuilder to be quite nifty. Here is how you would use it in your case.

final URL myUrl = UriComponentsBuilder
        .fromHttpUrl("http://IP:4567/foldername/1234?abc=xyz")
        .build()
        .toUri()
        .toURL();
Philippe
  • 4,088
  • 4
  • 44
  • 49
10

If using Spring Framework:

UriComponentsBuilder.newInstance()
  .scheme(scheme)
  .host(host)
  .path(path)
  .build()
  .toUri()
  .toURL();

A new UriComponentsBuilder class helps to create UriComponents instances by providing fine-grained control over all aspects of preparing a URI including construction, expansion from template variables, and encoding.

Know more: https://www.baeldung.com/spring-uricomponentsbuilder

JavaDoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html

Saikat
  • 14,222
  • 20
  • 104
  • 125
1

If you use Android, you can use the Uri.Builder API. Example:

val uri = Uri.Builder().scheme("https").authority("s3.amazonaws.com").appendEncodedPath(bucketName).appendEncodedPath(fileName).build()

Docs:

https://developer.android.com/reference/android/net/Uri.Builder

android developer
  • 114,585
  • 152
  • 739
  • 1,270