Java에서 URL 또는 URI를 작성하는 관용적 방법은 무엇입니까?


115

Java에서 URL 또는 URI를 어떻게 작성합니까? 이것을 쉽게 할 수있는 관용적 인 방법이나 라이브러리가 있습니까?

요청 문자열에서 시작하고 다양한 URL 부분 (스키마, 호스트, 경로, 쿼리 문자열)을 구문 분석 / 변경하고 쿼리 매개 변수 추가 및 자동 인코딩을 지원해야합니다.


7
이 문제에 대한 인기있는 비추천 솔루션이 존재하는지 여부가 명확하지 않기 때문에 문을 닫은 후 오랫동안 질문에 찬성합니다. 나는 '자바 URL 매개 변수 클래스'에 대한 인터넷 검색을 통해 이것을 발견했습니다.
user1445967 2013-08-12

4
제 의도는 Java 용 URL 빌더를 찾는 것이었고이 질문은 적어도 저에게 유용합니다.
whirlwin

답변:


76

Apache HTTP 구성 요소 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/…
Berkan Ercan 2017 년

61

저자로서 저는 URL / URI 빌더가 좋은지 판단하기에 가장 좋은 사람은 아니지만 여기에는 https://github.com/mikaelhg/urlbuilder 가 있습니다.

JDK 외부에서 종속성이 전혀없는 가장 간단한 가능한 완전한 솔루션을 원했기 때문에 직접 롤링해야했습니다.


6
미카엘이 멋져 보입니다. 메이븐 센트럴에 게시 할 생각이 있으신가요? 나는 그것이 작다는 것을 알고 있지만 더 쉽게 사용할 수 있습니다. JAX-RS 외에 비슷한 클래스를 찾을 수 없습니다. 종속성이 없다는 것은 확실히 장점입니다.
Barry Pitman

멋져 보이지만 빌더이기 때문에 변경 가능하기 때문에 매개 변수에 대해서만 setter가 있고 호스트, 포트, 프로토콜 및 경로에 대한 설정자가없는 이유는 무엇입니까? 그리고 글쎄, 그들에게도 게터가 없습니다. UPD : 오, 변경할 수 없습니다. setParameter는 복제본을 생성합니다. 음, 여전히 setHost / setPort / ...는 같은 방식으로 작동 할 수 있습니다. 또는 아마도 변경 가능한 버전도 있으면 좋을 것입니다.
mvmn 2013-06-01

3
"종속성이 전혀없는 가장 간단하고 완전한 솔루션"-중요한 것이 무엇인지 아시는 것 같습니다! 당신의 대답은 받아 들여진 imho이어야합니다. URL을 구축하기 위해 모든 HttpClient (모든 버전 업데이트 및이 질문에 관한 API를 사용하지 않음)를 포함하는 것이 버그가 많은 앱을 만드는 이유입니다.
Stijn de Witt

2
마지막으로 Maven Central에서 작업을 완료하는 데 4 년 밖에 걸리지 않았습니다.
미카엘 Gueck

@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 구성 요소 패키지를 사용하여 동일한 작업을 수행하는 방법을 알고 있습니까?
Link19

3
새로운 4x 버전은 더 이상이를 지원하지 않습니다.
Joscha

13

URI 빌드에 도움이되는 많은 라이브러리가 있습니다 (바퀴를 재발 명하지 마십시오). 시작하는 데 도움이되는 세 가지가 있습니다.


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

참조 : 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
그러나 이름 값 쌍 집합에서 쿼리 문자열을 실제로 구성하고 인코딩하는 기능은 제공하지 않습니다.
Link19 2012 년

4
어린이 신동이 Alan Partridge에게 말했듯이-불변성의 저하를 가질 수는 없습니다. ;-) youtube.com/watch?v=_lvFns5Lubc
Stewart

URI의 생성자는 경로에 불쾌한 일을합니다. 자세한 내용은 blog.palominolabs.com/2013/10/03/… 을 참조 하세요.
mpierce 2013 년

1
이 대답을 어떻게하지 않는지에 대한 예로 삼으십시오.
Mike Pone 2013 년

1
문자열 쿼리 ... 세분성에 대해 Sun / Oracle에 감사드립니다. 모든 공백을 더하기 기호로 바꾸고, 모든 매개 변수를 uri- 인코딩하고, 앰퍼샌드 기호로 모두 함께 연결합니다. 그런 다음 테이블에 머리를 반복적
Stijn de Witt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.