Який ідіоматичний спосіб скласти URL або URI на Java?


115

Як створити URL або URI на Java? Чи є ідіоматичний спосіб чи бібліотеки, які легко це роблять?

Мені потрібно дозволити починати з рядка запиту, аналізувати / змінювати різні частини URL-адреси (схема, хост, шлях, рядок запиту) та підтримувати додавання та автоматичне кодування параметрів запиту.


7
Оскарження питання задовго після його закриття, оскільки не ясно, чи існує популярне непридатне рішення цієї проблеми. Я знайшов це за допомогою googling для 'java class type class'.
користувач1445967

4
Моя мета полягала в пошуку конструктора URL-адрес для Java, і це питання корисне для мене щонайменше.
вихор

Відповіді:


76

Станом на Apache HTTP Component HttpClient 4.1.3, з офіційного підручника :

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

Редагувати: станом на v4.2 URIUtils.createURI()застаріло на користь 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
Це працює, але станом на v4.2 URIUtils.createURI () застаріло на користь URIBuilder. З позитивної сторони, схоже, у цього URIBuilder є метод addParameter (), тому рядки запитів побудови зараз повинні бути, принаймні, простішими.
stian

6
URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams);як сказав @stian
vanduc1102

Println надрукує наступне; google.com/…
Беркан Еркан

61

Як автор, я, мабуть, не найкраща людина, щоб оцінити, чи хороший мій конструктор URL-адрес / URI , але ось все-таки це: https://github.com/mikaelhg/urlbuilder

Я хотів найпростішого можливого повного рішення з нульовими залежностями поза JDK, тому мені довелося скрутити своє.


6
Чудово виглядає Мікаель, ти думав опублікувати його в Maven central? Я знаю його невелике, але полегшує його використання. Я не можу знайти подібного класу, окрім JAX-RS. Відсутність залежності, безумовно, є плюсом.
Баррі Пітман

Це виглядає приємно, але оскільки він є конструктором і таким чином змінюється, чому існують сеттери лише для параметрів, а не для хоста, порту, протоколу та шляху? І, ну, жодних заготівельників також немає. UPD: О, це не міняється - setParameter створює клон. Ну, але все ще setHost / setPort / ... може працювати так само. Або, можливо, непогано було б мати і змінну версію.
mvmn

3
"найпростіше можливе повне рішення з нульовими залежностями" - Здається, ви знаєте, що важливо! Ваша відповідь має бути прийнятим одним імхо. Включення всіх HttpClient (з усіма оновленнями версій та навіть знецінення самого API, про яке йдеться у цьому питанні), лише для створення URL-адреси - це те, що є важливим для найважчих програм з помилками.
Штійн де Вітт

2
Нарешті на Maven Central, і мені знадобилося лише чотири роки, щоб закінчити.
Мікаел Гек

@mikaelhg Дякую! Мені потрібно саме в цю мить!
Fabian Damken


29

Використання HTTPClient добре працювало.

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
Зараз це застаріла функціональність. Хтось знає, як використовувати новий пакет HTTP Components, щоб зробити те саме, тому що це мене наткнуло.
Посилання19

3
Нова версія 4x вже не підтримує це.
Джоша

13

Є багато бібліотек, які можуть допомогти вам у створенні URI (не винаходити колесо). Ось три, щоб розпочати:


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

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

Дивіться також: GIST> Тести будівельника URI


2
EE 7 - правильна відповідь. Все, що вам потрібно зробити - це залучити весь набір бібліотек EE, вибрати реалізацію JAX-RS, вирішити конфлікти версій jax-rs, і як винагороду ви матимете зручний клас UriBuilder, який працює дуже добре. Сарказм в стороні, це є правильною відповіддю. :)
tekHedd


10

Використовуйте OkHttp

Це 2020 і є дуже популярна бібліотека імені OkHttp яка позначено 35k раз на GitHub. За допомогою цієї бібліотеки ви можете створити URL-адресу, як показано нижче:

import okhttp3.HttpUrl;

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

Я виправив помилку, це addPathSegment(не addPathSegments).
PapaFreud

1

Після того, як вони отримали відмітку за пропозицію класу URL. Я скористаюся порадою коментатора і запропоную замість цього клас URI . Я пропоную вам уважно подивитися на конструктори для URI, оскільки клас дуже непорушний, коли він створений.
Я думаю, що цей конструктор дозволяє встановити все в URI, що вам може знадобитися.

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

8
Але він не забезпечує функціональність для фактичної побудови та кодування рядка запиту з набору пар значень імен.
Посилання19

4
Як сказав блудний дитина Алану Партріджу - у деградації незміненості не може бути, або є; або немає ;-) youtube.com/watch?v=_lvFns5Lubc
Стюарт

Конструктор URI робить неприємні речі на шляху. Докладні відомості див. У blog.palominolabs.com/2013/10/03/… .
mpierce

1
Нехай ця відповідь є прикладом того, як НЕ робити цього тоді.
Майк Пойн

1
Рядок запиту ... Дякую Sun / Oracle за детальність. Ми просто замінимо всі пробіли символами плюс, uri-кодуємо всі параметри і зв’яжемо їх усі разом із символами "ampersand", тоді ... повторимо голову об стіл неодноразово
Stijn de Witt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.