'장시간 독자, 처음 포스터'는 여기에 있습니다.HttpClient 및 비 ASCII URL 문자 (á, é, í, ó, ú)
내가 관리하는 스페인어 위키에 대해 bot을 만드는 중입니다. 저는 처음부터 그것을 만들고 싶었습니다. 저의 목적 중 하나는 자바를 연습하는 것이 었습니다. 그러나 HttpClient를 사용하여 GET 요청을 á, é, í, ó 또는 ú와 같은 비 ASCII 문자가 포함 된 URI로 만들려고 할 때 문제가 발생했습니다. 스택 트레이스에 도시 된 URI에 공간 %20
로 부호화되었는지
Exception in thread "main" java.lang.IllegalArgumentException: Invalid uri 'http://es.pruebaloca.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Categoría:Mejoras%20de%20las%20Botas&cmlimit=500&format=xml': Invalid query
at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222)
at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)
at net.metroidover.categorybot.http.HttpRequest.request(HttpRequest.java:69)
at net.metroidover.categorybot.http.HttpRequest.request(HttpRequest.java:120)
at net.metroidover.categorybot.http.Action.getCategoryMembers(Action.java:38)
at net.metroidover.categorybot.bot.BotComponent.<init>(BotComponent.java:58)
at net.metroidover.categorybot.bot.BotComponent.main(BotComponent.java:80)
참고하고 그대로 í
들 남아 :
String url = "http://es.metroid.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Categoría:Mejoras de las Botas"
method = new GetMethod(url);
client.executeMethod(method);
I 위 이렇게하면 getMethod 메소드는 URI 뿌려 . 정확히 똑같은 URI가 브라우저에서 완벽하게 작동하지만 GetMethod를 받아 들일 수는 없습니다. URI
가 i
의 탈출,
URI uri = new URI(url, false);
method = new GetMethod(uri.getEscapedURI());
client.executeMethod(method);
이 방법하지만, 이중 경우, 지금 공간 (%2520
) ...
http://es.metroid.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Categor%C3%ADa:Mejoras%2520de%2520las%2520Botas&cmlimit=500&format=xml
탈출 :
은 또한 다음을 수행하려고했습니다 쿼리에서 공백을 사용하지 않고 이중 이스케이프가 없으며 원하는 출력을 얻습니다. 따라서 ASCII 문자가 아닌 문자가 없으면URI
클래스를 사용할 필요가 없으며 이중 이스케이프 처리를하지 못합니다. 공간의 첫 번째 탈출을 방지하기위한 시도로,이 시도 :
URI uri = new URI(url, true);
method = new GetMethod(uri.getEscapedURI());
client.executeMethod(method);
그러나 URI
클래스는 그것을 좋아하지 않았다
org.apache.commons.httpclient.URIException: Invalid query
at org.apache.commons.httpclient.URI.parseUriReference(URI.java:2049)
at org.apache.commons.httpclient.URI.<init>(URI.java:167)
at net.metroidover.categorybot.http.HttpRequest.request(HttpRequest.java:66)
at net.metroidover.categorybot.http.HttpRequest.request(HttpRequest.java:121)
at net.metroidover.categorybot.http.Action.getCategoryMembers(Action.java:38)
at net.metroidover.categorybot.bot.BotComponent.<init>(BotComponent.java:58)
at net.metroidover.categorybot.bot.BotComponent.main(BotComponent.java:80)
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at net.metroidover.categorybot.http.Action.getCategoryMembers(Action.java:39)
at net.metroidover.categorybot.bot.BotComponent.<init>(BotComponent.java:58)
at net.metroidover.categorybot.bot.BotComponent.main(BotComponent.java:80)
것이 이중 이스케이프를 방지하는 방법에 대한 입력 대단히 감사하겠습니다. 나는 절대적으로 운이없는 모든 곳을 보았습니다.
감사합니다.
편집 :
:는 추가로, 최고의 나를 위해 작동 파르지팔의 하나이지만,이 솔루션은 내가method.setPath(url)
과 경로를 설정하는 것은
HttpMethod
내가 저장하기 위해 필요한 쿠키를 거부했다 말을하고 싶습니다
Aug 26, 2011 4:07:08 PM org.apache.commons.httpclient.HttpMethodBase processCookieHeaders
WARNING: Cookie rejected: "wikicities_session=900beded4191ff880e09944c7c0aaf5a". Illegal path attribute "/". Path of origin: "http://es.metroid.wikia.com/api.php"
그러나 생성자에게 URI를 보내고 setPath(url)
을 잊어 버리면 쿠키가 문제없이 저장됩니다.
String url = "http://es.metroid.wikia.com/api.php";
NameValuePair[] query = { new NameValuePair("action", "query"), new NameValuePair("list", "categorymembers"),
new NameValuePair("cmtitle", "Categoría:Mejoras de las Botas"), new NameValuePair("cmlimit", "500"),
new NameValuePair("format", "xml") };
HttpMethod method = null;
...
method = new GetMethod(url); // Or PostMethod(url)
method.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); // It had been like this the whole time
method.setQueryString(query);
client.executeMethod(method);
야이! 그건 완벽하게 작동합니다. 사실 이미 매개 변수를'ArrayList'로 보내고 있었기 때문에 많은 코드를 변경할 필요가 없었습니다. 감사합니다 :) –
ianmartorell