Jaki jest idiomatyczny sposób tworzenia adresu URL lub identyfikatora URI w języku Java?


115

Jak zbudować adres URL lub identyfikator URI w języku Java? Czy jest jakiś idiomatyczny sposób lub biblioteki, które z łatwością to robią?

Muszę zezwolić na rozpoczęcie od ciągu żądania, analizować / zmieniać różne części adresu URL (schemat, host, ścieżka, ciąg zapytania) i wspierać dodawanie i automatyczne kodowanie parametrów zapytania.


7
Głosowanie za pytaniem długo po jego zamknięciu, ponieważ nie jest jasne, czy istnieje popularne rozwiązanie tego problemu, które nie jest przestarzałe. Znalazłem to, szukając w Google „klasy parametrów adresu URL języka Java”.
user1445967

4
Moim zamiarem było znalezienie narzędzia do budowania adresów URL dla języka Java i to pytanie jest przydatne przynajmniej dla mnie.
whirlwin

Odpowiedzi:


76

Od Apache HTTP Component HttpClient 4.1.3, z oficjalnego samouczka :

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=
}
}

Edycja: od wersji 4.2 URIUtils.createURI()została wycofana na korzyść 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
To działa, ale od wersji 4.2 URIUtils.createURI () został zastąpiony URIBuilder. Z drugiej strony, ten URIBuilder wydaje się mieć metodę addParameter (), więc tworzenie łańcuchów żądań powinno być teraz przynajmniej prostsze.
stian

6
URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams);jak powiedział @stian
vanduc1102

Println powyżej drukuje następujące; google.com/…
Berkan Ercan

61

Jako autor prawdopodobnie nie jestem najlepszą osobą do oceny, czy mój kreator adresów URL / URI jest dobry , ale tutaj jest tak: https://github.com/mikaelhg/urlbuilder

Chciałem najprostszego możliwego kompletnego rozwiązania z zerowymi zależnościami poza JDK, więc musiałem stworzyć własne.


6
Wygląda świetnie Mikael, czy myślałeś o opublikowaniu go w Maven Central? Wiem, że jest mały, ale ułatwia korzystanie z niego. Nie mogę znaleźć podobnej klasy poza JAX-RS. Brak zależności to zdecydowanie plus.
Barry Pitman

Wygląda ładnie, ale skoro jest konstruktorem, a zatem modyfikowalnym, dlaczego istnieją setery tylko dla parametrów, a nie dla hosta, portu, protokołu i ścieżki? I cóż, nie ma dla nich getters. UPD: Och, to nie jest zmienne - setParameter tworzy klon. Cóż, nadal setHost / setPort / ... może działać w ten sam sposób. A może warto też mieć zmienną wersję.
mvmn

3
„najprostsze możliwe kompletne rozwiązanie bez zależności” - brzmi tak, jakbyś wiedział, co jest ważne! Twoja odpowiedź powinna być zaakceptowana imho. Uwzględnienie całego HttpClient (ze wszystkimi jego aktualizacjami wersji, a nawet wycofaniem samego interfejsu API, o którym jest to pytanie) tylko w celu zbudowania adresu URL jest tym, co sprawia, że ​​aplikacje są najbardziej obciążone błędami.
Stijn de Witt

2
Wreszcie na Maven Central i zajęło mi to tylko cztery lata.
Mikael Gueck

@mikaelhg Dziękuję! Potrzebuję dokładnie w tej chwili!
Fabian Damken


29

Używanie HTTPClient działało dobrze.

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
Ta funkcja jest obecnie przestarzała. Czy ktoś wie, jak używać nowego pakietu HTTP Components, aby zrobić to samo, ponieważ mnie to zaskoczyło.
Link19,

3
Nowa wersja 4x już tego nie obsługuje.
Joscha

13

Istnieje wiele bibliotek, które mogą pomóc w budowaniu identyfikatorów URI (nie odkrywaj na nowo koła). Oto trzy, od których możesz zacząć:


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();

Zobacz także: GIST> Testy URI Builder


2
EE 7 to poprawna odpowiedź. Wszystko, co musisz zrobić, to pobrać cały zestaw bibliotek EE, wybrać implementację JAX-RS, rozwiązać konflikty wersji jax-rs, aw nagrodę otrzymasz poręczną klasę UriBuilder, która działa naprawdę dobrze. Pomijając sarkazm, to jest poprawna odpowiedź. :)
tekHedd


10

Użyj OkHttp

To 2020 i jest bardzo popularna biblioteka o nazwie OkHttp który został oznaczony gwiazdką 35k razy na GitHub. Dzięki tej bibliotece możesz zbudować adres URL, jak poniżej:

import okhttp3.HttpUrl;

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

Poprawiłem literówkę, to addPathSegment(nie addPathSegments).
PapaFreud

1

Po ostrzeżeniu za zasugerowanie klasy URL. Posłużę się radą komentatora i zasugeruję zamiast tego klasę URI . Proponuję przyjrzeć się bliżej konstruktorom identyfikatora URI, ponieważ po utworzeniu klasa jest bardzo niezmienna.
Myślę, że ten konstruktor pozwala ustawić w identyfikatorze URI wszystko, czego możesz potrzebować.

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

8
Ale nie zapewnia funkcji rzeczywistego konstruowania i kodowania ciągu zapytania z zestawu par nazwa-wartość.
Link 19

4
Jak powiedział cudowne dziecko do Alana Partridge'a - nie można mieć degradacji niezmienności, albo jest, albo nie jest ;-) youtube.com/watch?v=_lvFns5Lubc
Stewart

Konstruktor URI robi nieprzyjemne rzeczy na ścieżce. Aby uzyskać szczegółowe informacje, zobacz blog.palominolabs.com/2013/10/03/… .
mpierce

1
Niech ta odpowiedź będzie przykładem, jak NIE robić tego wtedy.
Mike Pone

1
Zapytanie łańcuchowe ... Dziękuję firmie Sun / Oracle za szczegółowość. Po prostu zastąpimy wszystkie spacje symbolami plus, zakodujemy uri wszystkie parametry i sami połączymy je wszystkie razem z symbolami ampersand, a następnie ... wielokrotnie uderza głową w stół
Stijn de Witt
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.