Android에서 URI 빌더를 사용하거나 변수가있는 URL을 작성하십시오.


202

Android 앱을 개발 중입니다. API 요청을하려면 앱의 URI를 빌드해야합니다. URI에 변수를 넣는 다른 방법이 없다면 이것이 내가 찾은 가장 쉬운 방법입니다. 나는 당신이 사용해야한다는 것을 Uri.Builder알았지 만 어떻게 해야할지 잘 모르겠습니다. 내 URL은 다음과 같습니다

http://lapi.transitchicago.com/api/1.0/ttarrivals.aspx?key=[redacted]&mapid=value 

내 체계는 http, authority is lapi.transitchicago.com, path is /api/1.0, path segment (s) is ttarrivals.aspx, query string is key=[redacted]&mapid=value입니다.

내 코드는 다음과 같습니다.

Intent intent = getIntent();
String value = intent.getExtras().getString("value");
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
    .authority("www.lapi.transitchicago.com")
    .appendPath("api")
    .appendPath("1.0")
    .appendPath("ttarrivals.aspx")
    .appendQueryParameter("key", "[redacted]")
    .appendQueryParameter("mapid", value);

나는 할 수 있음을 이해 URI.add하지만 어떻게 그것을 통합 할 수 Uri.Builder있습니까? 내가 좋아하는 모든 것을 추가해야합니다 URI.add(scheme), URI.add(authority)과 정도? 아니면 그렇게 할 수 있습니까? 또한 URI / URL에 변수를 추가하는 다른 쉬운 방법이 있습니까?

답변:


426

다음 URL을 만들고 싶다고 가정 해 봅시다.

https://www.myawesomesite.com/turtles/types?type=1&sort=relevance#section-name

이것을 사용하여 빌드하려면 Uri.Builder다음을 수행하십시오.

Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
    .authority("www.myawesomesite.com")
    .appendPath("turtles")
    .appendPath("types")
    .appendQueryParameter("type", "1")
    .appendQueryParameter("sort", "relevance")
    .fragment("section-name");
String myUrl = builder.build().toString();

1
내 경로 세그먼트를 사용하면 경로입니까? 아니면 쿼리일까요?
hichris123

경로 인 경우이 appendPath()방법 이 적합합니다. 쿼리 문자열 인 경우 (? 뒤에 나오는)를 사용하십시오 appendQueryParameter(). 예제에있는 URL과 각 세그먼트에서 수행중인 작업을 살펴보십시오. 나는 또한 올바른 유형을 되찾기 위해 전화에 추가 toString()했습니다 build().
David

1
물음표 앞에 있지만 그 뒤에 /가 없습니다. 위의 질문에 대한 ttarrivals.aspx입니다. 이것이 경로일까요?
hichris123

옳은. 그것은 길의 끝일뿐입니다. 기술적으로 원하는 경우 끝에 "/"를 넣을 수 있으며 유효합니다. mysite.com/path은 동일하다 mysite.com/path
데이비드

1
완벽한 답변! API 문서에 이미 포함되어 있어야합니다.
robinmitra

259

사용하는 다른 방법이 Uri있으며 동일한 목표를 달성 할 수 있습니다

http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7

Uri를 빌드하려면 다음을 사용할 수 있습니다.

final String FORECAST_BASE_URL = 
    "http://api.example.org/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";

당신이 모든 위의 방법을 선언하거나 할 수 있습니다, 심지어 내부 Uri.parse()appendQueryParameter()

Uri builtUri = Uri.parse(FORECAST_BASE_URL)
    .buildUpon()
    .appendQueryParameter(QUERY_PARAM, params[0])
    .appendQueryParameter(FORMAT_PARAM, "json")
    .appendQueryParameter(UNITS_PARAM, "metric")
    .appendQueryParameter(DAYS_PARAM, Integer.toString(7))
    .build();

마침내

URL url = new URL(builtUri.toString());

14
더 많은 표를받을 자격이 있습니다! 필자의 경우 기본 사용 사례는 이미 정의 된 문자열 URL이 있고 매개 변수를 추가 / 추가하려는 경우입니다.
lorenzo-s

1
나는 햇볕 (이 정확한 문자열)에 대한 해결책을 찾고 있었지만 가장 많이 투표 된 질문은 훨씬 강력한 해결책을 제공합니다.
Nahum

1
Uri.buildUpon () 힌트에 감사드립니다! 두통을 덜어주었습니다.
chrjs

물론 URL이 만들어지는 순서가 혼란 스러웠습니다. 물론 완전한 URL이 아닌 유일한 변수이기 때문입니다.
blackHawk

기본 URL이 없지만 전체 URL을 대신 사용하면 어떻게 되나요? Parse + BuildUpon + AppendQueryParam + Build를 사용하면 유효하지 않은 url ([도메인] [경로] [queryParams] 대신 [도메인] [queryParams] [경로])을 얻음)
Giuseppe Giacoppo

20

위에서 훌륭한 대답은 간단한 유틸리티 방법으로 바뀌 었습니다.

private Uri buildURI(String url, Map<String, String> params) {

    // build url with parameters.
    Uri.Builder builder = Uri.parse(url).buildUpon();
    for (Map.Entry<String, String> entry : params.entrySet()) {
        builder.appendQueryParameter(entry.getKey(), entry.getValue());
    }

    return builder.build();
}

UTF8 컨텐츠를 변환 할 필요가 없습니까?
Webserveis

15

여기에 설명하는 좋은 방법이 있습니다.

URI에는 두 가지 형태가 있습니다

1 - 빌더 (준비 수정 , 하지 준비를 사용 )

2 - 내장 ( 하지 준비가 될 수정 , 준비 할 사용 )

당신은 빌더를 만들 수 있습니다

Uri.Builder builder = new Uri.Builder();

이렇게하면 빌더 를 다음과 같이 수정할 수 있습니다.

builder.scheme("https");
builder.authority("api.github.com");
builder.appendPath("search");
builder.appendPath("repositories");
builder.appendQueryParameter(PARAMETER_QUERY,parameterValue);

그러나 그것을 사용하려면 먼저 빌드해야합니다

retrun builder.build();

또는 당신은 그것을 사용할 것입니다. 그리고 당신은 한 내장 이미 사용 준비가 당신을 위해 내장되어 있지만 수정할 수 없습니다.

Uri built = Uri.parse("your URI goes here");

이것은 사용할 준비가되었지만 수정하려면 buildUpon () 해야합니다.

Uri built = Uri.parse("Your URI goes here")
           .buildUpon(); //now it's ready to be modified
           .buildUpon()
           .appendQueryParameter(QUERY_PARAMATER, parameterValue) 
           //any modification you want to make goes here
           .build(); // you have to build it back cause you are storing it 
                     // as Uri not Uri.builder

이제 그것을 수정할 때마다 buildUpon () 및 최종 build ()해야 합니다.

그래서 Uri.Builder는 A는 빌더 그것의 빌더를 저장하는 타입. 열린 우리당은 A는 내장 그 안에 이미 내장 된 URI를 저장하는 유형입니다.

새로운 Uri.Builder (); rerurns 빌더 . Uri.parse ( "your URI goes here")Built을 반환합니다 .

와 함께 빌드 () 당신은에서 변경할 수 있습니다 빌더내장 . buildUpon ()Built 에서 Builder로 변경할 수 있습니다 . 여기 당신이 할 수있는 일이 있습니다

Uri.Builder builder = Uri.parse("URL").buildUpon();
// here you created a builder, made an already built URI with Uri.parse
// and then change it to builder with buildUpon();
Uri built = builder.build();
//when you want to change your URI, change Builder 
//when you want to use your URI, use Built

그리고 그 반대도 :-

Uri built = new Uri.Builder().build();
// here you created a reference to a built URI
// made a builder with new Uri.Builder() and then change it to a built with 
// built();
Uri.Builder builder = built.buildUpon();

내 대답이 도움이 되었기를 바랍니다 :) <3


6

예를 들어 second Answer같은 URL 에이 기술을 사용했습니다.

http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7

Uri.Builder builder = new Uri.Builder();
            builder.scheme("https")
                    .authority("api.openweathermap.org")
                    .appendPath("data")
                    .appendPath("2.5")
                    .appendPath("forecast")
                    .appendPath("daily")
                    .appendQueryParameter("q", params[0])
                    .appendQueryParameter("mode", "json")
                    .appendQueryParameter("units", "metric")
                    .appendQueryParameter("cnt", "7")
                    .appendQueryParameter("APPID", BuildConfig.OPEN_WEATHER_MAP_API_KEY);

그런 다음 건물을 마치면 다음과 URL같이 얻습니다.

URL url = new URL(builder.build().toString());

연결을 엽니 다

  HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

simple예를 들어 링크가 위치 URI와 같은 경우

geo:0,0?q=29203

Uri geoLocation = Uri.parse("geo:0,0?").buildUpon()
            .appendQueryParameter("q",29203).build();

2
URL url = new URL(builder.build().toString());MalformedURLException에 대한 try catch 블록으로 줄 바꿈
Ali Kazi

2

을 (를) 사용 appendEncodePath()하면 여러 줄을 저장할 수 있습니다 appendPath(). 다음 코드 스 니펫은이 URL을 작성합니다.http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043

Uri.Builder urlBuilder = new Uri.Builder();
urlBuilder.scheme("http");
urlBuilder.authority("api.openweathermap.org");
urlBuilder.appendEncodedPath("data/2.5/forecast/daily");
urlBuilder.appendQueryParameter("zip", "94043,us");
URL url = new URL(urlBuilder.build().toString());

2

가장 좋은 답변 : https://stackoverflow.com/a/19168199/413127

 http://api.example.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7

코 틀린과 함께

 val myUrl = Uri.Builder().apply {
        scheme("https")
        authority("www.myawesomesite.com")
        appendPath("turtles")
        appendPath("types")
        appendQueryParameter("type", "1")
        appendQueryParameter("sort", "relevance")
        fragment("section-name")
        build()            
    }.toString()

Kotlin 버전을 추가해 주셔서 감사합니다. :)
M Mansour

0

람다 식으로 할 수 있습니다.

    private static final String BASE_URL = "http://api.example.org/data/2.5/forecast/daily";

    private String getBaseUrl(Map<String, String> params) {
        final Uri.Builder builder = Uri.parse(BASE_URL).buildUpon();
        params.entrySet().forEach(entry -> builder.appendQueryParameter(entry.getKey(), entry.getValue()));
        return builder.build().toString();
    }

그런 매개 변수를 만들 수 있습니다.

    Map<String, String> params = new HashMap<String, String>();
    params.put("zip", "94043,us");
    params.put("units", "metric");

Btw.와 같은 문제가 발생 “lambda expressions not supported at this language level”하면이 URL을 확인하십시오.

https://stackoverflow.com/a/22704620/2057154

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.