Java后台获取访问者外网IP、省和市信息

分析总结

服务器端获取访问者外网iP的核心代码就是下面这一行代码,需要特别注意的是下面这行代码只能在服务器端使用才能获取外网地址,在本地开发环境获取到的是内网IP,亲测有效,至于我提供的工具类只是更加全面的情况而已。另外想要通过下面代码获取的话需要代理服务器做一些相关配置,ng的配置方式可以参考这个:主机配置nginx后如何获取访问者IP

request.getRemoteAddr();

在这里插入图片描述



客户端获取外网IP地址的方式核心代码如下(完整代码到下面获取),通过模拟HTTP请求访问http://www.icanhazip.com接口接收返回的访问者IP地址数据。此方法只能在开发环境下有效,因为运行代码端是自己的电脑,开发环境下运营代码的电脑和访问者肯定是同一个网段,所以如果这个方法发布在服务器上后就一直获取到的是服务器外网IP地址,所以下面的方法只适合用来玩一玩

String ipAddr = IpUtil.getIpAddr(request);//获取ip地址
        boolean internalIp = internalIp(ipAddr);//判断ip是否内网ip
        log.info("ipAddr={}", ipAddr);
        log.info("internalIp={}", internalIp);
        if (!internalIp) {//外网地址直接返回
            log.info("直接返回外网IP={}", ipAddr);
            return ipAddr;
        }
        String result = "";
        URLConnection connection;
        BufferedReader in = null;
        try {
            URL url = new URL("http://www.icanhazip.com");
            connection = url.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "KeepAlive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(3000);
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("URLConnection建立连接返回result={}", result);
        return result;

完整代码

AddressUtils



import lombok.extern.slf4j.Slf4j;
import sun.net.util.IPAddressUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * * ip地址工具类
 * * @author ACGkaka
 * *
 */
@Slf4j
public class AddressUtils {
    /**
     * @param
     * @throws Exception
     * @todo 获取外网ip
     * @date 2018年11月12日
     * @author yanan
     */
    public static String getOuterNetIp(HttpServletRequest request) throws Exception {
        String ipAddr = IpUtil.getIpAddr(request);//获取ip地址
        boolean internalIp = internalIp(ipAddr);//判断ip是否内网ip
        log.info("ipAddr={}", ipAddr);
        log.info("internalIp={}", internalIp);
        if (!internalIp) {//外网地址直接返回
            log.info("直接返回外网IP={}", ipAddr);
            return ipAddr;
        }
        String result = "";
        URLConnection connection;
        BufferedReader in = null;
        try {
            URL url = new URL("http://www.icanhazip.com");
            connection = url.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "KeepAlive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(3000);
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("URLConnection建立连接返回result={}", result);
        return result;
    }

    /**
     * @param
     * @todo 判断是否内网ip
     * @date 2018年11月12日
     * @author yanan
     */
    public static boolean internalIp(String ip) {
        if ("127.0.0.1".equalsIgnoreCase(ip))
            return true;
        if ("0:0:0:0:0:0:0:1".equals(ip))
            return true;
        byte[] addr = IPAddressUtil.textToNumericFormatV4(ip);
        return internalIp(addr);
    }

    /**
     * @param
     * @todo 判断解析后的ip是否内网
     * @date 2018年11月12日
     * @author yanan
     */
    public static boolean internalIp(byte[] addr) {
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        // 10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        // 172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        // 127.0.0.1/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0) {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4) {
                    return true;
                }
            case SECTION_5:
                switch (b1) {
                    case SECTION_6:
                        return true;
                }
            default:
                return false;
        }
    }
}

HttpUtil

package com.luntek.certificate.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * @author Czw
 * @Description HTTP相关工具类
 * @Date 2019/4/11 0011 上午 10:46
 */
@Slf4j
@Service
public class HttpUtil {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        return builder.build();
    }

    /**
     * 通过response发送Excel表格
     *
     * @author Czw
     * @date 2019/4/11 0011 下午 12:56
     */
    public static HttpServletResponse setExcelResponse(HttpServletResponse response, String className) throws UnsupportedEncodingException {
        //防止文件名乱码
        String name = new String(className.getBytes(), "ISO8859-1");
        response.reset(); // 清除buffer缓存
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        return response;
    }
    @Autowired
    private RestTemplate restTemplate;


    // Get请求
    public String Get(String url, Map<String, Object> params) {
        String uri = buildUri(url, params);
        ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
        return response.getBody();
    }

    // Post请求(JSON请求头)
    public String JPost(String url, Map<String, Object> params) {
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, jsonHeaderBuilder());
        log.info("****req:{}****", request);
        ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
        return response.getBody();
    }

    // Post请求(URL请求头)
    public String UPost(String url, MultiValueMap<String, String> params) {
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, urlHeaderBuilder());
        ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
        return response.getBody();
    }

    // 拼接Url和参数
    private String buildUri(String url, Map<String, Object> params) {
        StringBuilder sb = new StringBuilder(url);
        sb.append("?");
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    // 构建Url请求头
    private HttpHeaders urlHeaderBuilder() {
        HttpHeaders h = new HttpHeaders();
        h.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return h;
    }

    // 构建Json请求头
    private HttpHeaders jsonHeaderBuilder() {
        HttpHeaders h = new HttpHeaders();
        h.setContentType(MediaType.APPLICATION_JSON);
        return h;
    }
}

接口代码

 /**
     * 测试外网ip获取地址
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/testGetAdd")
    public ResponseResult testGetAdd(HttpServletRequest request) {
        log.info("**********************");
        log.info(request.getRemoteAddr());
        String ip = null;
        try {
            ip = AddressUtils.getOuterNetIp(request);
            String url="http://ip-api.com/json/"+ip+"?";
            Map<String,Object> parm=new HashMap<>();
            parm.put("lang=","zh-CN");
            String str=httpUtil.Get(url,parm);
            JSONObject json = JSONObject.fromObject(str);
            return ResponseResult.success(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.success(ip);
    }



测试效果

在这里插入图片描述
在这里插入图片描述


网上获取外网ip的方式千篇一律而且很多都不行,找的时候看到下载里面很多都要积分下载的我这就没有设置了,希望大家点个赞就好了,好运~_~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一米阳光zw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值