Android에서 쿼리 문자열 구문 분석


271

Java EE에는 ServletRequest.getParameterValues ​​()가 있습니다.

비 EE 플랫폼에서 URL.getQuery ()는 단순히 문자열을 반환합니다.

Java EE에 있지 않을 때 URL에서 쿼리 문자열을 올바르게 구문 분석하는 일반적인 방법은 무엇입니까 ?


< 랜트 >

자신의 파서를 시도하고 만드는 대답에서 인기가 있습니다. 이것은 매우 재미 있고 흥미 진진한 마이크로 코딩 프로젝트이지만, 나는 그것이 좋은 생각이라고 말할 수 없습니다 :(

아래 코드 스 니펫은 일반적으로 결함이 있거나 끊어집니다 (btw). 그것들을 깨는 것은 독자에게 흥미로운 연습입니다. 그리고 해커들은이를 사용하는 웹 사이트를 공격합니다 .

쿼리 문자열 구문 분석은 잘 정의 된 문제이지만 사양을 읽고 뉘앙스를 이해하는 것은 쉽지 않습니다. 일부 플랫폼 라이브러리 코더가 열심히 작업하고 수정 작업을 수행하는 것이 훨씬 좋습니다!

< / rant >


샘플 URL, 가져 오는 getQuery()내용 및 출력으로 가져 오려는 내용을 게시 할 수 있습니까?
토마스 오웬스

1
서블릿 또는 JSP 페이지에서이 작업을 수행 하시겠습니까? 대답하기 전에 설명이 필요합니다.
ChadNC

1
POST 매개 변수를 구문 분석해야합니까?
Thilo November

2
J2EE (또는 OSGi를 통해 선택된 EE 패키지가있는 SE)에 있더라도이 질문은 의미가 있습니다. 필자의 경우 쿼리 문자열 / url로 인코딩 된 POST 본문은 의도적으로에 관계없이 시스템의 일부에 의해 처리됩니다 ServletRequest.
한노 피츠

61
<rant />에 대해 찬성했습니다!
Nowaker

답변:


65

Android M 이후 더 복잡해졌습니다. android.net.URI .getQueryParameter () 의 대답은 JellyBean 앞의 공백을 깨는 버그가 있습니다. Apache URLEncodedUtils.parse () 는 작동했지만 L 에서는 더 이상 사용되지 않으며 M 에서는 제거되었습니다 .

따라서 가장 좋은 대답은 UrlQuerySanitizer 입니다. API 레벨 1부터 존재했지만 여전히 존재합니다. 또한 특수 문자 또는 반복되는 값을 처리하는 방법과 같은 까다로운 문제에 대해 생각하게합니다.

가장 간단한 코드는

UrlQuerySanitizer.ValueSanitizer sanitizer = UrlQuerySanitizer.getAllButNullLegal();
// remember to decide if you want the first or last parameter with the same name
// If you want the first call setPreferFirstRepeatedParameter(true);
sanitizer.parseUrl(url);
String value = sanitizer.getValue("paramName"); // get your value

기본 구문 분석 동작에 만족하면 다음을 수행 할 수 있습니다.

new UrlQuerySanitizer(url).getValue("paramName")

그러나 기본 구문 분석 동작이 무엇인지 이해해야합니다. 원하는 동작이 아닐 수도 있습니다.


4
URLQuerySanitizer.getAllButNullLegal ()은 UrlQuerySanitizer가 아닌 UrlQuerySanitizer.ValueSanitizer를 리턴합니다.
피터 자오

31
어떤 이유로 위의 작업이 저에게 효과가 없었기 때문에 약간 수정해야했습니다.UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ

3
작동하지. UrlQuerySanitizer sdk-23에는 단 하나의 방법이 있습니다sanitize()
Ninja

특수 문자와 이모티콘을로 해독합니다 _. 나는 stackoverflow.com/a/35638979/1155282
Irshu

이것의 스프링 프레임 워크와 동등한 라이브러리가 있습니까?
iamjoshua

202

안드로이드 :

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");

20
이것은 URI 클래스가 아닌 Uri 클래스를 사용합니다 (Uri는 android.net의 일부이고 URI는 java.net의 일부 임)
Marius

5
또한 Ice Cream Sandwich 이전에는 값의 + 문자를 공백 문자로 구문 분석하지 못합니다.
rpetrich 20시 51 분

@rpetrich는 실제로 문서에 따르면 아이스크림 샌드위치를 ​​포함하여 버그가 젤리 빈보다 먼저 있다고 말합니다. ref
Big McLargeHuge

64

9
이것은 Android뿐만 아니라 apache http 클라이언트 라이브러리에서 사용할 수 있습니다. Btw, 아파치 링크가 변경되었습니다. 최신 : hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Cristian Vrabie

9
성가신 것은 특정 키의 값을 찾기 위해 반복해야한다는 것을 URLEncodedUtils.parse()반환합니다 List. MapBalusC의 답변에서 같은 것을 반환하면 훨씬 좋을 것입니다.
Asaph

1
@ Hanno Fietz 당신은 이러한 대안 을 신뢰 한다는 의미 입니까? 나는 그들이 버그가 있다는 것을 안다. 내가 본 버그를 지적하면 사람들이 내가 간과 한 버그를 찾는 것이 아니라 '수정 된'버전을 채택하도록 장려한다는 것을 알고 있습니다.
Will

1
@ 윌-글쎄, 나는 웹 사이트에서 얻은 복사하여 붙여 넣기 스 니펫을 절대 신뢰할 수 없으며 아무도해서는 안됩니다. 그러나 여기서는이 스 니펫을 검토하고 주석을 달았으므로 are실제로 도움이됩니다. 코드에서 무엇이 잘못되었는지에 대한 제안보는 것만 으로도 저 자신을 생각하는 데 큰 도움이됩니다. 그리고 "당신 자신의 롤이 더 낫다"고 말하는 것이 아니라 내 자신의 코드에 따라 결정을 내릴 수있는 좋은 자료를 갖는 것이 좋습니다.
Hanno Fietz

8
구문 분석은 위치 순서를 유지하고 더 쉽게 중복 항목을 허용하도록 목록을 반환한다고 상상합니다.
dhaag23

26

다음은 BalusC의 답변 이지만 컴파일하고 결과를 반환합니다.

public static Map<String, List<String>> getUrlParameters(String url)
        throws UnsupportedEncodingException {
    Map<String, List<String>> params = new HashMap<String, List<String>>();
    String[] urlParts = url.split("\\?");
    if (urlParts.length > 1) {
        String query = urlParts[1];
        for (String param : query.split("&")) {
            String pair[] = param.split("=");
            String key = URLDecoder.decode(pair[0], "UTF-8");
            String value = "";
            if (pair.length > 1) {
                value = URLDecoder.decode(pair[1], "UTF-8");
            }
            List<String> values = params.get(key);
            if (values == null) {
                values = new ArrayList<String>();
                params.put(key, values);
            }
            values.add(value);
        }
    }
    return params;
}

1
JVM 참고 : Java Collections를 사용하여 Scala에서 이와 동등한 형식을 구현했습니다. 여기 github 요지가 있습니다 : gist.github.com/3504765
Jay Taylor

2
I는 변경 제안 String pair[] = param.split("=");으로 String pair[] = param.split("=", 2);만에 처음 키 = 값 쌍을 분할. 나는 값에 인코딩되지 않은 등호를 가질 수 있다고 생각합니다.
데니

22

클래스 경로에 jetty (서버 또는 클라이언트) 라이브러리가있는 경우 jetty util 클래스 ( javadoc 참조 )를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

import org.eclipse.jetty.util.*;
URL url = new URL("www.example.com/index.php?foo=bar&bla=blub");
MultiMap<String> params = new MultiMap<String>();
UrlEncoded.decodeTo(url.getQuery(), params, "UTF-8");

assert params.getString("foo").equals("bar");
assert params.getString("bla").equals("blub");

13

Spring 3.1 이상을 사용하는 경우 (좋아요, 지원이 더 나아지기를 바랐습니다) UriComponentsand UriComponentsBuilder:

UriComponents components = UriComponentsBuilder.fromUri(uri).build();
List<String> myParam = components.getQueryParams().get("myParam");

components.getQueryParams() 를 반환 MultiValueMap<String, String>

더 많은 문서가 있습니다.


이것은 내가 찾고있는 것입니다. 내 질문은 어떻게 uri를 얻습니까? 나는 많이 변경할 수없는 코드 유지 관리에 갇혀 있으며 HttpServlet을 사용하지 않습니다. 대신 주석과 Spring (@Get, @Produces (mediaType) 및 @Path ( "/ dataAsJSON / datafield / {datafield}))을 사용하면 쿼리 문자열을 가져 오는 방법을 알아야하므로 다음과 같이 구문 분석 할 수 있습니다 이 예.
Nelda.techspiress

5

서블릿 또는 JSP 페이지의 경우 request.getParameter ( "paramname")을 사용하여 쿼리 문자열 키 / 값 쌍을 얻을 수 있습니다.

String name = request.getParameter("name");

다른 방법이 있지만 내가 만든 모든 서블릿 및 jsp 페이지에서 수행하는 방식입니다.


3
HttpServletRequest는 J2EE에 포함되어 있지 않습니다. 또한 getParamter ()를 사용하는 것은 실제로 구문 분석되지 않습니다.
Mr. Shiny and New 安 宇

3
시간을내어 그의 질문에 대한 설명을 요청한 의견을 읽으십시오. 이 답변은 "Android에서이 작업을 시도하고 있지만 모든 플랫폼의 모든 답변은 포인터를 제공하는 유용한 답변이 될 것입니다. 질문) 잠깐만 기다리세요! " 나는 그 의견에 근거하여 그의 질문에 대답했다. 추가하기에 유용한 것이 없다면 아무 것도 추가하지 마십시오
ChadNC

1
너무 화 내지 마십시오. "이것은 질문에 대답하지 않습니다"는 IMO를 추가하는 데 유용합니다.
Mr. Shiny and New 安 宇

1
안드로이드에 상관없이 문제는 URL을 포함하는 문자열을 구문 분석하고 URL 매개 변수를 얻는 방법입니다. 여기서 포팅하는 것은 서블릿 컨테이너가 HTTP 요청에서 들어오는 매개 변수를 구문 분석하는 서블릿 API의 일부입니다. 질문은 HTTP 요청이 아닌 URL을 포함하고 서블릿 컨테이너 내부가 아닌 문자열을 구문 분석하는 것에 관한 것이므로 관련이 없습니다.
mvmn

5

안드로이드에, 나는 @diyism 응답을 사용하여 시도하지만, 예를 들어 @rpetrich에 의해 제기 된 공백 문자 문제가 발생했습니다 나는 양식을 작성 곳 username = "us+us"password = "pw pw"같은 모습에 URL 문자열을 일으키는 :

http://somewhere?username=us%2Bus&password=pw+pw

그러나 @diyism 코드를 반환 "us+us"하고 "pw+pw",이 공백 문자를 감지하지 않습니다 즉. %20공백 문자로 URL을 다시 쓴 경우 :

http://somewhere?username=us%2Bus&password=pw%20pw

이것은 다음 수정으로 이어집니다.

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");

replace(" ", "%20")이것은 잘못된 느낌입니다. 그러나 나를 위해 트릭을 했어 : D
Mārtiņš Briedis

올바른 구문은 "일부 문자열"이어야합니다. replaceAll ( "[+]", "% 20");
RRTW

4

쿼리 문자열을 구문 분석하는 것은 원하는 용서에 따라 보이는 것보다 조금 더 복잡합니다.

먼저 쿼리 문자열은 ASCII 바이트입니다. 이 바이트를 한 번에 하나씩 읽고 문자로 변환하십시오. 문자가? 또는 & 다음 매개 변수 이름의 시작을 알립니다. 문자가 =이면 매개 변수 값의 시작을 나타냅니다. 문자가 %이면 인코딩 된 바이트의 시작을 알립니다. 여기 까다로운 곳이 있습니다.

% 문자를 읽을 때는 다음 두 바이트를 읽고 16 진수로 해석해야합니다. 즉, 다음 두 바이트는 0-9, af 또는 AF가됩니다. 이 두 16 진수를 함께 붙이면 바이트 값을 얻을 수 있습니다. 그러나 바이트는 문자가 아닙니다. . 문자를 인코딩하는 데 사용 된 인코딩을 알아야합니다. 문자 é는 ISO-8859-1에서와 동일하게 UTF-8로 인코딩하지 않습니다. 일반적으로 주어진 문자 집합에 어떤 인코딩이 사용되었는지 알 수 없습니다. 내 웹 사이트는 항상 UTF-8을 사용하여 모든 것을 제공하도록 구성되어 있기 때문에 항상 UTF-8을 사용하지만 실제로는 확실하지 않습니다. 일부 사용자 에이전트는 요청에서 문자 인코딩을 알려줍니다. 전체 HTTP 요청이있는 경우이를 읽으려고 시도 할 수 있습니다. URL이 격리되어 있다면 행운을 빕니다.

어쨌든 UTF-8 또는 다른 멀티 바이트 문자 인코딩을 사용한다고 가정하면 인코딩 된 바이트 하나를 디코딩 했으므로 다음 바이트를 캡처 할 때까지 따로 설정해야합니다. 한 번에 한 바이트 씩 올바르게 URL 디코딩 할 수 없으므로 함께 인코딩 된 모든 바이트가 필요합니다. 함께있는 모든 바이트를 따로두고 한 번에 모두 디코딩하여 캐릭터를 재구성하십시오.

또한 관대하고 URL을 조작하는 사용자 에이전트를 설명하려는 경우 더 재미있어집니다. 예를 들어, 일부 웹 메일 클라이언트는 이중 인코딩을합니다. 또는? & = 문자를 두 배로 늘리십시오 (예 :) http://yoursite.com/blah??p1==v1&&p2==v2. 이것을 올바르게 처리하려면 파서에 더 많은 논리를 추가해야합니다.


쿼리 문자열 매개 변수 값을 구문 분석하거나 검색하는 방법에 대해서는 설명하지 않습니다.
ChadNC

맞지만 조금 성가시다. 이를 위해 이미 URLDecoder가 있습니다.
BalusC 2009

2
@ChadNC : 세 번째 문장은 구문 분석하는 방법을 알려줍니다. 한 번에 한 바이트 씩 읽고 문자로 변환합니다. 네 번째 문장은 특별한 문자에 대해 경고합니다. 기타 대답을 읽지 않았습니까?
Mr. Shiny and New 安 宇

@BalusC : URLDecoder는 작동하지만 어떤 종류의 URL을 허용하는 데 더 관대하려고하면 실패 모드가 있습니다.
Mr. Shiny and New 安 宇

1
@ Mr.ShinyAndNew 구문 분석 쿼리 매개 변수에 동의하는 것은 쉽지 않습니다. 나는 FIQL을 지원하고 있으며 이것은 엉덩이에 진정한 고통이됩니다. 예 : yoursite.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira 06:11의

4

안드로이드에서는 아래 코드와 같이 간단합니다.

UrlQuerySanitizer sanitzer = new UrlQuerySanitizer(url);
String value = sanitzer.getValue("your_get_parameter");

또한 각 예상 쿼리 키를 등록하지 않으려면 다음을 사용하십시오.

sanitzer.setAllowUnregisteredParamaters(true)

전화하기 전에 :

sanitzer.parseUrl(yourUrl)

4

이것을 달성하는 방법이 있습니다.

1) :

public static String getQueryString(String url, String tag) {
    String[] params = url.split("&");
    Map<String, String> map = new HashMap<String, String>();
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }

    Set<String> keys = map.keySet();
    for (String key : keys) {
        if(key.equals(tag)){
         return map.get(key);
        }
        System.out.println("Name=" + key);
        System.out.println("Value=" + map.get(key));
    }
    return "";
}

2) 그리고 Uri 클래스를 사용하여 이것을 수행하는 가장 쉬운 방법 :

public static String getQueryString(String url, String tag) {
    try {
        Uri uri=Uri.parse(url);
        return uri.getQueryParameter(tag);
    }catch(Exception e){
        Log.e(TAG,"getQueryString() " + e.getMessage());
    }
    return "";
}

다음은 두 가지 방법 중 하나를 사용하는 방법의 예입니다.

String url = "http://www.jorgesys.com/advertisements/publicidadmobile.htm?position=x46&site=reform&awidth=800&aheight=120";      
String tagValue = getQueryString(url,"awidth");

tagValue의 값은 800


3

Android에서는 android.net.Uri 클래스 의 Uri.parse 정적 메소드를 사용 하여 무거운 작업을 수행 할 수 있습니다 . URI와 의도로 무언가를하고 있다면 어쨌든 그것을 사용하고 싶을 것입니다.


3

참고로 이것은 URLEncodedUtils를 기반으로하고 맵을 반환하는 결과입니다.

풍모:

  • URL의 쿼리 문자열 부분을 받아들입니다. request.getQueryString() )
  • 빈 쿼리 문자열은 빈을 생성합니다 Map
  • 값이없는 매개 변수 (? test)는 비어있는 것으로 매핑됩니다. List<String>

암호:

public static Map<String, List<String>> getParameterMapOfLists(String queryString) {
    Map<String, List<String>> mapOfLists = new HashMap<String, List<String>>();
    if (queryString == null || queryString.length() == 0) {
        return mapOfLists;
    }
    List<NameValuePair> list = URLEncodedUtils.parse(URI.create("http://localhost/?" + queryString), "UTF-8");
    for (NameValuePair pair : list) {
        List<String> values = mapOfLists.get(pair.getName());
        if (values == null) {
            values = new ArrayList<String>();
            mapOfLists.put(pair.getName(), values);
        }
        if (pair.getValue() != null) {
            values.add(pair.getValue());
        }
    }

    return mapOfLists;
}

호환성 도우미 (값은 ServletRequest.getParameterMap () 에서와 마찬가지로 문자열 배열에 저장 ) :

public static Map<String, String[]> getParameterMap(String queryString) {
    Map<String, List<String>> mapOfLists = getParameterMapOfLists(queryString);

    Map<String, String[]> mapOfArrays = new HashMap<String, String[]>();
    for (String key : mapOfLists.keySet()) {
        mapOfArrays.put(key, mapOfLists.get(key).toArray(new String[] {}));
    }

    return mapOfArrays;
}

3

이것은 나를 위해 작동합니다. 왜 모든 사람들이 Map, List>를 따랐는지 모르겠습니다.

일을 단순하게 유지하기 위해 URI.getQuery ();

public static Map<String, String> getUrlParameters(URI uri)
    throws UnsupportedEncodingException {
    Map<String, String> params = new HashMap<String, String>();
    for (String param : uri.getQuery().split("&")) {
        String pair[] = param.split("=");
        String key = URLDecoder.decode(pair[0], "UTF-8");
        String value = "";
        if (pair.length > 1) {
            value = URLDecoder.decode(pair[1], "UTF-8");
        }
        params.put(new String(key), new String(value));
    }
    return params;
}

1
다중 선택이 가능한 양식은 어떻습니까? 합법적 인 쿼리 문자열 (및 POST 양식 본문)에서 키를 반복하는 것이 완벽합니다. 다루지 않은 다른 결함 및 코너 케이스가 있습니다. 그들 중 많은 사람들이 다른 접근법에 대한 논평에서 언급되었습니다. 나는 질문에 내 욕망 에 따라 양질의 라이브러리를 사용하는 대신 그것을 고치는 것을 두려워하여 그것들을 지적하는 양식을 삼가 할 것입니다 .)
Will

2

구아바의 멀티 맵이 더 적합합니다. 다음은 깨끗하고 짧은 버전입니다.

Multimap<String, String> getUrlParameters(String url) {
        try {
            Multimap<String, String> ret = ArrayListMultimap.create();
            for (NameValuePair param : URLEncodedUtils.parse(new URI(url), "UTF-8")) {
                ret.put(param.getName(), param.getValue());
            }
            return ret;
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

1

1

Origanally 여기에 대답

안드로이드에는 android.net 패키지에 Uri 클래스가 있습니다 있습니다. URI는 android.net의 일부이고 URI는 java.net의 일부입니다.

Uri 클래스에는 쿼리 키-값 쌍을 추출하는 많은 기능이 있습니다. 여기에 이미지 설명을 입력하십시오

다음 함수는 키-값 쌍을 HashMap 형식으로 반환합니다.

자바에서 :

Map<String, String> getQueryKeyValueMap(Uri uri){
    HashMap<String, String> keyValueMap = new HashMap();
    String key;
    String value;

    Set<String> keyNamesList = uri.getQueryParameterNames();
    Iterator iterator = keyNamesList.iterator();

    while (iterator.hasNext()){
        key = (String) iterator.next();
        value = uri.getQueryParameter(key);
        keyValueMap.put(key, value);
    }
    return keyValueMap;
}

코 틀린에서 :

fun getQueryKeyValueMap(uri: Uri): HashMap<String, String> {
        val keyValueMap = HashMap<String, String>()
        var key: String
        var value: String

        val keyNamesList = uri.queryParameterNames
        val iterator = keyNamesList.iterator()

        while (iterator.hasNext()) {
            key = iterator.next() as String
            value = uri.getQueryParameter(key) as String
            keyValueMap.put(key, value)
        }
        return keyValueMap
    }

0

JRE에는 하나도 없다고 생각합니다. Apache HttpClient와 같은 다른 패키지에서도 비슷한 기능을 찾을 수 있습니다. 다른 패키지를 사용하지 않으면 직접 작성해야합니다. 그렇게 어렵지 않습니다. 여기 내가 사용하는 것이 있습니다.

public class QueryString {

 private Map<String, List<String>> parameters;

 public QueryString(String qs) {
  parameters = new TreeMap<String, List<String>>();

  // Parse query string
     String pairs[] = qs.split("&");
     for (String pair : pairs) {
            String name;
            String value;
            int pos = pair.indexOf('=');
            // for "n=", the value is "", for "n", the value is null
         if (pos == -1) {
          name = pair;
          value = null;
         } else {
       try {
        name = URLDecoder.decode(pair.substring(0, pos), "UTF-8");
              value = URLDecoder.decode(pair.substring(pos+1, pair.length()), "UTF-8");            
       } catch (UnsupportedEncodingException e) {
        // Not really possible, throw unchecked
           throw new IllegalStateException("No UTF-8");
       }
         }
         List<String> list = parameters.get(name);
         if (list == null) {
          list = new ArrayList<String>();
          parameters.put(name, list);
         }
         list.add(value);
     }
 }

 public String getParameter(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  if (values.size() == 0)
   return "";

  return values.get(0);
 }

 public String[] getParameterValues(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  return (String[])values.toArray(new String[values.size()]);
 }

 public Enumeration<String> getParameterNames() {  
  return Collections.enumeration(parameters.keySet()); 
 }

 public Map<String, String[]> getParameterMap() {
  Map<String, String[]> map = new TreeMap<String, String[]>();
  for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
   List<String> list = entry.getValue();
   String[] values;
   if (list == null)
    values = null;
   else
    values = (String[]) list.toArray(new String[list.size()]);
   map.put(entry.getKey(), values);
  }
  return map;
 } 
}

아파치 수업은 어떻습니까?
Will

1
: 당신은 구문 분석 () 메소드를 사용할 수 있습니다 hc.apache.org/httpcomponents-client/httpclient/apidocs/org/...
ZZ 코더

3
투표 할 수 있도록 아파치 커먼즈 링크를 자체 답변에 넣으십시오.
itsadok

0

BalusC의 답변을 바탕으로 몇 가지 Java 코드 예제를 작성했습니다.

    if (queryString != null)
    {
        final String[] arrParameters = queryString.split("&");
        for (final String tempParameterString : arrParameters)
        {
            final String[] arrTempParameter = tempParameterString.split("=");
            if (arrTempParameter.length >= 2)
            {
                final String parameterKey = arrTempParameter[0];
                final String parameterValue = arrTempParameter[1];
                //do something with the parameters
            }
        }
    }

0
public static Map <String, String> parseQueryString (final URL url)
        throws UnsupportedEncodingException
{
    final Map <String, String> qps = new TreeMap <String, String> ();
    final StringTokenizer pairs = new StringTokenizer (url.getQuery (), "&");
    while (pairs.hasMoreTokens ())
    {
        final String pair = pairs.nextToken ();
        final StringTokenizer parts = new StringTokenizer (pair, "=");
        final String name = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        final String value = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        qps.put (name, value);
    }
    return qps;
}


0

구아바 사용하기 :

Multimap<String,String> parseQueryString(String queryString, String encoding) {
    LinkedListMultimap<String, String> result = LinkedListMultimap.create();

    for(String entry : Splitter.on("&").omitEmptyStrings().split(queryString)) {
        String pair [] = entry.split("=", 2);
        try {
            result.put(URLDecoder.decode(pair[0], encoding), pair.length == 2 ? URLDecoder.decode(pair[1], encoding) : null);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    return result;
}

0

이것은 인기있는 스레드이기 때문에 여기에 대답하십시오. 이것은 권장 UrlQuerySanitizerAPI 를 사용하는 Kotlin의 깨끗한 솔루션입니다 . 공식 문서를 참조하십시오 . 매개 변수를 연결하고 표시하기 위해 문자열 작성기를 추가했습니다.

    var myURL: String? = null
    // if the url is sent from a different activity where you set it to a value
    if (intent.hasExtra("my_value")) {
        myURL = intent.extras.getString("my_value")
    } else {
        myURL = intent.dataString
    }

    val sanitizer = UrlQuerySanitizer(myURL)
    // We don't want to manually define every expected query *key*, so we set this to true
    sanitizer.allowUnregisteredParamaters = true
    val parameterNamesToValues: List<UrlQuerySanitizer.ParameterValuePair> = sanitizer.parameterList
    val parameterIterator: Iterator<UrlQuerySanitizer.ParameterValuePair> = parameterNamesToValues.iterator()

    // Helper simply so we can display all values on screen
    val stringBuilder = StringBuilder()

    while (parameterIterator.hasNext()) {
        val parameterValuePair: UrlQuerySanitizer.ParameterValuePair = parameterIterator.next()
        val parameterName: String = parameterValuePair.mParameter
        val parameterValue: String = parameterValuePair.mValue

        // Append string to display all key value pairs
        stringBuilder.append("Key: $parameterName\nValue: $parameterValue\n\n")
    }

    // Set a textView's text to display the string
    val paramListString = stringBuilder.toString()
    val textView: TextView = findViewById(R.id.activity_title) as TextView
    textView.text = "Paramlist is \n\n$paramListString"

    // to check if the url has specific keys
    if (sanitizer.hasParameter("type")) {
        val type = sanitizer.getValue("type")
        println("sanitizer has type param $type")
    }

-2

이 메소드는 par 이름과 par 값의 URI 및 리턴 맵을 사용합니다.

  public static Map<String, String> getQueryMap(String uri) {

    String queryParms[] = uri.split("\\?");

    Map<String, String> map = new HashMap<>();// 

    if (queryParms == null || queryParms.length == 0) return map;

    String[] params = queryParms[1].split("&");
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }
    return map;
}

1
위의 내 폭언에 따르면, 이것은 사소하게 충돌 할 수 있습니다. 고정을 방해하지 말고 전문 유틸리티 라이브러리를 사용하십시오.
Will

-3

"Java"라고 말하지만 "Java EE"는 아닙니다. JSP 및 / 또는 서블릿을 사용하고 있지만 전체 Java EE 스택을 사용하고 있지 않습니까? 이 경우 여전히 request.getParameter ()를 사용할 수 있어야합니다.

Java를 작성하고 있지만 JSP 또는 서블릿을 작성하지 않거나 Java를 참조 지점으로 사용하고 있지만 내장 매개 변수 구문 분석 기능이없는 다른 플랫폼을 사용하고 있음을 의미한다면 ... 와우 , 그것은 가능성이 거의없는 질문처럼 들리지만, 그렇다면 원칙은 다음과 같습니다.

xparm=0
word=""
loop
  get next char
  if no char
    exit loop
  if char=='='
    param_name[xparm]=word
    word=""
  else if char=='&'
    param_value[xparm]=word
    word=""
    xparm=xparm+1
  else if char=='%'
    read next two chars
    word=word+interpret the chars as hex digits to make a byte
  else
    word=word+char

(Java 코드를 작성할 수는 있지만 의미가 없습니다. Java를 사용할 수 있으면 request.getParameters 만 사용할 수 있기 때문입니다.)


16 진 숫자를 URL 디코딩 할 때 문자 인코딩을주의하십시오.
Mr. Shiny and New 安 宇

Android이므로 Java이지만 J2EE는 아닙니다.
Andrzej Doyle

언급을 잊어 버렸습니다. 또한 공백으로 변환해야하는 "+"도 확인해야합니다. 쿼리 문자열에서 포함 된 공백은 유효하지 않습니다.
Jay
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.