Qual è il modo idiomatico per comporre un URL o URI in Java?


115

Come si crea un URL o un URI in Java? C'è un modo idiomatico o biblioteche che lo fanno facilmente?

Devo consentire l'avvio da una stringa di richiesta, analizzare / modificare varie parti dell'URL (schema, host, percorso, stringa di query) e supportare l'aggiunta e la codifica automatica dei parametri di query.


7
Upvoting la domanda molto tempo dopo che è stata chiusa perché non è chiaro se esista una soluzione popolare non deprecata a questo problema. L'ho trovato cercando su Google "Java URL parameter class".
user1445967

4
Il mio intento era trovare un generatore di URL per Java, e questa domanda è utile almeno per me.
whirlwin

Risposte:


76

A partire da Apache HTTP Component HttpClient 4.1.3, dal tutorial ufficiale :

public class HttpClientTest {
public static void main(String[] args) throws URISyntaxException {
    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    qparams.add(new BasicNameValuePair("q", "httpclient"));
    qparams.add(new BasicNameValuePair("btnG", "Google Search"));
    qparams.add(new BasicNameValuePair("aq", "f"));
    qparams.add(new BasicNameValuePair("oq", null));
    URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
                                 URLEncodedUtils.format(qparams, "UTF-8"), null);
    HttpGet httpget = new HttpGet(uri);
    System.out.println(httpget.getURI());
    //http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
}
}

Modifica: a partire dalla v4.2 URIUtils.createURI()è stato deprecato a favore di URIBuilder:

URI uri = new URIBuilder()
        .setScheme("http")
        .setHost("www.google.com")
        .setPath("/search")
        .setParameter("q", "httpclient")
        .setParameter("btnG", "Google Search")
        .setParameter("aq", "f")
        .setParameter("oq", "")
        .build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());

20
Funziona, ma a partire dalla v4.2 URIUtils.createURI () è stato deprecato a favore di URIBuilder. Sul lato positivo, questo URIBuilder sembra avere un metodo addParameter () quindi la creazione di stringhe di richiesta dovrebbe essere almeno più semplice ora.
stian

6
URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams);come ha detto @stian
vanduc1102

Println sopra stampa quanto segue; google.com/…
Berkan Ercan

61

Come autore, probabilmente non sono la persona migliore per giudicare se il mio generatore di URL / URI è buono , ma qui è comunque: https://github.com/mikaelhg/urlbuilder

Volevo la soluzione completa più semplice possibile con zero dipendenze al di fuori del JDK, quindi ho dovuto eseguire il mio.


6
Sembra fantastico Mikael, hai pensato di pubblicarlo su Maven Central? So che è piccolo ma ne semplifica l'utilizzo. Non riesco a trovare una classe simile oltre a JAX-RS. La mancanza di dipendenze è sicuramente un vantaggio.
Barry Pitman

Sembra carino, ma poiché è un builder e quindi modificabile, perché ci sono setter solo per i parametri, ma non per host, porta, protocollo e percorso? E, beh, niente getter anche per quelli. UPD: Oh, non è modificabile - setParameter crea un clone. Bene, setHost / setPort / ... potrebbe funzionare allo stesso modo. O forse sarebbe anche bello avere una versione mutevole.
mvmn

3
"La soluzione completa più semplice possibile con zero dipendenze" - Sembra che tu sappia cosa è importante! La tua risposta dovrebbe essere quella accettata imho. Includere tutto HttpClient (con tutti i suoi aggiornamenti di versione e persino deprecare l'API di cui tratta questa domanda) solo per la creazione di un URL è ciò che rende le app piene di bug piene di bug.
Stijn de Witt

2
Finalmente su Maven Central, e mi ci sono voluti solo quattro anni per finire.
Mikael Gueck

@mikaelhg Grazie! Ne ho bisogno proprio in questo momento!
Fabian Damken


29

L'utilizzo di HTTPClient ha funzionato bene.

protected static String createUrl(List<NameValuePair> pairs) throws URIException{

  HttpMethod method = new GetMethod("http://example.org");
  method.setQueryString(pairs.toArray(new NameValuePair[]{}));

  return method.getURI().getEscapedURI();

}

6
Questa è ora una funzionalità deprecata. Qualcuno sa come utilizzare il nuovo pacchetto di componenti HTTP per fare lo stesso perché mi ha lasciato perplesso.
Link19

3
La nuova versione 4x non lo supporta più.
Joscha

13

Ci sono molte librerie che possono aiutarti con la costruzione di URI (non reinventare la ruota). Eccone tre per iniziare:


Java EE 7

import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();

org.apache.httpcomponents: HttpClient: 4.5.2

import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();

org.springframework: spring-web: 4.2.5.RELEASE

import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();

Vedi anche: GIST> Test di URI Builder


2
EE 7 è la risposta corretta. Tutto quello che devi fare è inserire l'intera suite di librerie EE, scegliere un'implementazione JAX-RS, risolvere i conflitti di versione di jax-rs e come ricompensa avrai una pratica classe UriBuilder che funziona davvero bene. Sarcasmo a parte, questa è la risposta corretta. :)
tekHedd


10

Usa OkHttp

È il 2020 e c'è una libreria molto popolare chiamata OkHttp che è stata recitata 35K volte su GitHub. Con questa libreria, puoi creare un URL come di seguito:

import okhttp3.HttpUrl;

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

Ho corretto un errore di battitura, è addPathSegment(non addPathSegments).
PapaFreud

1

Dopo essere stato criticato per aver suggerito la classe URL. Accetterò il consiglio del commentatore e suggerirò invece la classe URI . Ti suggerisco di esaminare attentamente i costruttori di un URI poiché la classe è molto immutabile una volta creata.
Penso che questo costruttore ti permetta di impostare tutto nell'URI di cui potresti aver bisogno.

URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)
          Constructs a hierarchical URI from the given components.

8
Ma non fornisce funzionalità per costruire e codificare effettivamente una stringa di query da un insieme di coppie di valori nome.
Link19

4
Come ha detto il bambino prodigio ad Alan Partridge, non si possono avere degradazioni dell'immutabilità, lo è o non lo è ;-) youtube.com/watch?v=_lvFns5Lubc
Stewart

Il costruttore di URI fa cose sgradevoli al percorso. Vedi blog.palominolabs.com/2013/10/03/… per i dettagli.
mpierce

1
Lascia che questa risposta sia un esempio di come NON farlo allora.
Mike Pone

1
Stringa di query ... Grazie Sun / Oracle per la granularità. Sostituiremo tutti gli spazi con i simboli più, codificheremo uri tutti i parametri e li collegheremo tutti insieme con i simboli della e commerciale noi stessi, quindi ... sbatte ripetutamente la testa sul tavolo
Stijn de Witt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.