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í.