streda 3. júna 2009

Ako na geolokáciu s WorldIP API

Pojem geolokácia (Geolocation) v tomto kontexte znamená určenie reálnej geografickej polohy počítača podľa jeho IP adresy.

Požiadavka:

Web stránka podporuje viac jazykových mutácií, medzi ktorými si užívateľ môže vybrať jazyk, ktorému rozumie. Pri otvorení stránky sa implicitne vyberie jazyk, ktorým sa hovorí v krajine, z ktorej je užívateľ pripojený na internet. Konkrétne, ak máme web stránku, ktorá podporuje anglický a slovenský jazyk, výsledok bude, že užívateľovi zo Slovenska, alebo Čiech sa načíta slovenská verzia a pri vstupe na stránku z iných krajín sa zobrazí anglická verzia.

Riešenie:

Riešenie by malo byť jednoduché, zadarmo, rýchlo realizovateľné a dostatočne univerzálne.
Malo by bežať na Google App Engine (GAE) s klientom v Google Web Toolkit (GWT).

Na prvý pohľad sa mi zapáčilo WorldIP API, pretože formát HTTP dotazu je veľmi jednoduchý a výsledkom je iba dvojmiestny kód krajiny. Teda nieje potrebné parsovať žiadne XML a neprenášajú sa iné zbytočné údaje.

Formát dotazu je:

http://api.wipmania.com/[IPADDR]?[URL]

kde:

IPADDR - je IP adresa, ktorej geografickú lokáciu chceme zistit URL - je doména našej aplikácie, slúži na kontrolu denných limitov

príklad: Aplikácia myappid.appspot.com sa dotazuje na pôvod IP adresy 123.45.67.89

http://api.wipmania.com/123.45.67.89?myappid.appspot.com

výsledok:

dvojznakový kód krajiny, napr. "SK" pre Slovensko.

Jednoduchá pomocná trieda, ktorá funguje aj na GAE:
public class WorldIPHelper {
...
 private static final String WIP_API_URL = "http://api.wipmania.com/";
 private static final String DOMAIN_NAME_PARAMETER = "?myappid.appspot.com";
...
 public static String getLocaleFromWorldIP(String remoteIPAddress) {
  String countryCode = "";
  try {
   URL url = new URL(WIP_API_URL + remoteIPAddress + DOMAIN_NAME_PARAMETER);
   BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
   char[] cbuf = new char[2];
   reader.read(cbuf);
   countryCode = new String(cbuf);
   reader.close();
  } catch (MalformedURLException e) {
   log.severe(e.toString());
  } catch (IOException e) {
   log.severe(e.toString());
  }
  return countryCodeToLocale(countryCode).getLocaleString();
 }
}

JSP stránka, ktorá nastavuje lokalizačnú vlastnosť GWT podľa IP adresy klienta.
...
<%
...
 localeString = WorldIPHelper.getLocaleFromWorldIP(request.getRemoteAddr());
...
%>
...
<meta name="gwt:property" content="locale=<%=localeString%>">
...

Limity:

- pre GAE platí hlavne skupina kvót UrlFetch - pre WorldIP API je to 10 000 dotazov denne na jednu aplikáciu

Ak by dané limity WorldIP API neboli dostačujúce, prípadne by nebolo vhodné sa z nejakého dôvodu spoliehať na externú službu, je tu tiež možnosť stiahnuť si priamo databázu IP adries, naimportovať si ju do vlastnej databázy a naimplementovať si vyhľadávanie vo vlastnej réžii.

Ak ste niekedy riešili niečo podobné, tak odporučte akú službu ste použili, prípadne či ste s ňou boli spokojní.

3 komentáre:

  1. Proč je uvedený příklad zaměřený na výběr jazyka návštěvníka? Preferovaný jazyk přece již dávno prohlížeče posílají. Geolokace má význam na zjištění *země* návštěvníka a tudíž třeba zobrazení správného místního času (i když u velkých zemí by to chtělo přesnější službu než je uvedena).

    OdpovedaťOdstrániť
  2. Príklad na časové pásma ma proste nenapadol, ale máš pravdu, mohol som tam radšej dať príklad na zisťovanie "search bots", "spy bots", "proxies" a "Tor network", bolo by to trošku dlhšie, ale možno zaujímavejšie.

    OdpovedaťOdstrániť
  3. Hm, napadli ma ešte iné celkom dobré príklady použitia, napríklad dostupnosť/cena tovaru v internetových obchodoch, ak sa obchod nachádza vo viacerých krajinách, ale prerábať sa mi to už nechce. :)

    OdpovedaťOdstrániť