developer tip

Android : 공백이있는 URL 문자열을 URI 객체로 구문 분석하는 방법은 무엇입니까?

optionbox 2020. 11. 30. 08:04
반응형

Android : 공백이있는 URL 문자열을 URI 객체로 구문 분석하는 방법은 무엇입니까?


공백이 포함 된 URL을 나타내는 문자열이 있고이를 URI 개체로 변환하고 싶습니다. 단순히 다음을 통해 만들려고하면

String myString = "http://myhost.com/media/File Name that has spaces inside.mp3";
URI myUri = new URI(myString);

그것은 나에게 준다

java.net.URISyntaxException: Illegal character in path at index X

여기서 index X는 URL 문자열에서 첫 번째 공백의 위치입니다.

객체 myString어떻게 구문 분석 할 수 URI있습니까?


실제로 "잘못된"문자를 URI 인코딩 해야 합니다. 문자열에는 실제로 전체 URL이 포함되어 있으므로 제대로 URI 인코딩하기가 어렵습니다. 어떤 슬래시를 /고려해야 하는지, 어떤 것을 고려 하지 않아야하는지 모릅니다 . 원시에서 String미리 예측할 수 없습니다 . 문제는 실제로 더 높은 수준에서 해결되어야합니다. 그게 String어디에서 왔습니까? 하드 코딩 되었습니까? 그런 다음 그에 따라 직접 변경하십시오. 사용자 입력으로 제공됩니까? 그것을 확인하고 오류를 표시하고 사용자가 스스로 해결하도록합니다.

어떤 식 으로든 URL의 공백으로 유효하게 만드는 것을 확인할 수 있다면 문자열 단위로 %20다음 같이 바꿀 수도 있습니다 .

URI uri = new URI(string.replace(" ", "%20"));

또는 URI 인코딩이 필요한 마지막 슬래시 뒤의 부분 확인할 수있는 경우 android.net.Uri유틸리티 클래스 사용 하여 그렇게 할 수도 있습니다 .

int pos = string.lastIndexOf('/') + 1;
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos)));

규칙에 따라 URLEncoder쿼리 문자열 매개 변수 이름 / 값을 인코딩하도록 설계되었으므로 작업에 적합 하지 않습니다 application/x-www-form-urlencoded(HTML 양식에서 사용됨). 쿼리 문자열 매개 변수의 Java URL 인코딩을 참조하십시오 .


java.net.URLEncoder.encode(finalPartOfString, "utf-8");

이것은 문자열을 URL 인코딩 합니다.

finalPartOfString 마지막 슬래시 뒤의 부분입니다. 귀하의 경우에는 노래 이름이 보입니다.


URL url = Test.class.getResource(args[0]);  // reading demo file path from                                                   
                                            // same location where class                                    
File input=null;
try {
    input = new File(url.toURI());
} catch (URISyntaxException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

URL 경로의 임의 위치에서 공백, @ 및 기타 안전하지 않은 문자를 처리하려면 여기에서 설명한대로 URL의 로컬 인스턴스와 함께 Uri.Builder를 사용 합니다 .

private Uri.Builder builder;
public Uri getUriFromUrl(String thisUrl) {
    URL url = new URL(thisUrl);
    builder =  new Uri.Builder()
                            .scheme(url.getProtocol())
                            .authority(url.getAuthority())
                            .appendPath(url.getPath());
    return builder.build();
}

이 함수를 작성했습니다.

public static String encode(@NonNull String uriString) {
    if (TextUtils.isEmpty(uriString)) {
        Assert.fail("Uri string cannot be empty!");
        return uriString;
    }
    // getQueryParameterNames is not exist then cannot iterate on queries
    if (Build.VERSION.SDK_INT < 11) {
        return uriString;
    }

    // Check if uri has valid characters
    // See https://tools.ietf.org/html/rfc3986
    Pattern allowedUrlCharacters = Pattern.compile("([A-Za-z0-9_.~:/?\\#\\[\\]@!$&'()*+,;" +
            "=-]|%[0-9a-fA-F]{2})+");
    Matcher matcher = allowedUrlCharacters.matcher(uriString);
    String validUri = null;
    if (matcher.find()) {
        validUri = matcher.group();
    }
    if (TextUtils.isEmpty(validUri) || uriString.length() == validUri.length()) {
        return uriString;
    }

    // The uriString is not encoded. Then recreate the uri and encode it this time
    Uri uri = Uri.parse(uriString);
    Uri.Builder uriBuilder = new Uri.Builder()
            .scheme(uri.getScheme())
            .authority(uri.getAuthority());
    for (String path : uri.getPathSegments()) {
        uriBuilder.appendPath(path);
    }
    for (String key : uri.getQueryParameterNames()) {
        uriBuilder.appendQueryParameter(key, uri.getQueryParameter(key));
    }
    String correctUrl = uriBuilder.build().toString();
    return correctUrl;
}

참고URL : https://stackoverflow.com/questions/2593214/android-how-to-parse-url-string-with-spaces-to-uri-object

반응형