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;
}
'developer tip' 카테고리의 다른 글
시간 부분을 무시하고 T-SQL에서 날짜 비교 (0) | 2020.11.30 |
---|---|
하나의 작업에 대한 컨트롤러 AuthorizeAttribute 재정의 (0) | 2020.11.30 |
R의 모형 행렬에있는 요인의 모든 수준 (0) | 2020.11.30 |
node.js에서 마지막으로 수정 된 파일 날짜 (0) | 2020.11.30 |
iOS 창의 루트 뷰 컨트롤러 변경 (0) | 2020.11.30 |