Java环境

jdk1.8

JAVA代码

pom.xml

        <dependency>
            <groupId>com.maxmind.geoip2</groupId>
            <artifactId>geoip2</artifactId>
            <version>2.17.0</version>
        </dependency>

注:3.0以上版本需要jdk11环境。

GeoipController.java

package net.hzcat.....controller;

import net.hzcat.....service.GeoipService;
import net.hzcat.....util.JsonUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
@RequestMapping("/geoip")
public class GeoipController {
    private final GeoipService geoipService;

    public GeoipController(GeoipService geoipService) {
        this.geoipService = geoipService;
    }

    @RequestMapping("/callback")
    public String callback(HttpServletRequest request){
        //String host = geoipService.getIpAddress(request);
        String host = "128.101.101.101";
        return geoipService.callback(host);
    }


    @RequestMapping(value = "/json", method = RequestMethod.GET)
    public JsonUtil json(HttpServletRequest request) {
        String host = request.getParameter("ip");
        if (host == null || host.length() == 0) {
            host = geoipService.getIpAddress(request);
        }

        return new JsonUtil(200, "success", true, geoipService.getJson(host));
    }
}

GeoipService.java

package net.hzcat.....service;

import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Transactional
public interface GeoipService {
    String callback(String host);
    String getIpAddress(HttpServletRequest request);
    List<Object> getJson(String host);
}

GeoipServiceImpl.java

package net.hzcat.....service.impl;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.AsnResponse;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import net.hzcat.....service.GeoipService;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class GeoipServiceImpl implements GeoipService {
    public String callback(String host){
        HashMap<String, String> city = getCity(host);
        HashMap<String, String> ans = getAns(host);
        return "callback('"+host+"', '"+city.get("country")+" "+city.get("subdivision")+" "+city.get("city")+" "+ans.get("orgname")+"')";
    }

    public List<Object> getJson(String host){
        HashMap<String, String> city = getCity(host);
        city.put("ip" , host);
        HashMap<String, String> ans = getAns(host);
        ans.putAll(city);
        List<Object> data = new ArrayList<>();
        data.add(ans);
        return data;
    }

    private HashMap<String, String> getCity(String host){
        HashMap<String, String> data = new HashMap<>();

        // A File object pointing to your GeoIP2 or GeoLite2 database
        File database = new File("/path/GeoLite2-City.mmdb");

        // This creates the DatabaseReader object. To improve performance, reuse
        // the object across lookups. The object is thread-safe.
        DatabaseReader reader;
        try {
            reader = new DatabaseReader.Builder(database).build();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        InetAddress ipAddress;
        try {
            ipAddress = InetAddress.getByName(host);
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }

        // Replace "city" with the appropriate method for your database, e.g.,
        // "country".
        CityResponse response;
        try {
            response = reader.city(ipAddress);
        } catch (IOException | GeoIp2Exception e) {
            throw new RuntimeException(e);
        }

        Country country = response.getCountry();
        //System.out.println(country.getIsoCode());            // 'US'
        //System.out.println(country.getName());               // 'United States'
        //System.out.println(country.getNames().get("zh-CN")); // '美国'
        data.put("country" , country.getNames().get("zh-CN"));
        Subdivision subdivision = response.getMostSpecificSubdivision();
        //System.out.println(subdivision.getName());    // 'Minnesota'
        //System.out.println(subdivision.getIsoCode()); // 'MN'
        data.put("subdivision" , subdivision.getNames().get("zh-CN"));

        City city = response.getCity();
        //System.out.println(city.getName()); // 'Minneapolis'
        data.put("city" , city.getNames().get("zh-CN"));

        //Postal postal = response.getPostal();
        //System.out.println(postal.getCode()); // '55455'

        //Location location = response.getLocation();
        //System.out.println(location.getLatitude());  // 44.9733
        //System.out.println(location.getLongitude()); // -93.2323
        return data;
    }

    private HashMap<String, String> getAns(String host){
        HashMap<String, String> data = new HashMap<>();
        // A File object pointing to your GeoLite2 ASN database
        File database = new File("/path/GeoLite2-ASN.mmdb");

        // This creates the DatabaseReader object. To improve performance, reuse
        // the object across lookups. The object is thread-safe.
        try (DatabaseReader reader = new DatabaseReader.Builder(database).build()) {

            InetAddress ipAddress = InetAddress.getByName(host);

            AsnResponse response = reader.asn(ipAddress);

            //System.out.println(response.getAutonomousSystemNumber());       // 217
            //System.out.println(response.getAutonomousSystemOrganization()); // 'University of Minnesota'
            data.put("orgname" , response.getAutonomousSystemOrganization());
        } catch (IOException | GeoIp2Exception e) {
            throw new RuntimeException(e);
        }
        return data;
    }

    public String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

运行效果

jsonp接口

callback('128.101.101.101', '美国 明尼苏达州 明尼阿波利斯 UMN-SYSTEM')

json接口

http://localhost:8080/api/geoip/json?ip=128.101.101.101

{
  "success": true,
  "message": "success",
  "code": 200,
  "data": [
    {
      "country": "美国",
      "subdivision": "明尼苏达州",
      "orgname": "UMN-SYSTEM",
      "city": "明尼阿波利斯",
      "ip": "128.101.101.101"
    }
  ]
}

相关文档

https://github.com/maxmind/GeoIP2-java