2010-04-13 3 views
20

쿼리 문자열이 포함 된 URI를 디코딩해야합니다. 예상 입력/출력 동작은 같은 것입니다 다음Java에서 URI 쿼리 문자열 디코딩

abstract class URIParser 
{  
    /** example input: 
     * something?alias=pos&FirstName=Foo+A%26B%3DC&LastName=Bar */ 
    URIParser(String input) { ... } 
    /** should return "something" for the example input */ 
    public String getPath(); 
    /** should return a map 
     * {alias: "pos", FirstName: "Foo+A&B=C", LastName: "Bar"} */ 
    public Map<String,String> getQuery(); 
} 

을 내가 java.net.URI를 사용하여 시도했지만, 내가 별명 = POS & FIRSTNAME = "왼쪽있어 위의 예에서, 그래서 쿼리 문자열을 디코딩 보인다 Foo + A & B = C & LastName = Bar "이므로"& "이 쿼리 구분 기호인지 쿼리 구성 요소의 문자인지 여부가 모호합니다.

편집 : 난 그냥 URI.getRawQuery()을 시도하고 인코딩을하지 않습니다, 그래서 &와 쿼리 문자열을 분할 할 수 있습니다, 그러나 나는 무엇을해야합니까? Javascript에 decodeURIComponent이 있습니다. 자바에서 해당 메소드를 찾을 수 없습니다.

제안 사항? 나는 새로운 라이브러리를 사용하지 않는 것을 선호한다.

+0

의 대답에 따라 URLDecoder 기능을 래핑하는 도우미 클래스를 만들어

새로운 libs를 소개하기 위해이 URI를받는 환경을 물어봐도 될까요? – stacker

답변

15

참조 클래스 URLDecoder

+4

이 부분을 사용하기 전에 쿼리 부분을 식별하고 매개 변수를 키/값 쌍으로 분할해야하지만 HTML 인코딩에 따라 퍼센트 인코딩 값을 지정된 인코딩 (UTF-8 참조)으로 디코딩해야합니다. application/x-www-form-urlencoded' 스펙을 사용하십시오. – McDowell

53

사용

URLDecoder.decode(proxyRequestParam.replace("+", "%2B"), "UTF-8") 
      .replace("%2B", "+") 

decodeURIComponent을 시뮬레이션 할 수 있습니다. Java의 URLDecoder은 원하는 것이 아닌 더하기 기호를 공백으로 디코딩하므로 replace 문이 필요합니다.

경고 : @xehpuk가 지적한대로 원래 (전 x-www-form-urlencoded를가) 해당 문자열을 포함 경우 데이터 것이다 손상 끝에 .replace("%2B", "+"). + 기호의 문제에 대해서는

+3

이것은 허용 된 대답이어야합니다. URI는 + 기호를 그대로 취급하지만 공백은 % 20으로 인코딩됩니다. + 및 % 20을 공백으로 디코딩하므로 URI 인코딩 된 문자열과 호환되지 않습니다. – Kosta

+3

두 번째 대체 지점은 무엇입니까? 디코딩 후에는 문자열에 "% 2B"의 인스턴스가 더 이상 존재하지 않으므로 "+"로 모두 바뀌므로 바꿀 내용이 없습니다. –

+2

요점은 디코딩 된 문자열에 인코딩 된 문자를 원하지 않는다는 것입니다. Java는 + 기호를 JavaScript로 디코딩하지 않으므로 먼저 + 기호를 인코딩하므로 자바에 의해 처리되지 않고 % 2B를 + 기호로 디코딩합니다. 간단히 말해서 : 이렇게하지 않으면 디코딩 된 URL에 원래 + 기호가 포함되지 않습니다 (Java는 디코딩 단계에서이를 잃어 버렸기 때문에). – janb

0

: 나는 당신이 원하는하지 않기 때문에 @janb

import android.net.Uri; 
import android.support.annotation.Nullable; 
import android.text.TextUtils; 

import java.io.UnsupportedEncodingException; 
import java.net.URLDecoder; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Locale; 

public class DateDecoder { 

    private static final String KEY_DATE = "datekey"; 

    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = 
      new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.US); 


    public static void main(String[] args) throws UnsupportedEncodingException { 
     try { 
      Uri uri = Uri.parse("http://asdf.com?something=12345&" + 
        KEY_DATE +"=2016-12-24T12:00:00+01:00"); 

      System.out.println("parsed date: " + DateDecoder.createDate(uri)); // parsed date: Sat Dec 24 12:00:00 GMT+01:00 2016 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Nullable 
    public static Date createDate(@Nullable Uri data) { 
     if (data != null) { 
      try { 
       String withPlus = decodeButKeepPlus(KEY_DATE, data.getEncodedQuery()); 
       if (!TextUtils.isEmpty(withPlus)) { 
        return SIMPLE_DATE_FORMAT.parse(withPlus); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     return null; 
    } 

    /** 
    * copied from android.net.Uri.java 
    */ 
    @Nullable 
    public static String decodeButKeepPlus(String encodedKey, String completeEncodedQuery) 
      throws UnsupportedEncodingException { 

     final int length = completeEncodedQuery.length(); 
     int start = 0; 
     do { 
      int nextAmpersand = completeEncodedQuery.indexOf('&', start); 
      int end = nextAmpersand != -1 ? nextAmpersand : length; 

      int separator = completeEncodedQuery.indexOf('=', start); 
      if (separator > end || separator == -1) { 
       separator = end; 
      } 

      if (separator - start == encodedKey.length() 
        && completeEncodedQuery.regionMatches(start, encodedKey, 0, encodedKey.length())) { 
       if (separator == end) { 
        return ""; 
       } else { 
        String encodedValue = completeEncodedQuery.substring(separator + 1, end); 
        if (!TextUtils.isEmpty(encodedValue)) { 
         return URLDecoder.decode(encodedValue.replace("+", "%2B"), "UTF-8").replace("%2B", "+"); 
        } 
       } 
      } 

      // Move start to end of name. 
      if (nextAmpersand != -1) { 
       start = nextAmpersand + 1; 
      } else { 
       break; 
      } 
     } while (true); 
     return null; 
    } 

} 
1
var reqParam = URLDecoder.decode(reqParam, "UTF-8")